Mathematica में गोल्फ के लिए टिप्स


41

Mathematica में गोल्फिंग के लिए आपके पास क्या सामान्य सुझाव हैं? मैं उन विचारों की तलाश कर रहा हूं जो सामान्य रूप से कोड की समस्याओं को लागू कर सकते हैं जो कम से कम कुछ हद तक मैथेमैटिका के लिए विशिष्ट हैं (उदाहरण के लिए "टिप्पणियां हटाएं" एक उत्तर नहीं है)।

जवाबों:


30

नीचे दिए गए टिप्स सबसे किफायती से सबसे अधिक बार उपयोग किए जाने वाले भिन्न होते हैं:

  1. जहां संभव हो, यहां तक ​​कि उच्च स्तरीय आदेशों का भी उपयोग करें:

  2. Graphics and TextAscii कला के लिए उपयोग करें : जैसे स्टार प्रोग्रामिंग! और एक एनालॉग घड़ी बनाएँ

  3. समर्पित प्रतीक:

    • तर्क और उनके लंबे रूप के नामों के बजाय संचालन प्रतीकों को सेट करें: ⋃, instead, instead, instead

    • Mapऔर Apply: /@, //@@@,@@@

  4. उपसर्ग और infix संकेतन:

    • Print@"hello" की जगह में Print["hello"]

    • a~f~b की जगह में f[a,b]

  5. जब कोई फ़ंक्शन केवल एक बार उपयोग किया जाता है, तो एक शुद्ध फ़ंक्शन एक चरित्र या दो का अर्थकरण कर सकता है।

  6. किसी सूची में तार जुड़ना। ""<>{"a","b","c"}के बजायStringJoin@{"a","b","c"}

  7. सूचीबद्ध कार्यों का शोषण। अब सूची बेहतर है।

    {a, b, c} + {x, y, z}= {a+x, b+y, c+z}

    {2, 3, 4} {5, 6, 7}= {10, 18, 28}

    {{a, b}, {c, d}}^{2, 3} = {{a^2, b^2}, {c^3, d^3}}


