پیتزا پای

پیتزا پای

تمرین یادگیری

مقدمه

در Common Lisp، مانند بسیاری از زبان‌ها، اعداد چند نوع دارند. دو مورد از ابتدایی‌ترین آن‌ها عبارت‌اند از:

اعداد صحیح

مانند بسیاری از زبان‌ها، Common Lisp اعداد صحیح دارد. این‌ها اعداد کامل و بدون ممیز اعشاری‌اند (مانند -6، 0، 25، 1234 و غیره).

Common Lisp هیچ محدودیتی برای بزرگی اعداد صحیح تعریف نکرده است. اعداد صحیح می‌توانند هر قدر بزرگ باشند (یا اگر منفی باشند، هر قدر کوچک).

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

اعداد اعشاری

مانند بسیاری از زبان‌ها، Common Lisp اعداد اعشاری دارد. این‌ها اعداد کسری یا کامل هستند که یک ممیز اعشاری دارند (مانند 3.14، -1.7، 99.99، 2048.0).

حساب

Common Lisp برای بیشتر عملیات از عملگرهای حسابی استاندارد استفاده می‌کند، اما تا حدی منحصربه‌فرد است، چون از «نماد پیشوندی» استفاده می‌کند، نه از «نماد میان‌وندی» آشناتر.

به‌طور واضح‌تر:

;; Infix-notation (non-lisp languages)
1 + 2 + 3 + 4 + 5 ; => 15
;; Prefix-notation (lisp languages)
(+ 1 2 3 4 5)     ; => 15

هرچند نماد پیشوندی بعضی عملیات مانند 2 + 2 را به شکل تا حدی ناآشنای (+ 2 2) درمی‌آورد، کار کردن با بیش از یک عدد را بسیار آسان‌تر می‌کند.

ریاضیات پایه

Common Lisp همه‌ی توابع معمول را دارد: +، -، *، / برای جمع، تفریق، ضرب و تقسیم.

وقتی به تقسیم می‌پردازید، ممکن است بخواهید باقی‌مانده‌ی تقسیم را بدانید؛ این کار با تابع mod (برای باقی‌مانده) انجام می‌شود که یک عدد و یک مقسوم‌علیه را به عنوان آرگومان می‌گیرد:

(mod 4 2)  ; => 0
(mod 2 4)  ; => 2
(mod 10 3) ; => 1

مقایسه‌ی اعداد

در نهایت، ممکن است مقایسه‌ی اعداد مختلف با توابعی مانند = (برابر)، /= (نابرابر) و >= (بزرگ‌تر یا مساوی) برایتان مفید باشد. وقتی این مقایسه‌ها درست باشند (مانند (= 1 1))، T را برمی‌گردانند و وقتی درست نباشند (مانند (> 0 1))، NIL را برمی‌گردانند.

دستورالعمل‌ها

لیلی، موجود فضاییِ Lisp، عاشق آشپزی است. او می‌خواهد با دوستانش یک مهمانی پیتزا برگزار کند، اما برای اینکه بیشترین استفاده را از مواد اولیه‌اش ببرد، دوست دارد پیش از شروع دقیقاً بداند به چه مقدار از هر ماده نیاز خواهد داشت.

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

1. نسبت خمیر

اول از همه، هر پیتزای عالی با یک خمیر خوشمزه شروع می‌شود!

لیلی عاشق پیتزاهای نازک و ترد با لبه‌ی ضخیم‌تر است. خمیر لازم برای وسط پیتزا همیشه ۲۰۰ گرم است، اما هر ۲۰ سانتی‌متر لبه به ۴۵ گرم خمیر نیاز دارد.

خوشبختانه، لیلی معادله‌ای به دست آورده است که گرم خمیر (g) را از تعداد پیتزاها (n) و قطرشان (d) محاسبه می‌کند:

g = n * (((45 * pi * d) / 20) + 200)

لیلی به تابعی نیاز دارد که:

  • تعداد پیتزاها (n) و قطرشان (d) را بگیرد
  • و مقدار خمیر لازم را با گرد کردن به نزدیک‌ترین گرم (g) برگرداند.

برای مثال، برای پختن ۴ پیتزا با قطر ۳۰ سانتی‌متر:

(dough-calculator 4 30) ; => 1648

2. کمی سس

لیلی در زدن سس وسواس زیادی دارد، اما اندازه‌ی پیتزاهایش ممکن است یکنواخت نباشد.

برای به دست آوردن قطر (d)، از معادله‌ی زیر استفاده می‌کند که در آن مقدار سس مصرف‌شده (s) متغیر است:

d = square-root of ((40 * s) / (3 * pi))

لیلی به تابعی نیاز دارد که قطر پیتزا (d) را از هر میلی‌لیتر سس مصرف‌شده (s) محاسبه کند.

برای مثال، اگر لیلی ۲۵۰ میلی‌لیتر سس استفاده کرده باشد:

(size-from-sauce 250) ; => 32.57

3. کمی پنیر، لطفاً

در سیاره‌ی لیلی، همه‌ی پنیرها به شکل مکعب‌های کامل عرضه می‌شوند و بر اساس اندازه فروخته می‌شوند. (چه انتظاری داشتید؟ این بالاخره یک سیاره‌ی فضایی است...)

باز هم، لیلی معادله‌ای به دست آورده است برای تعداد پیتزاهایی (n) با قطر مشخص (d) که از یک مکعب پنیر با طول ضلع (l) درست می‌شوند:

n = (2 * (l^3)) / (3* pi * (d^2))

تابعی بسازید که:

  • طول ضلع یک مکعب پنیر (l) و قطر پیتزاها (d) را بگیرد،
  • و تعداد پیتزاهای ساخته‌شده (n) را با گرد کردن به پایین برگرداند.

برای مثال، با یک مکعب پنیر ۲۵×۲۵×۲۵ سانتی‌متری و پیتزاهایی با قطر ۳۰ سانتی‌متر:

(pizzas-per-cube 25 30) ; => 3

4. تقسیم عادلانه

در نهایت، لیلی می‌خواهد هر پیتزا به ۸ برش تقسیم شود و به‌طور مساوی میان دوستانش پخش شود.

تابعی بسازید که:

  • تعداد پیتزاها و تعداد دوستان را بگیرد
  • و اگر پیتزاها به‌طور مساوی میان دوستان تقسیم شوند T و در غیر این صورت NIL را برگرداند.

برای مثال:

;; For splitting 3 pizzas between 4 friends
(fair-share-p 3 4) ; => T
;; For splitting 2 pizzas between 3 friends
(fair-share-p 2 3) ; => NIL
ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
Common Lisp Exercism

آماده‌اید پیتزا پای را شروع کنید؟

در Exercism ثبت‌نام کنید تا Common Lisp را همراه با 27 مفهوم92 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.