راه
۶ کیو· متوسطمتوسطPYTHON۴ ثانیه · ۲۵۶ مگابایت

بازی فولدر‌های خسته

از بین تمامی دوستان سلیب، تنها سجاد برای شب در خانه مانده و بقیه رفته‌اند؛ به همین دلیل بازی جدیدی ابداع کردند که دونفری بتوانند آن را اجرا کنند. سلیب بازی را به سمت دنیای IT پیش می‌برد و به سجاد ایده‌ی بازی جدیدش را می‌گوید.

بازی آن‌ها به این صورت است که در ابتدا مسیری از کامپیوتر سلیب به نام path، به‌طور تصادفی انتخاب می‌شود. سپس سلیب و سجاد، هریک پسوندی را برای خود انتخاب می‌کنند؛ مثلاً سلیب mp4 و سجاد jpg انتخاب می‌کند. کسی برنده‌ی بازی است که در مسیر انتخاب‌شده و تمامی زیر مسیر‌های آن، بیشترین فایل با آن پسوند را داشته باشد.

اما متأسفانه، سجاد می‌خواهد تقلب کند. تقلب او به این صورت است که یک نام را انتخاب می‌کند و پسوند تمامی فایل‌هایی که نام برابر با نام انتخابی او دارند را به پسوندِ انتخابیِ خودش تغییر می‌دهد.


📂 مثال: بازی‌ای که سجاد در آن تقلب نمی‌کند

text
src_folder
├── My-videos
│   └── video.mp4
├── image.jpg
└── video.mp4

اگر سلیب jpg و سجاد mp4 انتخاب کرده باشند، سجاد برنده‌ی بازی است؛ زیرا ۱ فایل با پسوند سلیب و ۲ فایل با پسوند سجاد وجود دارد.


📂 مثال: بازی‌ای که سجاد در آن تقلب می‌کند

text
src_folder
├── My-videos
│   ├── video2.mp4
│   └── about.txt
├── about.mp3
├── image.jpg
└── video1.mp4

اگر سلیب mp4 و سجاد jpg را انتخاب کرده باشند، سلیب برنده‌ی بازی است؛ زیرا ۲ فایل با پسوند سلیب و ۱ فایل با پسوند سجاد وجود دارد.

اما سجاد اکنون با تقلب روی اسم about می‌تواند دو فایل را به پسوند انتخابی خودش (یعنی jpg) تغییر داده (یعنی دو فایلی که نامشان about است را به about.jpg تبدیل کند) و با ۳ فایل، برنده‌ی بازی شود.


تابع extension_combat

شما باید تابع extension_combat را به گونه‌ای برای سجاد بنویسید تا با دریافت path و فرمت‌های انتخابی سلیب و سجاد بگوید که سجاد می‌تواند ببرد یا خیر.


📋 قوانین بازی

  • اگر سجاد به‌طور عادی برنده‌ی بازی می‌شد، تابع شما باید مقدار زیر را برگرداند: Win! Normally!
  • اگر سجاد به‌طور عادی برنده‌ی بازی نمی‌شد ولی می‌توانست با تقلب روی اسمی برنده شود، تابع شما باید مقدار زیر را برگرداند: Win! you can win if you cheat on '{cheat_name}'! توجه کنید که cheat_name نام کلمه‌ای است که سجاد باید روی آن تقلب کند تا ببرد؛ مثلاً در «مثال بازی‌ای که در آن سجاد تقلب می‌کند» که بالاتر توضیح داده شد، باید مقدار زیر را برگردانید: Win! you can win if you cheat on 'about'!
  • اگر سجاد با تقلب روی چندین اسم می‌توانست برنده شود، می‌توانید هریک از اسم‌ها را به دلخواه برگردانید.
  • اگر سجاد هیچ استراتژی بردی نداشت، باید مقدار زیر را برگردانید: Lose! you can't win this game!

💡 نکات

  • تضمین می‌شود اسم فولدرها شامل . نیست.
  • تضمین می‌شود اگر در فولدری دو فایل هم‌نام با پسوند متفاوت وجود داشت، اگر سجاد بر روی نام آن فایل تقلب کند، مشکلی ایجاد نمی‌شود (مثلاً اگر در یک فولدر SAliB.txt همراه SAliB.mp4 وجود داشت، اگر سجاد روی نام SAliB تقلب کند، تعداد فایل‌ها با پسوند انتخابی سجاد ۲ واحد به ازای این دو فایل اضافه می‌شود).
  • شما حق تغییر نام فایلی را ندارید و تنها باید بگویید که چه کسی بازی را می‌برد.
  • کد شما فقط می‌تواند از کتابخانه‌های استاندارد پایتون استفاده کند.
  • کد شما نباید شامل کلمه‌های shutil یا import sh یا from sh یا subprocess یا os.popen یا os.system باشد.

💡 راهنمایی ۱

مثال: فرض کنید فایل‌هایی که داریم به‌صورت زیر باشند.

text
salib.png
salib.png
ali.txt
sajjad.jpg
mehdi.png
saeid.png

اگر سجاد، پسوند txt و سلیب، پسوند png را انتخاب کرده باشند، در حالت عادی، سلیب برنده می‌شود.

