آیا تابه‌حال چیزی درمورد کدنویسی به روش گلف شنیده‌اید؟

ترجمه و تالیف : علیرضا معمارزاده
تاریخ انتشار : 06 خرداد 99
خواندن در 5 دقیقه
دسته بندی ها : برنامه نویسی

هدف کدنویسی به روش گلف ساده است: یافتن راه‌حل‌هایی برای مسائل کدنویسی که کم‌ترین میزان کاراکتر را داشته باشند. هرکسی که بتواند یک راه‌حل با کمترین میزان کاراکتر پیدا کند، برنده است.

این با برنامه‌نویسی به‌صورت سنتی که هدف آن حل سریع و مؤثر مسائل بود، متفاوت است.

اجازه دهید برایتان شرح دهم که این روش چگونه کار می‌کند و چرا من این‌قدر این روش را می‌پسندم...

یک مثال ساده

این چالش را درنظر بگیرید: «هرکدام از اعداد 1 تا 10 را در یک خط جداگانه چاپ کنید» کد PHP زیر را نگاه کنید:

for ($i = 1; $i <= 10; $i++) echo "$i\n";

به این صورت کوتاه‌تر می‌شود:

while(++$i < 11) echo "$i\n";

کد 29 کاراکتری دوم، رقابت را از کد 41 کاراکتری اولی می‌برد. چالش‌های واقعی دشوارتر از این مثال هستند، اما الان ایده اصلی را درک کردید. مثال مناسب‌تری را در قسمت‌های بعدی مشاهده خواهیم کرد.

چرا باید این کار را انجام دهیم؟

به این دلایل من روش کدنویسی گلف را می‌پسندم:

  1. جالب و چالش‌برانگیز است اما روش متفاوتی با روش کدنویسی سنتی برای حل مسائل دارد.
  2. یک تغییر خوب برای حل چالش‌هاست بدون اینکه نگران استانداردها، عملکرد و نمادهای بزرگ در کدنویسی باشید.
  3. تفکر جانبی را تشویق می‌کند. ما معمولاً سعی نمی‌کنیم که کدهای کوتاه‌تر و قابل خواندنی بنویسیم (مگر اینکه بخواهیم آن‌ها را در فضای تولید ببریم).
  4. دانش اولیه زبانی را بهبود می‌بخشد و یادگیری را تسهیل می‌کند.
  5. رقابت‌ها حساس به زمان نیستند (برای مثال مسابقه یافتن راه‌حل)، بنابراین می‌توانند در یک بازه زمانی اتفاق بیفتند.

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

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

در ادامه این مطلب به شما اطلاعاتی درمورد چگونگی انجام این چالش ارائه می‌دهم.

زمانی‌که راه‌حل‌های دیگران را مرور می‌کنم و روی پروژه خودم کار می‌کنم، اغلب قابلیت‌ها و توابع ساخته‌شده جدیدی از یک زبان پیدا می‌کنم که قبلاً از وجود آن‌ها بی‌خبر بودم. «من نمی‌دانستم که جاوااسکریپت توانایی انجام این کار را هم دارد...، این خیلی جالب است!»

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

مثال پایه‌ای

نگاهی به قطب‌نمای زیر که دارای 16 نقطه است، بیندازید:

تابه‌حال چیزی درمورد کدنویسی به روش گلف شنیده‌اید؟

یک ورودی رشته‌ای که نشانگر یکی از جهات قطب‌نما باشد، درنظر بگیرید، خروجی باید دو جهت مجاور آن در جهت عقربه‌های ساعت باشند. به‌عنوان‌مثال:

INPUT: OUTPUT
N: NNW NNE
SW: SSW WSW
ENE: NE E
...and so forth

الآن من قصد دارم که از زبان PHP برای کد مثال بالا استفاده کنم چون زبانی است که من از آن در شرکتم استفاده می‌کنم (برای کار در بک‌اند از آن استفاده می‌کنیم).

این روش کاملاً شناخته‌شده است و برای کسانی هم که زیاد با آن آشنا نیستند، قابل‌خواندن است. برای تعریف متغیرها از '$' استفاده می‌شود، تعدادی توابع تعریف‌شده دارد که اسامی آن‌ها نسبتاً توصیفی هستند و از براکت و سمی‌کالن در مدل سنتی آن استفاده می‌شود.

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

به سؤال برگردیم. این یک مسئله خیلی ساده است که با روش‌های مختلفی می‌توان با آن برخورد کرد. می‌توانستیم به این صورت شروع کنیم که جهات را در یک آرایه ذخیره کنیم، ورودی هدف را در این آرایه پیدا کنیم، سپس رشته‌های مجاور را به‌عنوان خروجی درنظر بگیریم؛ مانند کد زیر:

