ट्रैक
/
Common Lisp
Common Lisp
/
अभ्यास
/
लिली की लसान्या का बचा हुआ खाना
लिली की लसान्या का बचा हुआ खाना

लिली की लसान्या का बचा हुआ खाना

सीखने का अभ्यास

परिचय

लैम्ब्डा लिस्ट

Common Lisp में किसी फंक्शन की आर्गुमेंट लिस्ट को लैम्ब्डा लिस्ट कहा जाता है। एक लैम्ब्डा लिस्ट में अलग-अलग टाइप के आर्गुमेंट हो सकते हैं। इन अलग-अलग टाइपों को लैम्ब्डा लिस्ट कीवर्ड से दर्शाया जाता है, और ये सभी & से शुरू होते हैं। सबसे अधिक इस्तेमाल होने वाले टाइप वैकल्पिक, कीवर्ड और रेस्ट आर्गुमेंट टाइप हैं। किसी लैम्ब्डा लिस्ट कीवर्ड के बाद लैम्ब्डा लिस्ट में आने वाला हर पैरामीटर उसी टाइप का होगा। एक लैम्ब्डा लिस्ट में कोई लैम्ब्डा लिस्ट कीवर्ड सिर्फ एक बार ही इस्तेमाल किया जा सकता है।

लैम्ब्डा लिस्ट का इस्तेमाल कुछ और जगहों पर भी होता है, जिनकी बात हम आगे करेंगे, जैसे डीस्ट्रक्चरिंग और मैक्रो।

वैकल्पिक पैरामीटर

Common Lisp में किसी फंक्शन के कुछ आर्गुमेंट वैकल्पिक हो सकते हैं। लैम्ब्डा लिस्ट में इन्हें &optional लैम्ब्डा लिस्ट कीवर्ड से दर्शाया जाता है। अगर पैरामीटर निर्दिष्ट नहीं किया जाता, तो उसे nil वैल्यू से बाइंड किया जाता है। अगर कई वैकल्पिक पैरामीटर हों, तो उन्हें क्रम से बाइंड किया जाता है। वैकल्पिक पैरामीटर के लिए डिफ़ॉल्ट वैल्यू निर्दिष्ट की जा सकती हैं। अंत में, हर वैकल्पिक पैरामीटर के लिए एक सिंबल भी निर्दिष्ट किया जा सकता है, जो सही या गलत से बाइंड होता है। यह इस पर निर्भर करता है कि फंक्शन को कॉल करने वाले ने वह पैरामीटर दिया था या नहीं। इसे "सप्लाईड-पी पैरामीटर" कहा जाता है।