2
इसके बजाय लिखना हमेशा कम होता(Norm[#-#2]&) है EuclideanDistance
user202729

32

कुछ अंतर्निहित कार्यों को लंबे नामों के साथ छोटी अभिव्यक्तियों के साथ बदला जा सकता है।

उदाहरण के लिए:

  • Total => Tr
  • Transpose=> Threadया\[Transpose]
  • True => 1<2
  • False => 1>2
  • Times => 1##&
  • Alternatives => $|##&
  • IntegerQ => ⌊#⌋==#&
  • a[[1]] => #&@@a
  • a[[All,1]] => #&@@@a
  • ConstantArray[a,n]=> Array[a&,n]याTable[a,{n}]
  • Union@a=> {}⋃aयाa⋃a
  • ToExpression@n=> FromDigits@nयदि nएक संख्या है
  • Divisible[n,m] => m∣n
  • FromDigits[n,2]=> Fold[#+##&,n]यदि s और s की nसूची है01
  • Complex@z=> {1,I}.zजहां zफॉर्म की एक सूची है{x,y}

5
@ विश्विसारि Thread[{{a,b},{c,d}}]== Thread[List[{a,b},{c,d}]]== {List[a,c],List[b,d]}== {{a,c},{b,d}}==Transpose[{{a,b},{c,d}}]
एलेफाल्फा

2
मुझे लगता है कि आपकी Foldचाल के FromDigitsअलावा किसी अन्य आधार के लिए भी काम करता है 10। जैसे FromDigits[n,5]-> Fold[4#+##&,n](ठिकानों के लिए अतिरिक्त बाइट बचाने के बोनस के साथ ) 100और 1000
मार्टिन एंडर

1
@ UTB-8 में mbomb007 3 बाइट्स। वास्तव में यह चरित्र है U+F3C7
एलेफाल्पा

1
मैंने अंत में 10.3 स्थापित किया। यदि हम पूर्ण कार्यक्रमों पर विचार कर रहे हैं, तो मुझे नहीं लगता कि Echoयह एक विकल्प है, क्योंकि यह >>वास्तविक स्ट्रिंग को प्रिंट करने से पहले STDOUT को प्रिंट (और एक स्थान) करता है।
मार्टिन एंडर

2
के लिए Complex[x,y] => {1,I}.{x,y}, मुझे लगता x+y*Iहै कि एक ही प्रभाव के साथ बहुत कम है?
शायरु असकोतो

22

दोहराया मूल्यों के साथ सूची

यह काम करने के लिए एक सामान्य वेक्टर है:

{0,0}

यह पता चला है कि यह एक बाइट द्वारा छोटा किया जा सकता है:

0{,}

अगर वेक्टर दो शून्य से अधिक है तो और भी बाइट्स बच जाते हैं। इसका उपयोग शून्य मैट्रिसेस को इनिशियलाइज़ करने के लिए भी किया जा सकता है, उदाहरण के लिए निम्न में से एक शून्य 2 मैट्रिक्स मैट्रिक्स है:

0{{,},{,}}

इसका उपयोग गैर-शून्य मानों के लिए भी किया जा सकता है यदि वे पर्याप्त रूप से बड़े या पर्याप्त रूप से कई या नकारात्मक हैं। निम्नलिखित जोड़े की तुलना करें:

{100,100}
0{,}+100
{-1,-1}
0{,}-1
{3,3,3,3}
0{,,,}+3

लेकिन याद रखें कि 6 मूल्यों से शुरू होकर, आप 1~Table~6इस मामले में बेहतर हैं (संभवतः पूर्ववर्ती आवश्यकताओं के आधार पर)।

इसका कारण यह है कि ,सूची में दो तर्कों का परिचय दिया गया है, लेकिन छोड़ी गई दलीलें (कहीं भी गणित में) निहित हैं Null। इसके अलावा, गुणन है Listable, और 0*xहै 0के लिए लगभग किसी भी x(जैसी चीजों के लिए छोड़कर Infinityऔर Indeterminate) इसलिए यहाँ क्या हो रहा है है:

  0{,}
= 0*{,}
= 0*{Null,Null}
= {0*Null,0*Null}
= {0,0}

1S की सूचियों के लिए , आप घातांक नियमों का उपयोग करके एक समान चाल का उपयोग कर सकते हैं। 1सूची में कम से कम तीन एस होने पर बाइट्स को बचाने के दो अलग-अलग तरीके हैं :

{1,1,1}
1^{,,}
{,,}^0

7
+1; यह सिर्फ यह दिखाने के लिए जाता है कि जबकि मैथेमेटिका में हर चीज के लिए बिल्ट-इन हो सकता है, लेकिन इसमें गोल्फ एक वास्तविक चुनौती हो सकती है।
लीजनमोनमल 978

यदि आप एक ऐसा सरणी चाहते हैं जो अंततः 1s से भरा है, तो 1^{,,,}एक बाइट से छोटा है 0{,,,}+1
मिशा लावरोव

@ मिशालारोव ओह, अच्छी पकड़। यह इसे तीन मूल्यों में छोटा बनाता है और आप इसका उपयोग भी कर सकते हैं {,,}^0। मैं पोस्ट को संपादित करूँगा।
मार्टिन एंडर

19

अपने शुद्ध कार्य तर्कों को जानें

जब गोल्फ कोड, आप अक्सर एक कार्यात्मक दृष्टिकोण को रोजगार देंगे, जहां आप &शॉर्टहैंड सिंटैक्स के साथ अनाम (शुद्ध) फ़ंक्शन का उपयोग करते हैं । इस तरह के एक फ़ंक्शन के तर्कों को एक्सेस करने के लिए बहुत सारे अलग-अलग तरीके हैं, और आप अक्सर संभावनाओं पर एक अच्छी समझ रखने के लिए कुछ बाइट्स से दाढ़ी बना सकते हैं।

एकल तर्कों तक पहुँचना

आप शायद यह जानते हैं कि आपने पहले शुद्ध कार्यों का उपयोग किया है। 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

इन के साथ प्रयोग करना जारी रखें, और मुझे बताएं कि क्या आपको कोई अन्य उपयोगी या विशेष रूप से दिलचस्प एप्लिकेशन मिलते हैं!


15

Sqrt@2या 2^.5=>√2

a[[1]]=>a〚1〛

#+#2&=>+##&

Flatten@a=> Join@@a(कभी-कभी)

Function[x,x^2]=> xx^2या#^2&

a〚1;;-1;;2〛=>a〚;;;;2〛

a〚2;;-1 ;;2〛=>a〚2;;;;2〛

a〚All,1〛=>a〚;;,1〛

{{1}}〚1,1〛=>Tr@{{1}}

0&~Array~10=>0Range@10

Range[10^3]=>Range@1*^3


1
नोट जब बाइट्स से मापने का उपयोग कर कि और ले जाता है 3 प्रत्येक (मान UTF8) बाइट्स
user202729

12

संचालक कार्य के रूप में

जूलिया के लिए डेनिस की हालिया खोज से प्रेरित होकर मैंने सोचा कि मैं इस बारे में गणितज्ञ के लिए देखूंगा। मैं जानता था कि गणितज्ञ बड़ी संख्या में अप्रयुक्त ऑपरेटरों को परिभाषित करता है, लेकिन इस पर कभी ध्यान नहीं दिया।

संदर्भ के लिए, सभी ऑपरेटरों की सूची यहां एक पूर्ववर्ती तालिका के रूप में पाई जा सकती है । अंतिम कॉलम में त्रिभुज इंगित करता है कि उस ऑपरेटर का अंतर्निहित अर्थ है या नहीं। जबकि उन सभी को नहीं जिन्हें आसानी से परिभाषित नहीं किया जा सकता है, उनमें से अधिकांश कर सकते हैं।

आसानी से, दो अप्रयुक्त ऑपरेटरों के पास कोडपॉइंट 256 से कम है, जैसे कि उन्हें आईएसओ 8859-1 एन्कोडेड सोर्स फाइल में सिंगल बाइट्स के रूप में इस्तेमाल किया जा सकता है:

  • ± (0xB1) या तो एक यूनीरी प्रीफ़िक्स ऑपरेटर या बाइनरी इन्फिक्स ऑपरेटर के रूप में उपयोग किया जा सकता है।
  • · (0xB7) को n> 2 के लिए एक वैरेडिक या n-ary infix ऑपरेटर के रूप में उपयोग किया जा सकता है।

हालांकि एक और पकड़ है: किसी अजीब कारण से जब इन ऑपरेटरों को परिभाषित करने के लिए आपको उनके सामने एक स्थान की आवश्यकता होती है, या फिर गणितज्ञ एक गुणा करने की कोशिश करता है। उनका उपयोग करते समय आपको किसी भी स्थान की आवश्यकता नहीं होती है:

±x_:=2x
x_ ±y_:=x+y
x_ ·y_ ·z_:=x*y+z
Print[±5]  (* 10 *)
Print[3±4] (*  7 *)
Print[3·4·5] (* 17 *)

इसके साथ तुलना करें:

f@x_:=2x
x_~g~y_:=x+y
h[x_,y_,z_]:=x*y+z
Print[f@5]   (* 10 *)
Print[3~g~4] (*  7 *)
Print[h[x,y,z]] (* 17 *)

तो यह फ़ंक्शन को परिभाषित करते समय एक बाइट बचाता है और इसका उपयोग करते समय दो बाइट्स। ध्यान दें कि ·चार ऑपरेंड्स के लिए बाइट्स की परिभाषा बचेगी नहीं और अधिक ऑपरेंड्स के लिए बाइट्स खर्च करना शुरू कर देगी, लेकिन तर्कों में उपयोग किए गए ऑपरेटर्स की पूर्वता के आधार पर उपयोग बाइट्स को बचा सकता है। यह नोट करना भी अच्छा है कि आप सस्ते में एक वैरेडिक फंक्शन को परिभाषित कर सकते हैं जिसे तब और अधिक कुशलता से कहा जा सकता है:

x_ ·y__:={y}
Print[1·2·3·4·5] (* {2, 3, 4, 5} *)

लेकिन ध्यान दें कि इन चर कार्यों को एक ही तर्क के साथ कॉल करना आसानी से संभव नहीं है। (आप कर सकते हैं CenterDot[x]या ##&[]·xयदि आप वास्तव में जरूरत है कि एक अच्छा मौका है कि आप एक अलग समाधान के साथ बेहतर हैं।)

बेशक, यह उन समाधानों के लिए कुछ भी नहीं बचा रहा है जहां एक अनाम फ़ंक्शन पर्याप्त है, लेकिन कभी-कभी आपको बाद में उपयोग के लिए सहायक कार्यों को परिभाषित करने की आवश्यकता होती है, और कभी-कभी यह नामांकित कार्यों को परिभाषित करने के लिए छोटा होता है जैसे विभिन्न मापदंडों के लिए विभिन्न परिभाषाएं सेट करना। उन मामलों में, ऑपरेटर के बजाय बाइट्स की एक सभ्य राशि बचा सकते हैं।

ध्यान दें कि इन आईएसओ 8859-1 एन्कोडेड फ़ाइलों का उपयोग करके $CharacterEncodingविंडोज डिफ़ॉल्ट की तरह एक संगत मूल्य पर सेट किया जाना है WindowsANSI। कुछ सिस्टम पर यह डिफॉल्ट होता है, UTF-8जो सिंगल बाइट्स से इन कोड पॉइंट्स को नहीं पढ़ पाएंगे।


यह वास्तव में बहुत अच्छा है, मुझे नहीं पता था कि गणितज्ञ के पास ऑपरेटरों की एक सूची थी, और यहां तक ​​कि उनकी मिसाल भी शामिल थी। जिन दो ऑपरेटरों को आपने पाया, मुझे यकीन है कि काम आएगा।
मील

8

पूर्णांक के आधार पर मूल्यों का चयन

के बीच चयन करने के लिए भोली दृष्टिकोण yऔर है या zनहीं, इस पर निर्भर करता हैx01

If[x<1,y,z]

हालांकि, इसका एक छोटा तरीका है:

y[z][[x]]

यह काम करता है क्योंकि [[0]]देता है Headएक अभिव्यक्ति की, इस मामले में y, जबकि [[1]]सिर्फ पहला तत्व देता है - पहला तर्क इस मामले में, z

आप दो से अधिक मानों के बीच चयन करने के लिए भी इसका उपयोग कर सकते हैं:

u[v,w][[x]]

ध्यान दें कि यह काम नहीं करेगा यदि uएक ऐसा फ़ंक्शन है जो वास्तव में किसी चीज़ का मूल्यांकन करता है। यह महत्वपूर्ण है कि गणितज्ञ u[v,w]वैसा ही रहे जैसा वह है। हालाँकि, यह ज्यादातर मामलों में काम करता है, जिसमें अगर uएक नंबर है, एक स्ट्रिंग या एक सूची है।

इस ट्रिक का श्रेय एलेफाल्फा को जाता है - मैंने उनके एक उत्तर में यह खोज की।

यदि xशून्य-आधारित के बजाय 1-आधारित है, तो बस उपयोग करें

{y,z}[[x]]

या

{u,v,w}[[x]]

कुछ दुर्लभ मामलों में, आप इस तथ्य का उपयोग भी कर सकते हैं कि गुणन का मूल्यांकन कुछ मूल्यों के लिए नहीं किया जाता है:

{"abc","def"}[[x]]
("abc""def")[[x]]

ध्यान दें कि गणितज्ञ वास्तव में तर्क का पुनर्निमाण करेगा, यदि वह बिना मूल्यांकन के रहता है, तो उपरोक्त के समान है

("def""abc")[[x]]

8

के लिए विकल्प Length

लीजनमैमल 978 और मीशा लावरोव के कुछ सुझावों के साथ इसे पूरी तरह से फिर से लिखा गया है। दोनों को बहुत धन्यवाद।

कई मामलों में, का Lengthउपयोग करके थोड़ा छोटा किया जा सकता है Tr। मूल विचार इनपुट को 1s की सूची में बदलना है , ताकि Trउन्हें बोया जा सके जो तब सूची की लंबाई के बराबर होगा।

ऐसा करने का सबसे आम तरीका 1^x(एक सूची के लिए x) उपयोग करना है । यह काम करता है क्योंकि Powerहै Listableऔर 1^nसबसे परमाणु मूल्यों के लिए nबस है 1(सभी नंबरों को, तार और प्रतीकों सहित)। इसलिए हम पहले ही इसके साथ एक बाइट बचा सकते हैं:

Length@x
Tr[1^x]

बेशक, यह मानता है कि xएक अभिव्यक्ति है, जिसकी तुलना में उच्च पूर्वता है ^

यदि xकेवल 0s और 1s शामिल हैं, तो हम एक और बाइट का उपयोग करके बचा सकते हैं Factorial(यह मानते हुए कि xइससे अधिक पूर्वता है !):

Length@x
Tr[x!]

कुछ दुर्लभ मामलों में, गुणा की xतुलना में कम पूर्वता हो सकती है ^लेकिन फिर भी उच्च पूर्वता हो सकती है। उस मामले में भी इसकी तुलना में कम पूर्वता होगी @, इसलिए हमें वास्तव में तुलना करने की आवश्यकता है Length[x]। ऐसे ऑपरेटर का एक उदाहरण है .। उन मामलों में, आप अभी भी इस फॉर्म के साथ एक बाइट बचा सकते हैं:

Length[x.y]
Tr[0x.y+1]

अंत में, इस पर किस तरह की सूचियाँ काम करती हैं, इस बारे में कुछ टिप्पणी:

जैसा कि शीर्ष पर उल्लेख किया गया है, यह केवल संख्याओं, तारों और प्रतीकों वाली फ्लैट सूचियों पर काम करता है। हालाँकि, यह कुछ गहरी सूचियों पर भी काम करेगा, हालाँकि यह वास्तव में कुछ अलग करता है। एक एन- डी आयताकार सरणी के लिए, उपयोग करना Trआपको सबसे छोटा आयाम देता है (पहले के विपरीत)। यदि आप जानते हैं कि सबसे बाहरी आयाम सबसे छोटा है, या आप जानते हैं कि वे सभी समान हैं, तो Tr-expressions अभी भी बराबर हैं Length


3
बस एक और भी छोटा समाधान मिला Length@x == Tr[1^x]:। अधिकांश सूचियों के साथ काम करना चाहिए।
लीजनमोनमाल 978

@ LegionMammal978 यह आश्चर्यजनक है, धन्यवाद :)। मैं जल्द ही इसे संपादित करूंगा।
मार्टिन एंडर

1
दो बार, मैंने खुद को विशेष मामले में एक बाइट को बचाने के Tr[x!]बजाय खुद का उपयोग किया है Tr[1^x]जहां xकेवल शून्य और वाले होते हैं।
मिशा लावरोव

@ मिशालवॉव यह वास्तव में साफ है! :)
मार्टिन एंडर

7
  1. पुनरावर्ती समाधानों का अन्वेषण करें - गणितज्ञ बहु-प्रतिमान है, लेकिन कार्यात्मक दृष्टिकोण अक्सर सबसे किफायती है। NestWhileखोज समस्याओं के लिए एक बहुत कॉम्पैक्ट समाधान हो, और कर सकते हैं NestWhileListऔर FoldListजब आप वापसी या मध्यवर्ती पुनरावृत्तियों के परिणामों की प्रक्रिया पूरी की शक्तिशाली हैं। Map (/@), Apply (@@, @@@), MapThread, और वास्तव में Wolfram की पर सब कुछ कार्यात्मक प्रोग्रामिंग प्रलेखन पेज शक्तिशाली सामान है।

  2. वेतन वृद्धि / गिरावट के लिए संक्षिप्त रूप - उदाहरण के लिए, इसके बजाय While[i<1,*code*;i++]आप कर सकते हैं
    While[i++<1,*code*]

  3. मत भूलो कि आप पूर्व-वृद्धि / वेतन वृद्धि कर सकते हैं - उदाहरण के लिए, --iइसके बजाय i--। यह कभी-कभी तैयारी के संचालन को समाप्त करके आपको आसपास के कोड में कुछ बाइट्स बचा सकता है।

  4. डेविड कारहर के # 5 के लिए कोरोल: जब एक ही फ़ंक्शन का कई बार उपयोग किया जाता है, तो इसे प्रतीक को असाइन करना बाइट्स को बचा सकता है। उदाहरण के लिए, यदि आप ToExpressionकिसी समाधान में 4 बार उपयोग कर रहे हैं, तो आपको इसके बाद t=ToExpressionउपयोग करने में सक्षम बनाता है t@*expression*। हालाँकि, इससे पहले कि आप यह विचार करें कि क्या एक ही फ़ंक्शन का दोहराया जाना अधिक किफायती पुनरावर्ती दृष्टिकोण के लिए एक अवसर का संकेत देता है।


MapThreadअक्सर द्वारा प्रतिस्थापित किया जा सकता है \[Transpose]TIO
user202729

7

{}यदि आप उपयोग कर रहे हैं तो उपयोग न करें @@@

कुछ मामलों में, आप एक अभिव्यक्ति का सामना कर सकते हैं जैसे:

f@@@{{a,b},{c,d}}

लिखकर बाइट कम करना संभव है:

f@@@{a|b,c|d}

Alternativesइसकी बहुत कम पूर्वता है, इसलिए यह आम तौर पर अभिव्यक्ति लिखने के लिए ठीक है (एक उल्लेखनीय अपवाद शुद्ध कार्य है; आप इसे केवल सबसे बाईं ओर के तत्व में उपयोग कर सकते हैं Alternatives)।

f@@@{f@a|b~g~1,#^2&@c|d@2}

ध्यान दें कि f@@a|b|c(के बजाय f@@{a,b,c}) काम नहीं करता है क्योंकि Applyकी तुलना में अधिक पूर्वता है Alternative

इस मामले में, आपको बस उपयोग करना चाहिए f@@{a,b,c}


6

केवल 10 गणितज्ञ

संचालक रूप

Mathematica 10 तथाकथित "ऑपरेटर रूपों" का समर्थन करता है, जिसका मूल रूप से मतलब है कि कुछ कार्यों पर अंकुश लगाया जा सकता है। एक फ़ंक्शन को तैयार करना अपने एक ऑपरेटर को ठीक करके एक नया फ़ंक्शन बनाना है। कहो, आप SortBy[list, somereallylongfunction&]बहुत से अलग का उपयोग कर रहे हैं list। इससे पहले कि आप शायद असाइन किया होगा SortByकरने के लिए sऔर करने के लिए शुद्ध समारोह fइतना

s=SortBy;
f=somereallylongfunction&;
list1~s~f;
list2~s~f;
list3~s~f;

अब आप करी SortByकर सकते हैं, जिसका अर्थ है कि अब आप कर सकते हैं

s=SortBy[somereallylongfunction&];
s@list1;
s@list2;
s@list3;

अन्य कार्यों की शुरुआत की जिसमें एक सूची या समारोह तर्क ले (लेकिन सीमित नहीं) का एक बहुत के लिए एक ही काम करता है Select, Map, Nearest, आदि

Mathematica.SE पर ybeltukov ओवर इन की एक पूरी सूची का उत्पादन करने में सक्षम था :

{"AllTrue", "AnyTrue", "Append", "Apply", "AssociationMap", "Cases", 
 "Count", "CountDistinctBy", "CountsBy", "Delete", "DeleteCases", 
 "DeleteDuplicatesBy", "Extract", "FirstCase", "FirstPosition", 
 "FreeQ", "GroupBy", "Insert", "KeyDrop", "KeyExistsQ", "KeyMap", 
 "KeySelect", "KeySortBy", "KeyTake", "Map", "MapAt", "MapIndexed", 
 "MatchQ", "MaximalBy", "MemberQ", "Merge", "MinimalBy", "NoneTrue", 
 "Position", "Prepend", "Replace", "ReplacePart", "Scan", "Select", 
 "SelectFirst", "SortBy", "StringCases"}

रचना और अधिकार

Composition( @*) और RightComposition( /*) के लिए नए शॉर्टहैंड हैं । एक स्पष्ट रूप से वंचित उदाहरण जहां ये पात्रों को बचा सकते हैं, उन्हें निम्नलिखित तीन समकक्ष लाइनों में देखा जाता है

Last@Range@# & /@ Range[5]
Last@*Range /@ Range[5]
Range /* Last /@ Range[5]

5

0-तर्क कार्य न लिखें

इस तरह कोड की कोई आवश्यकता नहीं है:

f[]:=DoSomething[1,2]
(*...*)
f[]
(*...*)
f[]

आप :=दाहिने हाथ के पक्ष के पुनर्मूल्यांकन के लिए एक चर का उपयोग कर सकते हैं :

f:=DoSomething[1,2]
(*...*)
f
(*...*)
f

इसका मतलब यह भी है कि आप n++5 बाइट्स की कीमत पर किसी भी एक्शन को करने वाले किसी भी एक्शन को (भले ही यह कुछ-कुछ वैसा ही हो ) उर्फ को सिंगल कैरेक्टर में बदल सकते हैं। तो n++चौथे उपयोग के बाद वापस भुगतान करता है:

n++;n++;n++;n++
f:=n++;f;f;f;f

5

%एक मुफ्त चर प्राप्त करने के लिए उपयोग करें

यह टिप केवल तभी लागू होती है जब Mathematica का REPL वातावरण ग्रहण किया जा सकता है। %जब स्क्रिप्ट के रूप में कोड चलाया जाता है, तो इसे परिभाषित नहीं किया जाता है।

जब आप REPL सुविधाओं का उपयोग कर सकते हैं, तो ऐसा न करें:

a=someLongExpression;some[other*a,expression@a,using^a]

इसके बजाय, याद रखें कि गणितज्ञ अंतिम मूल्यांकित (newline-termized) अभिव्यक्ति को इसमें संग्रहीत करता है %:

someLongExpression;
some[other*%,expression@%,using^%]

जोड़े गए न्यूलाइन की एक बाइट खर्च होती है, लेकिन आप दो को हटाकर बचत कर रहे हैं a=, इसलिए कुल मिलाकर यह एक बाइट बचाता है।

कुछ मामलों में (जैसे कि जब aभी आप किसी भी तरह का मूल्य प्रिंट करना चाहते हैं ), तो आप ;दो बाइट्स बचाकर भी छोड़ सकते हैं :

someLongExpression
some[other*%,expression@%,using^%]

एक या दो बाइट्स काफी मामूली लग सकते हैं, लेकिन यह एक महत्वपूर्ण मामला है, क्योंकि यह बार-बार अभिव्यक्ति (जो कि एक बहुत ही सामान्य तकनीक है) के निष्कर्षण को गोल्फ बनाते समय अधिक उपयोगी बनाता है:

बार-बार अभिव्यक्ति निकालने की सामान्य तकनीक में ओवरहेड के चार बाइट्स होते हैं, जिन्हें अभिव्यक्ति के आगे उपयोग से बचाने की आवश्यकता होती है। किसी भी चीज को बचाने के लिए नामित चर में निष्कर्षण के लिए एक अभिव्यक्ति (अभिव्यक्ति की लंबाई) के उपयोग की न्यूनतम संख्या की एक छोटी तालिका है:

Length   Min. Uses
2        6
3        4
4        3
5        3
6        2
...      2

अनाम चर का उपयोग करके, बाइट्स के एक जोड़े को बचाने के लिए बहुत अधिक बार संभव होगा:

When ; is required                        When ; can be omitted

Length   Min. Uses                        Length   Min. Uses
2        5                                2        4
3        3                                3        3
4        3                                4        2
5        2                                ...      2
...      2

मुझे नहीं लगता कि %%या %nगोल्फ के लिए इस्तेमाल किया जा सकता है, क्योंकि यदि आप उन्हें कम से कम दो बार उपयोग नहीं करते हैं, तो आप अभिव्यक्ति को वहीं रख सकते हैं, जहां इसकी आवश्यकता है। और अगर आप इसे दो बार उपयोग करते हैं, तो चर नाम का अतिरिक्त वर्ण कुछ को छोड़ने से बचत को रद्द कर देता है x=


ध्यान दें कि यह स्क्रिप्ट मोड में काम नहीं करता है।
एलेफाल्फा

@alephalpha स्क्रिप्ट मोड क्या है?
मार्टिन एंडर


@alephalpha ओह ठीक है, मैं अपने दिमाग को वहां एक सेकंड के लिए बंद कर देता हूं ... तो इसका मतलब यह है कि इसका वास्तव में उपयोग नहीं किया जा सकता है, जब तक कि आरईपीएल वातावरण ग्रहण नहीं किया जा सकता है।
मार्टिन एंडर

5

यदि किसी सूची को क्रमबद्ध किया गया है तो जाँच करना

यह अनिवार्य रूप से इस टिप का एक कोरोलरी है लेकिन यह एक पर्याप्त रूप से सामान्य कार्य है जो मुझे लगता है कि यह अपने स्वयं के उत्तर का वारंट करता है।

जाँच करने के लिए भोली तरीका है कि कोई सूची क्रम में है या नहीं

OrderedQ@a

हम एक बाइट के साथ बेहतर कर सकते हैं

Sort@a==a

हालाँकि, यह काम नहीं करता है यदि हमारे पास वह चीज नहीं है जिसे हम पहले से ही एक चर में जांचना चाहते हैं। (हमें कुछ ऐसा चाहिए होगा Sort[a=...]==aजो अनावश्यक रूप से लंबा हो।) हालांकि, एक और विकल्प है:

#<=##&@@a

सबसे अच्छी बात यह है कि इसका उपयोग यह जांचने के लिए किया जा सकता है कि इनपुट एक ही बाइट काउंट के लिए उल्टा है या नहीं:

#>=##&@@a

एक और बाइट को बचाया जा सकता है अगर a) हम जानते हैं कि सूची तत्व अलग हैं और b) हम 0 और 9 के बीच एक कम बाउंड जानते हैं (समावेशी; या रिवर्स सॉर्ट किए गए ऑर्डर के लिए ऊपरी बाउंड):

0<##&@@a
5>##&@@a

यह देखने के लिए कि यह क्यों काम करता है, शीर्ष पर जुड़ी टिप में "तर्कों के अनुक्रम" देखें।


वैकल्पिक रूप से, (सख्त) रिवर्स-सॉर्ट किए गए काम के लिए निचली-बाउंड भी ##>0&@@a:। सॉर्ट किए गए ऊपरी-बाउंड के लिए समान।
user202729

@ user202729 ओह अच्छा बिंदु, संपादित करने के लिए स्वतंत्र महसूस करें (अन्यथा अगर मुझे याद है तो मैं इसे सप्ताहांत में करने की कोशिश करूंगा)।
मार्टिन एंडर 10

5

एक स्ट्रिंग को दोहराते हुए

StringRepeat[str,n]उपयोग के बजाय (0Range[n]+str)<>""। या अगर strयह किसी भी स्लॉट तर्क पर निर्भर नहीं करता है, तो भी बेहतर इस टिप के Array[str&,n]<>""अनुसार है ।


1
कोरोलरी: StringRepeat[s,n+1]उपयोग के बजाय Array[s&,n]<>s(यहां तक ​​कि जब आपके पास पहले से ही n+1एक चर में है, तो भी)।
मार्टिन एंडर

बेहतर,Table[str,n]<>""
अटारीट

5

यदि आपको रिवर्स में क्रमबद्ध संख्याओं की सूची की आवश्यकता है, तो उपयोग न करें

Reverse@Sort@x

परंतु

-Sort@-x

छह बाइट बचाने के लिए। नकारात्मक मान द्वारा छाँटना भी SortByपरिदृश्यों के लिए उपयोगी है:

Reverse@SortBy[x,Last]
SortBy[x,-Last@#&]

2
किस बारे में -Sort@-x?
जुंगह्वान मिन

1
@JungHwanMin ओह, उह, हाँ, यह बहुत बेहतर है। :)
मार्टिन एंडर

4

आप एक अभिव्यक्ति छड़ी कर सकते हैं Breakजिसमें एक या दो अक्षर बचा सकते हैं। उदाहरण ( अन्य विवरण स्पष्टता के लिए नहीं ):

result = False;
Break[]

में बदल सकते हैं

Break[result = False]

एक चरित्र को बचाने के लिए। यदि फ़ंक्शन की अभिव्यक्ति में फ़ंक्शन एप्लिकेशन की तुलना में कम पूर्वता नहीं है, तो आप किसी अन्य वर्ण को भी सहेज सकते हैं:

Print@x;
Break[]

में बदल सकते हैं

Break@Print@x

हालांकि अनिर्धारित, तर्क को Breakआसपास के लूप द्वारा लौटाया जाना प्रतीत होता है, जो संभावित रूप से और भी अधिक बचत का कारण बन सकता है।


4

एक स्ट्रिंग से सभी व्हाट्सएप को हटाने के लिए s, उपयोग करें

StringSplit@s<>""

यही है, StringSplitडिफ़ॉल्ट (गैर-व्हाट्सएप घटकों में विभाजित) का उपयोग करें और बस उन्हें वापस एक साथ जोड़ दें। यदि आप किसी अन्य चरित्र से छुटकारा चाहते हैं या सबस्ट्रिंग करना चाहते हैं तो वही शायद सबसे छोटा है:

s~StringSplit~"x"<>""

4

के लिए विकल्प Range

एक बहुत ही सामान्य कार्य 1 से लेकर n(आमतौर पर इनपुट के रूप में दिए गए) तक सभी नंबरों पर कुछ प्रकार के फ़ंक्शन को लागू करना है । ऐसा करने के लिए अनिवार्य रूप से 3 तरीके हैं (उदाहरण के रूप में एक अनाम पहचान फ़ंक्शन का उपयोग करके):

#&/@Range@n
Array[#&,n]
Table[i,{i,n}]

मैं पहले वाले (जो भी कारण हो) के लिए जाता हूं, लेकिन यह शायद ही सबसे अच्छा विकल्प है।

Arrayइसके बजाय का उपयोग कर

उपरोक्त उदाहरण से पता चलता है कि उपयोग Arrayमें एक ही बाइट गिनती है। हालांकि, इसका यह फायदा है कि यह एक एकल अभिव्यक्ति है। विशेष रूप से, यदि आप एक फ़ंक्शन के साथ परिणाम को आगे संसाधित करना चाहते हैं, तो आप fउपसर्ग संकेतन का उपयोग कर सकते हैं, जो एक बाइट को बचाता है Range:

f[#&/@Range@n]
f@Array[#&,n]

इसके अलावा, आप अपने अनाम फ़ंक्शन के चारों ओर कोष्ठक को छोड़ सकते हैं, जिसकी आपको आवश्यकता हो सकती है Range, जैसे

15/(#&)/@Range@n
15/Array[#&,n]

यदि आप इसे आगे उपयोग नहीं करना चाहते हैं (या किसी ऑपरेटर के पास जिसकी पूर्ववर्तीता कम है), तो आप इसके बजाय Arrayखुद को infix संकेतन में लिख सकते हैं और एक बाइट भी बचा सकते हैं:

#&/@Range@n
#&~Array~n

इसलिए, Arrayलगभग निश्चित रूप से बेहतर है Range

Tableइसके बजाय का उपयोग कर

अब तालिका को 3 बाइट्स या कम से कम 2 के लिए बनाना होगा जब infix अंकन एक विकल्प है:

#&/@Range@n
i~Table~{i,n}

जब infix संकेतन का उपयोग नहीं कर रहा है, Tableतो यदि आप अपने फ़ंक्शन में कई कथनों को शामिल करते हैं, तो आपको कोष्ठक को छोड़ना पड़ सकता है:

(#;#)&/@Range@n
Table[i;i,{i,n}]

यह अभी भी लंबा है, लेकिन नीचे उल्लेखित मामले में अतिरिक्त बचत देता है।

इस तथ्य से वास्तविक बचत स्टेम Tableजो चल चर को एक नाम देता है उसे खारिज नहीं किया जाना चाहिए। अक्सर, आपने उन अनाम फ़ंक्शंस को नेस्ट किया होगा जहां आप बाहरी चर का उपयोग आंतरिक कार्यों में से एक के अंदर करना चाहते हैं। जब ऐसा होता है, Tableतो इससे छोटा होता है Range:

(i=#;i&[])&/@Range@n
Table[i&[],{i,n}]
i&[]~Table~{i,n}

न केवल आप असाइन करने के लिए पात्रों को बचाते हैं i, आप इस प्रक्रिया में फ़ंक्शन को एक बयान में भी कम करने में सक्षम हो सकते हैं, जो आपको इसके शीर्ष पर infix संकेतन का उपयोग करने की अनुमति देता है। संदर्भ के लिए, Arrayइस मामले में भी लंबा है, लेकिन अभी भी इससे छोटा है Range:

(i=#;i&[])&~Array~n

आप वास्तव में कब उपयोग करेंगे Range?

जब भी आपको मानों को संसाधित करने के लिए फ़ंक्शन कॉल की आवश्यकता नहीं होती है, उदाहरण के लिए जब मैपिंग को सदिश ऑपरेशन के माध्यम से किया जा सकता है। उदाहरण के लिए:

5#&~Array~n
5Range@n
#^2&~Array~n
Range@n^2

बेशक, यह भी छोटा है अगर आप किसी भी फ़ंक्शन को मैप नहीं करना चाहते हैं, जैसे

Mean@Array[#&,n]
Mean@Range@n

अंत में कोई और जो f/@Range[x]नियमित रूप से उपयोग करता है ...
LegionMammal978

4

किसी शर्त को पूरा करने वाली सबसे छोटी संख्या का पता लगाना

जैसा i=1;While[cond[i],i++]है वैसा ही कुछ निर्माण ठीक है, लेकिन एक विकल्प है जो दो बाइट्स छोटा है:

1//.i_/;cond[i]:>i+1

उपरोक्त कोड बार-बार एक नंबर iको बदल देता है i+1जबकि यह शर्त पूरी करता है cond[i]। इस मामले में, iशुरू होता है 1

ध्यान दें कि पुनरावृत्तियों की डिफ़ॉल्ट अधिकतम संख्या 2 ^ 16 (= 65536) है। अगर आपको इससे अधिक पुनरावृत्तियों की आवश्यकता है, Whileतो बेहतर होगा। ( MaxIterations->∞बहुत लंबा है)


4

दुरुपयोग शॉर्ट सर्किट मूल्यांकन

आप कभी-कभी Ifएक तार्किक ऑपरेटर से बदल सकते हैं ।

उदाहरण के लिए, मान लें कि आप एक फ़ंक्शन बनाना चाहते हैं जो यह जांचता है कि क्या नंबर प्राइम है, और प्रिंट 2*(number) - 1यदि यह सच है:

If[PrimeQ@#,Print[2#-1]]&

यदि आप &&इसके बजाय उपयोग करते हैं तो यह छोटा है :

PrimeQ@#&&Print[2#-1]&

यहां तक ​​कि जब आपके पास कई भाव होते हैं, तब भी आप बाइट बचाते हैं:

If[PrimeQ@#,a++;Print[2#-1]]&

PrimeQ@#&&a++&&Print[2#-1]&
(* or *)
PrimeQ@#&&(a++;Print[2#-1])&

आप उन ||मामलों के लिए उपयोग कर सकते हैं जब आप चाहते हैं कि शर्त यह हो False:

If[!PrimeQ@#,Print[2#-1]]&
(* or *)
If[PrimeQ@#,,Print[2#-1]]&
(* can become *)
PrimeQ@#||Print[2#-1]&

ये तरकीबें काम करती हैं क्योंकि लॉजिकल ऑपरेटर्स को शॉर्ट-सर्कुलेट किया जा सकता है ; दूसरे तर्क और उसके बाद भी वैध बूलियन अभिव्यक्ति की आवश्यकता नहीं है।

बेशक, यह तब काम नहीं करता है Ifजब आपको वापसी मूल्य की आवश्यकता होती है या जब आपको सच्चाई और झूठे तर्क दोनों की आवश्यकता होती है If


3

यहां एक सूची है जिसमें ऑपरेटर इनपुट रूपों का भार है जो बहुत सारी चीजों को छोटा कर सकता है। इनमें से कुछ का उल्लेख अन्य पोस्टों में किया गया है, लेकिन सूची लंबी है और मुझे हमेशा वहाँ पर कुछ नई चीजें खोजने के लिए आश्चर्य होता है:


हालाँकि, यह केवल तभी काम करता है जब ऑपरेटर कम UTF-8 बाइट्स का उपयोग करता है।
लीजियनममाल 978

3

का उपयोग करते हुए Optional (:)

Optional (:) प्रतिस्थापन के लिए सूचियों का विस्तार करने के लिए इस्तेमाल किया जा सकता है, विस्तार के लिए एक अलग नियम को परिभाषित किए बिना।

मेरे द्वारा यह उत्तर और @ngenisis द्वारा यह उत्तर उदाहरण हैं।

प्रयोग

... /. {p___, a_: 0, b_, q___} /; cond[b] :> ...

उपरोक्त प्रतिस्थापन पहले पैटर्न का उपयोग करता है {p___, a_, b_, q___}और एक ऐसा मैच पाता है जो bएक निश्चित स्थिति को पूरा करता है।

जब ऐसा कोई मैच नहीं मिलता है, तो यह चूक जाता है a_और इसके बजाय खोज करता है {p___, b_, q___}aखोज में शामिल नहीं है और मान लिया गया है 0

ध्यान दें कि दूसरा पैटर्न खोज केवल उसी के लिए काम करेगा bजो सूची की शुरुआत में होता है; यदि किसी bशर्त को पूरा करने का कोई मूल्य बीच में है, तो {p___, a_, b_, q___}(जिसकी उच्च मिसाल है) इसके बजाय उसका मिलान करेगा।

0जब bसूची की शुरुआत में एक संतोषजनक स्थिति होती है तो प्रतिस्थापन प्रीपेंडिंग के बराबर होता है। (अर्थात अलग नियम को परिभाषित करने की आवश्यकता नहीं है {b_, q___} /; cond[b] :> ...)


3

जानिए कब (और कब नहीं) नाम शुद्ध कार्य तर्कों का उपयोग करने के लिए

कोड गोल्फ के लिए, शुद्ध Functionदलीलों को आमतौर पर Slots का उपयोग करके संदर्भित किया जाता है ; जैसे #पहले तर्क के #2लिए, दूसरे के लिए आदि ( अधिक विवरण के लिए यह उत्तर देखें)।

कई मामलों में, आप घोंसला बनाना चाहेंगे Function। उदाहरण के लिए, 1##&@@#&एक है Functionजो अपनी पहली तर्क के रूप में एक सूची लेता है और उसके तत्वों का उत्पाद आउटपुट। यहाँ उस समारोह में है TreeForm:

यहाँ छवि विवरण दर्ज करें

शीर्ष स्तर पर दिए गए तर्क Functionकेवल शीर्ष स्तर पर मौजूद Slots और SlotSequences को भर सकते हैं , जो इस मामले में इसका मतलब है कि SlotSequenceभीतर के Functionलोगों के पास शीर्ष स्तर तक तर्क तक पहुँचने का कोई रास्ता नहीं होगा Function

हालांकि, कुछ मामलों में, आप बाहरी के लिए तर्कों को संदर्भित करने में सक्षम होने के लिए Functionएक दूसरे के भीतर एक नेस्टेड चाह सकते हैं । उदाहरण के लिए, आप कुछ ऐसा चाह सकते हैं , जहाँ फ़ंक्शन शीर्ष स्तर के तर्क पर निर्भर करता है । समवर्ती के लिए, मान लें कि इसके इनपुट मोडुलो के शेष को इनपुट को शीर्ष स्तर पर देना चाहिए । इसे पूरा करने का एक तरीका यह है कि शीर्ष स्तर के तर्क को एक चर में नियत किया जाए:FunctionFunctionArray[fun,...]&funFunctionfunFunction

(x=#;Array[Mod[#^2,x]&,...])&

जहां भी xभीतर दिखाई Function Mod[#^2,x]&पड़ता है, वह पहले तर्क को बाहरी को संदर्भित करेगा Function, जबकि #आंतरिक को पहले तर्क को संदर्भित करेगा Function। एक बेहतर दृष्टिकोण इस तथ्य का उपयोग करना है कि Functionदो तर्क रूप हैं जहां पहला तर्क एक प्रतीक या प्रतीकों की सूची है जो नामित तर्कों का प्रतिनिधित्व करेगा Function(जैसा कि अनाम Slotएस के विपरीत )। यह इस मामले में हमें तीन बाइट्स बचाने के लिए समाप्त होता है:

xArray[Mod[#^2,x]&,...]

U+F4A1बाइनरी इन्फिक्स ऑपरेटर का प्रतिनिधित्व करने वाला तीन बाइट निजी उपयोग चरित्र है \[Function]। आप Functionदूसरे के भीतर बाइनरी फॉर्म का उपयोग भी कर सकते हैं Function:

Array[xMod[x^2,#],...]&

यह ऊपर के बराबर है। कारण यह है कि है, यदि आप नामित तर्कों का उपयोग कर रहे हैं, तो Slotहै और SlotSequencesअगले के हैं मान लिया जाता Functionहै, जो ऊपर नाम तर्क का उपयोग नहीं करता।

अब सिर्फ इसलिए कि हम Functionइस तरह से घोंसला बना सकते हैं , इसका मतलब यह नहीं है कि हमें हमेशा चाहिए। उदाहरण के लिए, यदि हम किसी सूची के उन तत्वों को चुनना चाहते हैं जो इनपुट से कम हैं, तो हमें कुछ करने के लिए लुभाया जा सकता है:

Select[...,xx<#]&

यह वास्तव में उपयोग करने के लिए छोटा होगा Casesऔर Functionपूरी तरह से नेस्टेड की आवश्यकता से बचने के लिए :

Cases[...,x_/;x<#]&

2

आप आसपास काम करके एक बाइट को बचा सकते हैं Prependया PrependTo:

l~Prepend~x
{x}~Join~l
{x,##}&@@l

या

l~PrependTo~x
l={x}~Join~l
l={x,##}&@@l

दुर्भाग्य से, यह अधिक सामान्य के लिए मदद नहीं करता है Append, जो Array.push()अन्य भाषाओं में सबसे कम समकक्ष है ।


2

मेथेमेटिका 10.2: BlockMapहै Partition+Map

इस टिप को शीर्षक भी दिया जा सकता है, "रिलीज नोट्स पढ़ें, उन सभी को"। (संदर्भ के लिए, यहाँ 10.2 के लिए रिलीज नोट्स हैं और आज के 10.3 रिलीज के यहाँ ।)

वैसे भी, यहां तक ​​कि मामूली रिलीज में नई सुविधाओं का खजाना होता है, और 10.2 से अधिक उपयोगी वाले (गोल्फ के लिए) नया BlockMapफ़ंक्शन होता है। यह अनिवार्य रूप से जोड़ती है Partitionऔर Map, जो कि गोल्फर्स के लिए बहुत अच्छा है, क्योंकि Partitionइसका उपयोग अक्सर किया जाता है, और यह वास्तव में बहुत लंबे समय तक चलने वाला नाम है। नया फ़ंक्शन अपने आप छोटा नहीं होगा Partition, लेकिन जब भी आप किसी फ़ंक्शन को पार्टीशन पर मैप करना चाहते हैं (जो संभवतः अधिक बार नहीं होता है), तो आप अब एक बाइट या दो बचा सकते हैं:

#&/@l~Partition~2
BlockMap[#&,l,2]
#&/@Partition[l,3,1]
BlockMap[#&,l,3,1]

बचत तब और अधिक बढ़ जाती है जब अनाम फ़ंक्शन की नई स्थिति आपको कुछ स्वयं को बचाने के लिए अनुमति देती है:

#&@@(#&/@Partition[l,3,1])
#&@@BlockMap[#&,l,3,1]

दुर्भाग्य से, मुझे नहीं पता कि BlockApplyवे उस समय क्यों नहीं जोड़े गए थे ...

यह भी ध्यान दें कि चक्रीय सूची प्राप्त करने के लिए BlockMapआप 4 के पैरामीटर का समर्थन नहीं करते हैं Partition:

Partition[Range@5, 2, 1, 1]
(* Gives {{1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 1}} *)
BlockMap[f, Range@5, 2, 1, 1]
(* Nope... *)

2

एक चर में कार्यों और अभिव्यक्तियों का भंडारण

यदि आपका उत्तर कई बार समान फ़ंक्शन या अभिव्यक्तियों का उपयोग करके समाप्त होता है, तो आप उन्हें चर में संग्रहीत करने पर विचार कर सकते हैं।

यदि आपकी अभिव्यक्ति की लंबाई है lऔर आप इसे nकई बार उपयोग करते हैं, तो यह आम तौर पर l * nबाइट्स का उपयोग करेगा ।

हालाँकि, यदि आप इसे एक लंबाई -1 चर में संग्रहीत करते हैं, तो यह केवल 3 + l + nबाइट्स (या 2 + l + nबाइट्स, यदि आप चर को असाइन करते हैं जहाँ आपको आवश्यकता नहीं होगी CompoundExpression (;)या कोष्ठक नहीं होंगे )।


उदाहरण के लिए, आइए एक साधारण समस्या पर विचार करें, एन की तुलना में दो गुना कम जुड़ावों का पता लगाना ।

कोई यह 54 बाइट समाधान लिख सकता है:

Select[Range@#,PrimeQ@#&&(PrimeQ[#+2]||PrimeQ[#-2])&]&

इस उदाहरण में, फ़ंक्शन PrimeQतीन बार उपयोग किया जाता है।

PrimeQएक चर नाम निर्दिष्ट करके , बाइट की संख्या को कम किया जा सकता है। निम्नलिखित दोनों 48 बाइट्स (54 - 6 बाइट्स) हैं:

Select[p=PrimeQ;Range@#,p@#&&(p[#+2]||p[#-2])&]&
Select[Range@#,(p=PrimeQ)@#&&(p[#+2]||p[#-2])&]&

2

आरोही कुंजी-मूल्य सूची प्राप्त करने के लिए, Sortइसके बजाय का उपयोग करेंSortBy

जैसे सूचियों के लिए list = {{1, "world"}, {0, "universe"}, {2, "country"}}, निम्नलिखित तीन कथन लगभग बराबर हैं।

SortBy[list,#[[1]]&]
list~SortBy~First
Sort@list

मिलाना SelectऔरSortBy

कभी-कभी हमें बड़े सेट से प्रविष्टियाँ लेने की आवश्यकता होती है और उन्हें न्यूनतम / अधिकतम खोजने के लिए छाँटना पड़ता है। कुछ परिस्थितियों में , दो ऑपरेशनों को एक में जोड़ा जा सकता है।

उदाहरण के लिए, न्यूनतम के लिए, निम्नलिखित दो कथन लगभग बराबर हैं।

SortBy[Select[l,SomeFormula==SomeConstant&],SortValue&]
SortBy[l,SortValue+99!(SomeFormula-SomeConstant)^2&]

तथा

SortBy[Select[l,SomeFormula!=SomeConstant&],SortValue&]
SortBy[l,SortValue+1/(SomeFormula-SomeConstant)&]

1/0है ComplexInfinityजो सभी वास्तविक संख्या की तुलना में "बड़ा",।

कुंजी-मूल्य सूची के लिए, उदाहरण के लिए:

{SortValue,#}&/@SortBy[Select[l,SomeFormula==SomeConstant],SortValue&]
Sort[{SortValue+99!(SomeFormula-SomeConstant)^2,#})&/@l]

1

एक Arrayसाथ चपटे##&

परिणाम की सूची की गणना करने के लिए बहुआयामी सरणी का उपयोग करते समय, चपटा होने की आवश्यकता होती है, ##&चौथे तर्क के रूप में उपयोग करें । इसके स्थान पर Array के सिर को ##&(समतुल्य Sequence) के स्थान पर प्रतिस्थापित किया जाता है List, इसलिए अंतिम परिणाम Sequenceपरिणामों का (सपाट) होगा ।

दो आयामों में, तुलना करें

{Array[f,dims,origin,##&]}
Join@@Array[f,dims,origin]

बेशक, Join@@Array[f,dims] अभी भी 2 (या 3, यदि इन्फिक्स नोटेशन का उपयोग किया जा सकता है) बाइट्स से कम है {Array[f,dims,1,##&]}

तीन या अधिक आयामों में, {Array[f,dims,origin,##&]}हमेशा विकल्प से कम होता है, भले ही मूल 1 हो।

{Array[f,dims,1,##&]}
f~Array~dims~Flatten~2

1

डिफ़ॉल्ट मान

डिफ़ॉल्ट मान एक कुशल तरीके से अनुपलब्ध पैटर्न तर्कों से निपटते हैं। उदाहरण के लिए, यदि हम Exp[c_*x]किसी नियम में c, भोले के लिए मैच पैटर्न करना चाहते हैं

Exp[x] + Exp[2x] /. {Exp[c_*x] -> f[c], Exp[x] -> f[1]}
(*    f[1] + f[2]    *)

यदि हम cलापता होने पर डिफ़ॉल्ट मान का उपयोग करने की तुलना में कई बाइट्स का उपयोग करते हैं:

Exp[x] + Exp[2 x] /. Exp[c_.*x] -> f[c]
(*    f[1] + f[2]    *)

डिफ़ॉल्ट का उपयोग पैटर्न के बाद एक डॉट के साथ इंगित किया गया है c_.:।

डिफ़ॉल्ट मान संचालन के साथ जुड़े हुए हैं: उपरोक्त उदाहरण में, ऑपरेशन Timesमें है c_.*x, और इसके लिए एक लापता मूल्य c_इस प्रकार से जुड़ा हुआ डिफ़ॉल्ट मान से लिया गया है Times, जो 1. है। Plusडिफ़ॉल्ट मान 0 के लिए है:

Exp[x] + Exp[x + 2] /. Exp[x + c_.] -> f[c]
(*    f[0] + f[2]    *)

के लिए Powerघातांक, डिफ़ॉल्ट 1:

x + x^2 /. x^n_. -> p[n]
(*    p[1] + p[2]    *)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.