<?php

// build our array $d (for "directions")
$d=['N','NNE','NE','ENE','E','ESE','SE','SSE','S','SSW','SW','WSW','W','WNW','NW','NNW'];

// find array key index of input $i
$k=array_search($i,$d);

// print adjacent directions, compensating for wraparound 
echo $d[$k?$k-1:15].' '.$d[($k+1)%16];

بنابراین توانستیم یک راه‌حل پیدا کنیم که 152 کاراکتر دارد. برای نوشتن این کد از کاراکترهای زیادی استفاده کردیم و فقط در مواردی که ورودی موردنظر در ابتدا یا انتهای آرایه باشد این زیاده‌روی جبران می‌شود.

این کد را به‌صورت زیر بهبود می‌بخشیم:

<?php

// now we're converting a string into our directions array to save some characters
$d=explode(' ','N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW');

// the rest of the code remains the same...

حالا بهتر شد. تعداد کاراکترها را به 133 تا کاهش دادیم. یک رشته (در PHP تقسیم کردن را، explode می‌نامند) را برای ایجاد آرایه تقسیم کردیم که باعث کاهش 19تایی در تعداد کاراکترها شد.

همچنان به فکر کاهش تعداد کاراکترها در آرایه هستیم به‌طوری‌که در سینتکس هم قابل‌استفاده باشد.

اما یک راه بهتر هم حتماً وجود دارد!

بیایید کمی بیشتر به مسئله فکر کنیم. این مسئله اساساً یک مسئله ساده است. شاید بتوان از آرایه صرف‌نظر کرد و فقط به رشته پرداخت و سپس راه‌حل مورد نظر را کشف و مسئله را حل کرد.

چه چیزی به جستجو و استخراج بخشی از یک رشته کمک می‌کند؟ البته که Regex. بهتر است امتحان کنیم:

<?php

// use regex to find the directions adjacent to our input direction
preg_match("/([^ ]+ )$i ([^ ]+)/",'N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW N NNE',$m);

// print adjacent directions ($m is an array containing results of our capture groups)
echo $m[1].$m[2];

از این راه توانستیم، تعداد کاراکترها را به 116 تا برسانیم. این راه‌حلی بود که من زمانی که برای اولین بار در حال یادگیری کدنویسی به روش گلف بودم، برای این مسئله به‌صورت آنلاین ارائه دادم.

ما به‌هیچ‌وجه مجبور به استفاده از آرایه‌ها نیستیم. راه‌حل‌های زیادی برای کوتاه کردن مسئله به روش متفاوتی در زبان php وجود دارند. Regex جادویی به ما کمک می‌کند که هدف موردنظر و دو جهت کناری آن‌را پیدا کنیم.

بدین ترتیب موفق شدیم 36 کاراکتر را نسبت به راه‌حل اولیه کاهش دهیم. فکر می‌کنم که ایده اصلی کدنویسی به روش گلف را درک کردید.

نکاتی برای کسانی که از روش گلف استفاده می‌کنند.

برای تسلط یافتن به کدنویسی به روش گلف، ابتدا باید بهترین تمرین‌های توسعه را کنار بگذارید (اغلب حتی برعکس آن‌ها را انجام دهید).

به هر چالش از زوایای مختلفی نگاه کنید، مدام از خودتان بپرسید: «چه راه دیگری برای حل این مسئله وجود دارد؟» و آن‌قدر گزینه‌هایتان را اصلاح کنید تا زمانی که به کوتاه‌ترین راه‌حل برسید.

وقتی چالش سخت می‌شود، از هنرهای پنهان زبان برنامه‌نویسی‌تان استفاده کنید و به هر شکل ممکن سعی کنید حتی یک یا دو کاراکتر را حذف کنید که این درواقع مرز بین شکست و پیروزی است.

همین‌طور که درحال تمرین روش گلف هستید، متوجه می‌شوید که همیشه یک حیله وجود دارد که باید آن را یاد بگیرید؛ بنابراین مرور راه‌حل‌های دیگران باعث می‌شود که برای مراحل بعدی آماده‌تر شوید.

