چالش برنامه نویسی با زبان پایتون

برای چالش آماده هستید
برای چالش آماده هستید


قبل از هر چیز باید بگویم عنوان یادداشت غلط انداز است اما عنوان بهتری به ذهنم نرسید، اگر پیشنهادی دارید بگید.

خلاصه داستان این است که من مدتی می‌شود مشغول یادگیری زبان پایتون به صورت خودآموز هستم. چند روز پیش بود که با خودم گفتم این همه به سایت‌های مختلف سرک کشیدم و ویدیوهای آموزش برنامه‌نویسی دیدم حالا وقتش است که به خودم ثابت کنم در برنامه‌نویسی کجای کارم. برای همین تصمیم گرفتم خودم را به چالش بکشم.

اول از همه نظرم به سمت وبسایت اویلر رفت. مشکل بزرگ وبسایت اویلر این است که زیادی بین برنامه نویس‌ها معروف است و تمام مسائلش را به تمام زبان‌های برنامه‌نویسی یکبار حل کردن و راه حل‌ها را روی اینترنت قراردادند؛ و از آنجایی که من نمی‌توانم بعد از ده دقیقه فکر کردن روی یک مسئله و به نتیجه نرسیدن در برابر وسوسه گوگل کردن مقاوت کنم کلا بیخیالش شدم و تصمیم گرفتم سراغ یک سایتی برم که کمتر معروف باشه و با یک سرچ ساده به راه حل مسائل نرسم.

بعد از کمی جستجو در اینترنت به این وبسایت رسیدم. تعدادی چالش برای تازه کارها طراحی کرده که درجه سختی آن‌ها از ۲ در مقایس ده تایی شروع می‌شود و تا ۷ ادامه دارد. در این یادداشت قصد دارم راجع به یکی از این چالش‌ها با درجه سختی ۳ از ۱۰ و تلاش‌های چندباره‌ام برای حل آن صحبت کنم.



چالش

چالش از ما میخواهد یک تابع بنویسم به نام double_letters که یک رشته به عنوان ورودی میگیرید. حالا باید داخل تابع این رشته را بررسی کنیم، اگر یک حرف دوبار داخل رشته تکرار شده بود مقدار True و در غیر اینصورت تابع باید مقدار False را برگرداند. نکته اینجاست که حروف تکراری باید دقیقا پشت سر هم آماده باشند. مثلا حرف l در کلمه Hello یا حرف f در کلمه off.



تلاش اول

کسانی که پایتون کار کردند می‌دانند و آگاه هستند رشته‌ها در پایتون یکسری خواص مشابه با لیست‌ها دارند. یعنی می‌توانیم چیزی شبیه به کد زیر بنویسم:

>>> name = "Mohammad"

>>> name[4] == name[5]

True

با توجه به این موارد تصمیم گرفتم یک حلقه for بنویسیم که کارکترهای رشته را دو به دو با هم مقایسه کند. بخاطر همین یک کد شبیه به کد زیر نوشتم.

b = 0

for i in range(len(string)):

b = i + 1

if string[i] == string[b]:

return True

خوب اگر یک برنامه نویس کهنه‌کار باشید الان با دیدن کد بالا یا دارید به ریش اینجانب می‌خندید یا آنکه فشار خونتان چسبیده به سقف، اول از همه تعریف متغییر b خارج از حلقه کار واقعا اشتباهی بود و بدتر از همه این کد اصلا خروجی جزء خطا ندارد. b برابر است با i + 1 و در آخر string[b] از رنج خارج می‌شود و برنامه به خطا میخورد.

برای حل این مشکل دست به یک کار احمقانه‌تر زدم و یک if نوشتم که هر وقت b از حداکثر رنج بیشتر شد آن را برابر با صفر قرار بده، برنامه به ظاهر شروع به کار کرد اما به ازای بعضی از مقادیر خاص مثل 'nono' مقدار غلط True را برمی‌گرداند.

وقتی دیدم زیادی کثافت کاری شد کلا همه چیز را پاک کردم و استراتژی‌ام را عوض کردم.

تلاش دوم

در تلاش دوم یک راه حل خیلی عجیبی به ذهنم رسید و هنوز در حیرتم چطور این راه حل به فکرم خطور کرد. اینبار تصمیم گرفتم رشته دریافتی را تبدیل به یک لیست کنم و در متغییر a بریزم و عکس آن را در متغییر b:

>>> a = [i for i in string]

>>> b = a[::-1]

حالا اگر مقدار a و b را برای رشته Hello چاپ کنیم خواهیم داشت:

['H', 'e', 'l', 'l', 'o']

['o', 'l', 'l', 'e', 'H']

حالا اگر دقت کنید دومین آیتم هر لیست برابر است با حرف l (برای کسانی که با برنامه‌نویسی آشنا نیستند: شمردن را از صفر شروع کنید) به نظر می‌رسید برنامه حل شده است فقط باید می‌نوشتم:

for i in range(len(string)):

if a[i] == b[i]:

return True

اما برنامه با رشته‌های فرد مثل 'abc' مشکل داشت. برای حل این مشکل تصمیم گرفتم یک if بنویسم که اگر تعداد کارکترهای رشته وردی فرد بود یک کارکتر الکی به آخر رشته اضافه کند اما باز هم برای مقداری مثل on and off برنامه جواب غلط میداد.

تلاش سوم

از قدیم گفتن «تا سه نشه بازی نشه» بعد از دو شکست بالاخره سومین تلاشم جواب داد و موفق شدم چالش را حل کنم.

راه حل نهایی
راه حل نهایی

فکر نمی‌کنم نیاز به توضیحی خاصی باشد. همینقدر بگم که بعد از نوشتن این کد خوش و خوشحال رفتم داخل سایت قرار دادمش و سایت هم بهم تبریک گفت که توانستم چالش را حل کنم. بعد از حل چالش وبسایت راه حل آن را هم نشان میدهد. راه حل پیش فرض سایت به شکل زیر است:

def double_letters(string):
for i in range(len(string) - 1):
letter1 = string[i]
letter2 = string[i + 1]
if letter1 == letter2:
return True
return False

و حتی می‌شود این چالش را در یک خط هم حل کرد:

def double_letters(string):
return any([a == b for a, b in zip(string, string[1: ])] )

خلاصه فهمیدم که برای نوشتن یک برنامه روش‌های مختلفی وجود دارد و اینکه بسیار کد باید زد تا پخته شود خامی؛ شما اگر جای من بودید چطور این چالش را حل میکردید؟