ولی اگر سجاد تقلب کند، سلیب برنده‌ی بازی نیست؛ زیرا سجاد می‌تواند روی اسم salib تقلب کند. طبق این تقلب، دو فایل اول، به salib.txt تبدیل شده و تعداد فایل‌های با پسوند سجاد، برابر ۳ می‌شوند؛ ولی تعداد فایل‌های با پسوند سلیب، دیگر آن ۴ فایل قبل نیستند و باید ۲ واحد از تعداد فایل‌های سلیب کم کنیم. در این صورت، تعداد فایل‌های سلیب برابر ۲ تا خواهد شد و چون ۳ بزرگتر از ۲ است، سجاد برنده می‌شود.


💡 راهنمایی ۲

برای بررسی برد سجاد در صورت تقلب، تنها بررسی اسم فایلی که بیشترین تکرار را دارد، کافی نیست.

مثال: فرض کنید سجاد پسوند png و سلیب پسوند jpg را برگزینند و در تمام فولدرها، فایل‌های زیر را داشته باشیم:

  • ۳ فایل به نام c.png
  • ۲ فایل به نام a.jpg
  • ۲ فایل به نام b.jpg

روشن است که در حالت عادی و بدون تقلب، سلیب برنده است. اسم فایلی که بیشترین تکرار را دارد، c است که اگر سجاد بخواهد روی آن تقلب کند، باز هم برنده نخواهد شد.

اما اگر سجاد روی یکی از اسامی a یا b تقلب کند، به دلیل آن‌که از تعداد فایل‌های سلیب کم شده و به تعداد فایل‌های سجاد اضافه می‌شود، سجاد برنده خواهد شد. بنابراین، بررسی اسم فایلی که بیشترین تکرار را دارد کافی نیست و باید تمام فایل‌ها را برای تقلب سجاد بررسی کرد.


💡 راهنمایی نهایی

ساختار کلی تابع به این شکل است:

python
import os
from collections import Counter

def extension_combat(salib_format, sajjad_format, path):
    # شمارش فایل‌ها در حالت عادی
    salib_count = 0
    sajjad_count = 0
    name_counts = Counter()
    name_format_counts = {}  # {name: {format: count}}

    for root, dirs, files in os.walk(path):
        for file in files:
            if '.' not in file:
                continue
            name, ext = file.rsplit('.', 1)
            if ext == salib_format:
                salib_count += 1
            elif ext == sajjad_format:
                sajjad_count += 1
            name_counts[name] += 1
            if name not in name_format_counts:
                name_format_counts[name] = {}
            name_format_counts[name][ext] = name_format_counts[name].get(ext, 0) + 1

    # بررسی برد عادی
    if sajjad_count > salib_count:
        return "Win! Normally!"

    # بررسی تقلب روی هر نام
    for name in name_counts:
        new_salib = salib_count
        new_sajjad = sajjad_count
        for ext, cnt in name_format_counts[name].items():
            if ext == salib_format:
                new_salib -= cnt
            elif ext == sajjad_format:
                new_sajjad -= cnt
        new_sajjad += name_counts[name]
        if new_sajjad > new_salib:
            return f"Win! you can win if you cheat on '{name}'!"

    return "Lose! you can't win this game!"
  • salib_count و sajjad_count ← شمارش فایل‌ها در حالت عادی
  • name_counts ← تعداد کل فایل‌ها برای هر نام (صرف‌نظر از پسوند)
  • name_format_counts ← تعداد فایل‌ها برای هر نام و هر پسوند
  • بررسی برد عادی: sajjad_count > salib_count
  • بررسی تقلب روی هر نام: حذف فایل‌های سلیب و سجاد با آن نام، سپس اضافه کردن کل فایل‌های آن نام به سجاد
  • اگر new_sajjad > new_salib ← سجاد با تقلب روی آن نام برنده می‌شود

✅ این تمرین را در ویرایشگر خود پیاده‌سازی کنید. به یاد داشته باشید که تابع باید یکی از سه رشته‌ی خروجی مشخص‌شده را برگرداند.

نمونه‌ها

ورودی نمونه ۱
make_file("src/My-videos/video.mp4")
make_file("src/image.jpg")
make_file("src/video.mp4")
extension_combat("jpg", "mp4", "src")
خروجی نمونه ۱
'Win! Normally!'
ورودی نمونه ۲
make_file("src/a.mp4")
make_file("src/b.mp4")
make_file("src/c.mp4")
make_file("src/x.jpg")
make_file("src/docs/about.txt")
make_file("src/about.mp3")
make_file("src/more/about.pdf")
extension_combat("mp4", "jpg", "src")
خروجی نمونه ۲
"Win! you can win if you cheat on 'about'!"
ورودی نمونه ۳
make_file("game/c.png")
make_file("game/one/c.png")
make_file("game/two/c.png")
make_file("game/a.jpg")
make_file("game/one/a.jpg")
make_file("game/b.jpg")
make_file("game/d.jpg")
make_file("game/e.jpg")
extension_combat("jpg", "png", "game")
خروجی نمونه ۳
"Win! you can win if you cheat on 'a'!"
ورودی نمونه ۴
make_file("p/a1.png")
make_file("p/a2.png")
make_file("p/deep/a3.png")
make_file("p/deep/er/a4.png")
make_file("p/a5.png")
extension_combat("png", "txt", "p")
خروجی نمونه ۴
"Lose! you can't win this game!"
ورودی نمونه ۵
make_file("n/x/y/z/one.txt")
make_file("n/x/two.txt")
make_file("n/three.txt")
make_file("n/readme.md")
make_file("n/x/y/notes.md")
extension_combat("md", "txt", "n")
خروجی نمونه ۵
'Win! Normally!'

برای نوشتن پاسخ و دریافت امتیاز، ابتدا وارد حساب شوید.

ورود