نکات زیر را به‌خاطر داشته باشید زیرا قرار است تا انتها در این مسابقه رقابت کنید:

  1. قبل از آن‌که شروع به کدنویسی کنید به مسئله فکر کنید و یا اینکه آن‌را روی وایت‌برد بنویسید.
  2. بهترین کد را دور بی‌اندازید. راه‌حل بهینه (کوتاه‌ترین) شما ممکن است نامناسب، نامرتب و با کمترین درخواست در یک رأی‌گیری باشد.
  3. از چندین زاویه به مسئله نگاه کنید تا بتوانید کوتاه‌ترین راه‌حل را برای آن پیدا کنید.
  4. با نوشتن یک کد خوانا فقط برای خودتان شروع کنید و وقتی به راه‌حل موردنظر دست یافتید، آن را اصلاح کنید.
  5. از تکنیک‌های ذخیره حجم مثل اپراتورهای سه‌گانه، اپراتورهای افزایشی/کاهشی، اپراتورهای منطقی در مقداردهی به متغیر، مقداردهی در حلقه و غیره استفاده کنید.
  6. تمام تلاش خود را برای سوءاستفاده از انعطاف‌پذیری، ویژگی‌های کاهش‌یافته و تمام ویژگی‌های زبان مورد‌استفاده‌تان به کار ببرید تا تعداد کاراکترها را تا حد امکان کاهش دهید.
  7. مستندات مخصوص به زبان برنامه‌نویسی‌تان را مرور کنید، به‌ویژه توابع ساخته‌شده که برای کار با رشته‌ها، آرایه‌ها، regex و lambda هستند.
  8. از گوگل برای نکات مربوط به روش گلف مختص به زبان برنامه‌نویسی منتخب‌تان کمک بگیرید.

نکاتی برای ایجاد رقابت

من نکاتی از مسابقات گلف یاد گرفتم:

  1. فواصل، تب یا خطوط جدید را در سیستم امتیازدهی درنظر نگیرید. از ابزاری مثل ابزار شمارشگر کاراکتر استفاده کنید که فقط تعداد کاراکترها (بدون فواصل) را حساب می‌کند. این باعث می‌شود که کدها خوانا باشند و مقایسه نتایج را لذت‌بخش‌تر می‌کند.
  2. از مسائلی استفاده کنید که بتوان چندین راه‌حل برای آن‌ها درنظر گرفت. مسائلی که در آن‌ها بتوان رشته و آرایه را دست‌کاری کرد برای شروع مناسب هستند. مسائلی که الگوریتم‌های پیچیده‌تری دارند برای چالش‌های متوسط و پیشرفته مناسب‌تر هستند، اما این‌ها اغلب برای رقابت‌های سنتی مناسب‌تر هستند، هدف روش گلف این است که درحد یک زنگ تفریح بتوانید از آن‌ها فاصله بگیرید.
  3. شرکت در مسابقات بهترین راه است. چالشی را به‌وجود آورید و زمانی را برای تکمیل آن درنظر بگیرید، به شرکت‌کنندگان اجازه دهید که راه‌حل‌ها را پیدا کنند و از یک تابلوی امتیازدهی استفاده کنید که بعد از دریافت هر پاسخ، بروزرسانی می‌شود. هرچه افراد ببینند که تعداد کاراکترها درحال کاهش است، بیشتر ترغیب به ادامه مسابقه می‌شوند، آن‌هایی که متوجه می‌شوند راه‌حل‌های دیگری هم هست، نمی‌توانند دربرابر وسوسه تلاش بیش‌تر برای بهینه کردن کدهایشان مقاومت کنند.
  4. یک سیستم امتیازدهی به این صورت تهیه کنید که هرزمان کدی ارائه می‌شود که رکوردهای قبلی را بهبود می‌بخشد، امتیاز را اعلام کند؛ برای مثال: «کمترین تعداد کاراکترها هم‌اکنون 253 است.» این روش باعث تشویق و ترغیب می‌شود.
  5. در صورت تساوی تعداد کاراکترها، کسی را برنده اعلام کنید که زودتر کد را نوشته است. این باعث تشویق افراد به سرعت‌بخشی در کدنویسی می‌شود.
  6. از سیستم چرخشی استفاده کنید به این صورت که هرکسی که در آخرین چالش پیروز شود، برای چالش بعدی باید آماده شود.
  7. از زبان گلف پرهیز کنید. مجموعه‌ای از زبان‌های برنامه‌نویسی وجود دارند که برای کدنویسی به روش گلف هستند، به این معنی که برای تولید برنامه‌های تا حد امکان کوتاه طراحی شده‌اند و کدهای کاملاً ناخوانایی هم تولید می‌کنند. به نظر من این روش سرگرمی و پتانسیل یادگیری زبان را از بین می‌برد، به‌جای آن از زبان‌های واقعی استفاده کنید.

زمانی را به فکرکردن در این مورد اختصاص دهید که کدام راه به بیش‌ترین لذت و جذابیت منجر می‌شود، از منطق شفاف و واضحی برخوردار باشید و سپس چالش را آغاز کنید!

منبع

گردآوری و تالیف علیرضا معمارزاده
آفلاین
user-avatar

Student of Software Engineering, python Developer, i love programming and game

دیدگاه‌ها و پرسش‌ها

برای ارسال نظر لازم است ابتدا وارد سایت شوید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید