अपने शुद्ध कार्य तर्कों को जानें
जब गोल्फ कोड, आप अक्सर एक कार्यात्मक दृष्टिकोण को रोजगार देंगे, जहां आप &
शॉर्टहैंड सिंटैक्स के साथ अनाम (शुद्ध) फ़ंक्शन का उपयोग करते हैं । इस तरह के एक फ़ंक्शन के तर्कों को एक्सेस करने के लिए बहुत सारे अलग-अलग तरीके हैं, और आप अक्सर संभावनाओं पर एक अच्छी समझ रखने के लिए कुछ बाइट्स से दाढ़ी बना सकते हैं।
एकल तर्कों तक पहुँचना
आप शायद यह जानते हैं कि आपने पहले शुद्ध कार्यों का उपयोग किया है। N वें तर्क के रूप में जाना जाता है #n
, और #
के लिए एक उपनाम के रूप में कार्य करता है #1
। इसलिए, यदि आप कहते हैं, तो आप एक फ़ंक्शन लिखना चाहते हैं जो किसी अन्य फ़ंक्शन और उसके तर्क के रूप में लेता है (उस फ़ंक्शन के तर्क को पास करने के लिए), उपयोग करें
#@#2&
यह नकारात्मक संख्याओं के साथ काम नहीं करता है (जैसे कि आप सूची का उपयोग करते समय उपयोग कर सकते हैं)।
तर्क नाम तक पहुंच (V10 में नया)
Mathematica 10 में प्रमुख नई भाषा सुविधाओं में से एक है Association
, जो मूल रूप से कुंजी-प्रकार के नक्शों के साथ मनमाने ढंग से लिखी गई है, जैसे
<| x -> 1, "abc" -> 2, 5 -> 3 |>
यदि इस तरह के एक संघ को शुद्ध कार्य के पहले तर्क के रूप में पारित किया जाता है , तो आप कुछ का उपयोग कर सकते हैं यदि इसके तर्क को नामित पैरामीटर के रूप में देखा जा सकता है:
{#, #2, #3, #abc, #xyz} & [<| "abc" -> "1st", "xyz" -> "2nd", abc -> "3rd" |>, "4th", "5th"]
(* {<| "abc" -> "1st", "xyz" -> "2nd", abc -> "3rd" |>, "4th", "5th", "1st", "2nd"} *)
ध्यान दें कि #
अभी भी उम्मीद के अनुसार पूरे संघ को संदर्भित करता है। काम करने के लिए नामित मापदंडों के लिए, कुंजियों को तार होना चाहिए (यदि आप उदाहरण के लिए अपरिभाषित चर का उपयोग करते हैं तो यह काम नहीं करेगा), और उन तार को एक अक्षर से शुरू होना चाहिए और केवल अक्षर और अंक होंगे।
"स्व" तर्क #0
एक कम ज्ञात विशेषता यह है कि #0
यह भी मौजूद है, और आपको फ़ंक्शन ऑब्जेक्ट को स्वयं देता है। यह वास्तव में quines और सामान्यीकृत quines में उपयोगी हो सकता है। वास्तव में, सबसे छोटा गणितज्ञ क्वीन (मुझे पता है) है
ToString[#0][] & []
थोड़ा कष्टप्रद यह है कि यह आपके द्वारा दर्ज किए गए सटीक वर्ण नहीं देगा। उदाहरण के लिए, यदि @
फ़ंक्शन अनुप्रयोग के लिए उपयोग करता है, तो यह अभी भी रेंडर [...]
करेगा और कुछ स्थानों पर रिक्त स्थान डाला जाएगा। यह आमतौर पर आप जितना चाहें उतना क्वीन को थोड़ा लंबा कर देंगे, लेकिन यह हमेशा काम करेगा, पहले क्वीन को गोल्फ करके, और फिर बस इसके आउटपुट को कॉपी करना - जो अब एक वास्तविक क्वीन होना चाहिए।
Quines के अलावा, इसका मतलब यह भी है कि आप अपने फ़ंक्शन का नाम लिए बिना पुनरावर्ती कोड लिख सकते हैं। इन तीनों की तुलना करें (भोले लेकिन गोल्फ वाले) फिबोनाची कार्यान्वयन:
f@0=0;f@1=1;f@n_:=f[n-1]+f[n-2]
f@n_:=If[n<2,n,f[n-1]+f[n-2]]
If[#<2,#,#0[#-1]+#0[#-2]]&
तर्कों के अनुक्रम
अब यहीं से असली जादू शुरू होता है। गोल्फ में अक्सर दृश्यों का उपयोग नहीं किया जाता है, क्योंकि Sequence
यह अभी भी सबसे लंबे समय के लिए लायक होने के लिए एक नाम है। लेकिन शुद्ध कार्यों में वे चमकते हैं। यदि आप अनुक्रमों से परिचित नहीं हैं, तो वे मूल रूप से कुछ अन्य भाषाओं में छपों की तरह हैं, यदि आप किसी अनुक्रम में List
या किसी फ़ंक्शन की तर्क सूची में अनुक्रम का उपयोग करते हैं, तो यह तत्व स्वचालित रूप से अलग स्लॉट में विस्तारित हो जाएंगे। इसलिए
{1, Sequence[2, 3, 4], 5} == {1, 2, 3, 4, 5}
f["a", Sequence[0, {}], "b"] == f["a", 0, {}, "b"]
अब, शुद्ध कार्यों में ##
या ##1
सभी तर्कों का एक क्रम है। इसी तरह, ##2
दूसरे से शुरू होने वाले सभी तर्कों का एक क्रम है, ##3
तीसरे से शुरू होने वाले सभी तर्क आदि। इसलिए एक शुरुआत के लिए, हम सिर्फ 5 बाइट की बचत के Sequence
रूप में लागू कर सकते हैं ##&
। एक उदाहरण के उपयोग के रूप में, यह हमें एक विकल्प प्रदान करता है Join@@list
( इस टिप को देखें ), जो किसी भी बाइट को नहीं बचाता है, लेकिन इसके बारे में जानने के लिए अच्छा है:
##&@@@list
यह प्रभावी रूप से एक नेस्टेड सूची के पहले स्तर को समतल करता है। इसके साथ हम और क्या कर सकते हैं? यहाँ एक 2 बाइट्स के लिए छोटे विकल्प है RotateLeft
:
RotateLeft@list
{##2,#}&@list
इन चीजों के लिए अकेले इस सुविधा को ध्यान में रखना लायक है। हालाँकि, हम बेहतर कर सकते हैं! अनुक्रम वास्तव में दिलचस्प हो जाते हैं जब विचार करते हैं कि ऑपरेटरों को वास्तव में हुड के तहत कार्यों के रूप में लागू किया जाता है। जैसे a+b
वास्तव में मूल्यांकन करता है Plus[a,b]
। तो अगर हम एक अनुक्रम देते हैं ...
1+##&[1,2,3]
=> Plus[1,##]
=> Plus[1,1,2,3]
=> 7
इस युक्ति का उपयोग इस टिप में एक बाइट को बचाने के लिए किया गया है Times
, क्योंकि juxtaposition तकनीकी रूप से भी सिर्फ एक ऑपरेटर है:
1##&[1,2,3]
=> Times[1,##]
=> Times[1,1,2,3]
=> 6
आप एक बाइट को बचाने के लिए इसका उपयोग कर सकते हैं Unequal
यदि आपके पास एक एकल-वर्ण मान या चर है जो आपको पता है कि आपके तर्क में नहीं है ( N
संभवतः 99% मामलों में काम करेगा):
Unequal[a,b,c]
N!=##&[a,b,c]
यह अपरिपक्व ऑपरेटरों के साथ और भी दिलचस्प हो जाता है -
और /
- बाद वाले दो वास्तव में गुणा और प्रतिपादक के संदर्भ में लागू होते हैं। यहां उन चीजों की एक सूची है जो आप कर सकते हैं, जहां अंतिम कॉलम मानता है कि फ़ंक्शन को तर्कों को पारित किया गया था a, b, c
:
Operator Function Expanded Equivalent to
+## Plus[##] Plus[a,b,c] a+b+c
1## Times[1,##] Times[1,a,b,c] a*b*c
-## Times[-1,##] Times[-1,a,b,c] -a*b*c
x+## Plus[x,##] Plus[x,a,b,c] x+a+b+c
x-## Plus[x,Times[-1,##]] Plus[x,Times[-1,a,b,c]] x-a*b*c
x## Times[x,##] Times[x,a,b,c] x*a*b*c
x/## Times[x,Power[##,-1]] Times[x,Power[a,b,c,-1]] x*a^b^c^-1
##/x Times[##,Power[x,-1]] Times[a,b,c,Power[x,-1]] a*b*c/x
x^## Power[x,##] Power[x,a,b,c] x^a^b^c
##^x Power[##,x] Power[a,b,c,#] a^b^c^x
x.## Dot[x,##] Dot[x,a,b,c] x.a.b.c
अन्य आम ऑपरेटर हैं !=
, ==
, &&
, ||
। कम आम लोगों को ध्यान में रखने के लिए कर रहे हैं |
, @*
, /*
। समाप्त करने के लिए, यहाँ एक छोटी सी बोनस चाल है:
#### Times[##,##] Times[a,b,c,a,b,c] (a*b*c)^2
इन के साथ प्रयोग करना जारी रखें, और मुझे बताएं कि क्या आपको कोई अन्य उपयोगी या विशेष रूप से दिलचस्प एप्लिकेशन मिलते हैं!
(Norm[#-#2]&)
हैEuclideanDistance
।