(defun optional-parameters (&optional x (y 'default) (z nil z-supplied-p))
  (list x y (if z-supplied-p (list :z-was-supplied z)
                             (list :z-was-not-supplied z))))

(optional-parameters)          ; => (NIL DEFAULT (:Z-WAS-NOT-SUPPLIED NIL))
(optional-parameters 5 nil 10) ; => (5 NIL (:Z-WAS-SUPPLIED 10))

कीवर्ड पैरामीटर

Common Lisp में किसी फंक्शन के नाम वाले पैरामीटर भी हो सकते हैं, जिन्हें "कीवर्ड पैरामीटर" कहा जाता है। लैम्ब्डा लिस्ट में इन्हें &key लैम्ब्डा लिस्ट कीवर्ड से दर्शाया जाता है। कीवर्ड पैरामीटर आवश्यक पैरामीटर नहीं होते। वैकल्पिक पैरामीटर की तरह इन्हें भी डिफ़ॉल्ट वैल्यू दी जा सकती हैं, और इसके लिए सिंबल बाइंड किए जा सकते हैं, जिनसे पता चलता है कि वे दिए गए थे या नहीं।

कीवर्ड पैरामीटर वाले फंक्शन को कॉल करते समय पैरामीटर की वैल्यू से पहले पैरामीटर का नाम कीवर्ड के रूप में लिखा जाता है। फंक्शन को कॉल करने वाला कीवर्ड पैरामीटर किसी भी क्रम में निर्दिष्ट कर सकता है।

(defun keyword-parameters (&key x (y 'default) (z nil z-supplied-p))
  (list x y (if z-supplied-p (list :z-was-supplied z)
                             (list :z-was-not-supplied z))))

(keyword-parameters)            ; => (NIL DEFAULT (:Z-WAS-NOT-SUPPLIED NIL))
(keyword-parameters :y 5)       ; => (NIL 5 (:Z-WAS-NOT-SUPPLIED NIL))
(keyword-parameters :z 10 :x 5) ; => (5 DEFAULT (:Z-WAS-SUPPLIED 10))

वैकल्पिक और कीवर्ड पैरामीटर को साथ इस्तेमाल करते समय ध्यान रखना चाहिए, क्योंकि कीवर्ड का नाम और आर्गुमेंट वैकल्पिक पैरामीटर खुद ले सकते हैं:

(defun could-be-confusing (&optional x y &key z) (list x y z))
(could-be-confusing :z 'huh?) ; => (:Z HUH? NIL)

रेस्ट पैरामीटर

Common Lisp में किसी फंक्शन में एक ऐसा पैरामीटर भी हो सकता है जिसमें आवश्यक या वैकल्पिक पैरामीटर संभाल लिए जाने के बाद बचे हुए सारे आर्गुमेंट आ जाते हैं। इस पैरामीटर को &rest लैम्ब्डा लिस्ट कीवर्ड से दर्शाया जाता है। अगर फंक्शन के सारे आर्गुमेंट दूसरे टाइप के पैरामीटर ले लेते हैं, तो रेस्ट पैरामीटर एक खाली लिस्ट से बाइंड होता है। अगर कुछ आर्गुमेंट बच जाते हैं, तो रेस्ट पैरामीटर उन आर्गुमेंट की एक लिस्ट से बाइंड होता है।

(defun rest-of-it (req &optional opt &rest rest) (list req opt rest))
(rest-of-it 1)         ; => (1 NIL NIL)
(rest-of-it 1 2)       ; => (1 2 NIL)
(rest-of-it 1 2 3)     ; => (1 2 (3))
(rest-of-it 1 2 3 4 5) ; => (1 2 (3 4 5))

निर्देश

लिस्प एलियन लिली ने आपकी मदद से निश्चित रूप से बहुत सारी लज़ान्या बनाई है। वे आपको कुछ बचा हुआ खाना देकर धन्यवाद देना चाहते हैं। लेकिन पहले उनके पास उन फंक्शनों में से एक के बारे में कुछ सुझाव हैं जिनमें आपने उनकी मदद की थी।

इस अभ्यास में आप कुछ और फंक्शन लिखेंगे, जो लिली को उनकी लज़ान्या पकाने में मदद करेंगे और साथ ही उन्हें आपके साथ बचा हुआ खाना बाँटने में भी मदद करेंगे।

आपके पास छह काम हैं: तीन मौजूदा लज़ान्या पकाने वाले फंक्शनों को बेहतर बनाने के बारे में, और तीन बचा हुआ खाना बाँटने के बारे में।

1. preparation-time-in-minutes को इस्तेमाल करना आसान बनाइए

लिली कहते हैं कि उन्हें आपका preparation-time-in-minutes इस्तेमाल करना थोड़ा मुश्किल लगा, क्योंकि फंक्शन इस्तेमाल करने से पहले उन्हें सारी परतें गिननी पड़ती थीं। लिली सोचते हैं कि क्या आप फंक्शन का एक ऐसा रूप बना सकते हैं जो परतों को (कितनी भी हों) आर्गुमेंट के तौर पर ले, और फिर इस आधार पर तैयारी का समय निकाले कि कितनी परतें थीं? याद रहे, एक परत तैयार करने में 19 मिनट लगते हैं।

(preparation-time 'sauce 'cheese 'right-handed-macaroni 'cheese 'sauce
                  'left-handed-macaroni 'sauce 'sauce 'cheese 'cheese)
                  ;; => 190 (because there are 10 layers.)

2. ओवन में लगने वाला अनुमानित समय बदलने की सुविधा दीजिए

लिली के माता-पिता हमेशा अपनी लज़ान्या 337 मिनट तक पकाते थे, लेकिन लिली मानते हैं कि दूसरे लिस्प एलियन अपनी लज़ान्या ज़्यादा या कम समय तक पकाना पसंद करते हैं।

इसलिए अच्छा होगा कि remaining-minutes-in-oven expected-minutes-in-oven का इस्तेमाल न करे, बल्कि एक वैकल्पिक पैरामीटर ले, जो तय करे कि समय लंबा, बहुत लंबा, छोटा या बहुत छोटा होना चाहिए। लंबा या छोटा होने का मतलब है 337 के डिफ़ॉल्ट समय में 100 जोड़ना या घटाना। बहुत लंबा या बहुत छोटा होने का मतलब है 200 जोड़ना या घटाना। अगर कोई पैरामीटर न दिया जाए, या आर्गुमेंट 'normal' हो, तो 337 की डिफ़ॉल्ट वैल्यू लौटाई जानी चाहिए।

(remaining-minutes-in-oven)             ;; => 337
(remaining-minutes-in-oven :normal)     ;; => 337
(remaining-minutes-in-oven :shorter)    ;; => 237
(remaining-minutes-in-oven :very-short) ;; => 137
(remaining-minutes-in-oven :longer)     ;; => 437
(remaining-minutes-in-oven :very-long)  ;; => 537

3. लिली को एक और पसंदीदा पकाने का तरीका याद आता है

वह बदलाव आपने अभी पूरा ही किया था कि लिली को याद आता है कि कुछ लिस्प एलियन ऐसे भी हैं जिन्हें बहुत ही कम पकाने का समय पसंद है। वास्तव में वे इसे कच्चा ही चाहते हैं। तो अब फंक्शन को 0 लौटाना चाहिए अगर आर्गुमेंट NIL हो, और वे ही वैल्यू भी लौटानी चाहिए जो पिछले काम में थीं।

(remaining-minutes-in-oven)     ;; => 337
(remaining-minutes-in-oven nil) ;; => 0

4. बचा हुआ खाना बाँटना

अब जब आपने लज़ान्या पकाने वाले फंक्शनों को बेहतर बनाने में मदद की है, तो बहुत सारी लज़ान्या बच गई है! लिली आपकी सारी मदद का बदला चुकाना चाहते हैं, इसलिए वे बचा हुआ खाना आपके साथ बाँटना चाहते हैं। इसके लिए आपको एक फंक्शन लिखना होगा जो तीन पैरामीटर लेता है: बचे हुए खाने की कुल मात्रा, लिली को उनकी अलमारियों में मिले बचे खाने के डिब्बों की संख्या, और आपके लिए वही संख्या। चूँकि बचे खाने के डिब्बे ढूँढने में अलग-अलग समय लग सकता है, और सही मात्रा तब तय हो सकती है जब आप और लिली अपनी-अपनी अलमारियाँ ढूँढ़ रहे हों, इसलिए आप दोनों सहमत होते हैं कि फंक्शन को आर्गुमेंट किसी भी क्रम में मिल सकते हैं, ताकि जैसे-जैसे हर संख्या तय होती जाए, आप उसे लिखते जाएँ। जब आपके पास तीनों संख्याएँ हों, तो आप फंक्शन कॉल का ब्रैकेट बंद करके उसे इवैल्यूएट कर सकते हैं।

फंक्शन को बचे खाने में से जो बचा रहेगा उसकी मात्रा लौटानी चाहिए, यानी बचे खाने के वज़न और आपने तथा लिली ने मिलकर जितने डिब्बे ढूँढे उनकी कुल संख्या के बीच का अंतर।

(split-leftovers :weight 20 :human 10 :alien 5) ;; => 5
(split-leftovers :weight 20 :alien 10 :human 2) ;; => 8
(split-leftovers :alien 12 :weight 20 :human 4) ;; => 4

5. अनुमान लगाना

अपनी-अपनी अलमारियों तक कुछ चक्कर लगाने के बाद आप दोनों सहमत होते हैं कि अच्छा होगा अगर फंक्शन यह मान ले कि आपके या लिली के पास, मान लीजिए, 10 डिब्बे हैं, अगर यह बताया न गया हो।

(split-leftovers :weight 20 :human 5) ;; => 5
(split-leftovers :weight 20 :alien 5) ;; => 5
(split-leftovers :weight 20)          ;; => 0

6. बचे हुए खाने की मानक मात्रा

और भी बेहतर यह होगा कि फंक्शन मान ले कि डिब्बों में भरने लायक खाना बचा हुआ है। तो अगर वज़न न दिया गया हो, तो फंक्शन को :just-split-it लौटाना चाहिए। लेकिन अगर वज़न दिया गया हो और वह nil हो, तो उसे :looks-like-someone-was-hungry लौटाना चाहिए।

(split-leftovers :human 5 :alien 5) ;; => :JUST-SPLIT-IT
(split-leftovers :weight NIL :human 5 :alien 5) ;; => :LOOKS-LIKE-SOMEONE-WAS-HUNGRY
GitHub के ज़रिए संपादित करें यह लिंक एक नई विंडो या टैब में खुलता है
Common Lisp Exercism

लिली की लसान्या का बचा हुआ खाना शुरू करने के लिए तैयार हैं?

Exercism पर साइन अप कीजिए और Common Lisp को 27 कॉन्सेप्ट92 अभ्यास तथा असली इंसानों से मिलने वाली मेंटरिंग के साथ सीखिए और उसमें महारत हासिल कीजिए, वह भी बिल्कुल मुफ्त।