بازی فولدرهای خسته
از بین تمامی دوستان سلیب، تنها سجاد برای شب در خانه مانده و بقیه رفتهاند؛ به همین دلیل بازی جدیدی ابداع کردند که دونفری بتوانند آن را اجرا کنند. سلیب بازی را به سمت دنیای IT پیش میبرد و به سجاد ایدهی بازی جدیدش را میگوید.
بازی آنها به این صورت است که در ابتدا مسیری از کامپیوتر سلیب به نام path، بهطور تصادفی انتخاب میشود. سپس سلیب و سجاد، هریک پسوندی را برای خود انتخاب میکنند؛ مثلاً سلیب mp4 و سجاد jpg انتخاب میکند. کسی برندهی بازی است که در مسیر انتخابشده و تمامی زیر مسیرهای آن، بیشترین فایل با آن پسوند را داشته باشد.
اما متأسفانه، سجاد میخواهد تقلب کند. تقلب او به این صورت است که یک نام را انتخاب میکند و پسوند تمامی فایلهایی که نام برابر با نام انتخابی او دارند را به پسوندِ انتخابیِ خودش تغییر میدهد.
📂 مثال: بازیای که سجاد در آن تقلب نمیکند
src_folder
├── My-videos
│ └── video.mp4
├── image.jpg
└── video.mp4
اگر سلیب jpg و سجاد mp4 انتخاب کرده باشند، سجاد برندهی بازی است؛ زیرا ۱ فایل با پسوند سلیب و ۲ فایل با پسوند سجاد وجود دارد.
📂 مثال: بازیای که سجاد در آن تقلب میکند
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باشد.
💡 راهنمایی ۱
مثال: فرض کنید فایلهایی که داریم بهصورت زیر باشند.
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تقلب کند، به دلیل آنکه از تعداد فایلهای سلیب کم شده و به تعداد فایلهای سجاد اضافه میشود، سجاد برنده خواهد شد. بنابراین، بررسی اسم فایلی که بیشترین تکرار را دارد کافی نیست و باید تمام فایلها را برای تقلب سجاد بررسی کرد.
💡 راهنمایی نهایی
ساختار کلی تابع به این شکل است:
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!'
برای نوشتن پاسخ و دریافت امتیاز، ابتدا وارد حساب شوید.
ورود