مسیرها
/
Common Lisp
Common Lisp
/
تمرین‌ها
/
فهرست‌های بلند لزلی
فهرست‌های بلند لزلی

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

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

مقدمه

لیست

با توجه به اینکه نام زبانی که داریم استفاده می‌کنیم، یعنی Lisp، مخفف LIST Processing است، ممکن است فکر کنید این زبان امکاناتی برای کار با لیست‌هایی از عنصرها دارد، و حق با شماست!

هرچند Common Lisp ساختارهای داده‌ای جز لیست هم دارد، لیست‌ها هنوز بسیار پرکاربردند.

لیست در Common Lisp دنباله‌ای از عنصرهاست. به آن cons هم می‌گویند (بیشتر به دلایل تاریخی). خود عنصرها لازم نیست هم‌نوع باشند. برای مثال می‌توانید لیستی داشته باشید شامل 1، two و "III".

ساختن لیست‌ها

کافی است لیستی نقل‌قول‌شده مثل '(1 two "III") را تایپ کنید؛ آنگاه لیستی ساخته و ارزیابی می‌شود (که به (1 two "III") ارزیابی می‌شود).

دو تابع اصلی هم برای ساختن لیست وجود دارد: list و cons.

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

(list 1 'two "III") ; => (1 two "III")

cons دو عنصر می‌گیرد و لیستی می‌سازد که عنصر اولش car آن (سرِ لیست) است و عنصر دومش cdr آن (بقیه‌ی لیست):

(cons 1 2)            ; => (1 . 2) ;; (a list without `nil` as its `cdr` is printed in this way)
(cons 1 nil)          ; => (1)
(cons 1 (cons 2 nil)) ; => (1 2)

با توابع car و cdr می‌توان به car و cdr یک لیست دسترسی پیدا کرد.

(first و rest هم‌معنی car و cdr هستند و دقیقاً به یک شکل کار می‌کنند.)

طول و دسترسی تصادفی

طول یک لیست را می‌توان با length تعیین کرد. طول یک لیست خالی صفر است.

می‌توان با nth به عنصری دلخواه دسترسی پیدا کرد (توجه کنید که ایندکس لیست‌ها از ۰ شروع می‌شود).

درخواست ایندکسی بزرگ‌تر از طول لیست خطا نیست. در عوض، به nil ارزیابی می‌شود:

(nth 23 '(short list)) ; => nil

چند متد کمکی هم برای دسترسی به عنصرهای اول لیست وجود دارد: first، second، third و همین‌طور تا tenth. جالب است، نه؟

ترکیب لیست‌ها

دو لیست یا بیشتر را می‌توان با append ترکیب کرد:

(append '(a b c) '(1 2 3)) ; => (A B C 1 2 3)
(append '(a b c) '())     ; => (A B C)

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

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

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

البته قلم و کاغذ ساده برای یک بیگانه‌ی Lisp کافی نیست. حتی «List» بیشتر کلمه‌ی «Lisp» است! باید چند تابع نوشته شود تا به پیگیری خرید کمک کند.

آیا می‌توانید به لزلی در پیگیری لیست خرید کمک کنید؟

1. ساخت یک لیست جدید

اولین کار این است که لزلی باید یک لیست خالی ایجاد کند. تابعی به نام new-list برای این کار عالی است.

(new-list) ; => ()

اوه نه... لزلی از قبل چند مورد در ذهن دارد، بنابراین به تابعی نیاز دارد که سه عنصر بگیرد (خوشبختانه لزلی فقط لیستی از سه عنصر می‌سازد. نه بیشتر، نه کمتر!) و یک لیست خرید جدید با آن موارد ایجاد کند. تابعی به نام list-of-things بنویسید که سه عنصر می‌گیرد و لیستی از آن‌ها برمی‌گرداند.

(list-of-things 'bread 'milk 'butter) ; => '(bread milk butter)

2. افزودن موارد به لیست

قبل از رفتن به فروشگاه، لزلی در انبار غذا را نگاه می‌کند تا ببیند چه موردی لازم دارد. با نوشتن تابع add-to-list به آن‌ها کمک کنید که یک عنصر را به ابتدای لیست اضافه می‌کند.

(add-to-list 'butter '(bread)) ; => '(butter bread)

3. موارد بعدی در لیست کدامند؟

هنگام خرید، لزلی می‌خواهد بداند برای بعدی به دنبال چه موردی بگردد. آن‌ها همچنین دوست دارند در لیست جلوتر را ببینند تا عنصر دوم، سوم، یا حتی بیست و سومین (عدد شانس‌شان) را ببینند.

  • first-thing به اولین عنصر لیست ارزیابی می‌شود
  • second-thing به عنصر دوم ارزیابی می‌شود
  • third-thing به عنصر سوم ارزیابی می‌شود
  • twenty-third-thing به عنصر بیست و سوم ارزیابی می‌شود
(first-thing '(bread butter milk)) ; => 'bread
(second-thing '(bread butter milk)) ; => 'butter
(third-thing '(bread butter milk)) ; => 'milk

4. حذف یک مورد از لیست

لزلی می‌خواهد اولین عنصر لیست را پیدا کند و آن را از قفسه بردارد. با نوشتن تابع remove-first-item به آن‌ها کمک کنید. این تابع به لیستی ارزیابی می‌شود که شامل همه‌ی موارد به جز اولین عنصر لیست ورودی است.

(remove-first-item '(bread butter milk)) ; => '(butter milk)

5. لیست‌های بزرگ‌تر از لیست‌های کوچک‌تر

لزلی متوجه شد که به طور تصادفی دو لیست خرید ساخته است، نه یکی! تابعی به نام list-append بنویسید که لیستی را برمی‌گرداند که شامل عناصر لیست اول و سپس عناصر لیست دوم است.

(list-append '(bread salt) '(butter milk)) ; => '(bread salt butter milk)

6. چقدر طولانی‌تر؟

لزلی نگران شده است که این سفر خرید کمی طول بکشد. فقط چند مورد در این لیست وجود دارد؟ تابعی به نام just-how-long بنویسید تا به آن‌ها بگوید لیست‌شان چقدر طولانی است.

(just-how-long '(bread milk butter salt)) ; => 4
ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
Common Lisp Exercism

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

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