फिशाइल नंबर


47

मुझे यह अनुक्रम OEIS के इवोल्यूशन पर काम करते हुए मिला, लेकिन इसे उत्तर के रूप में पोस्ट करने के लिए कभी भी नहीं मिला। मैथेमेटिका में एक संदर्भ कार्यान्वयन लिखने के बाद, मैंने सोचा कि यह एक अलग चुनौती के रूप में करने के लिए एक मजेदार अभ्यास है, इसलिए यहां हम जाते हैं।

आइए एक संख्यात्मक विखंडन रिएक्टर का निर्माण करें! एक सकारात्मक पूर्णांक पर विचार करें N। एक उदाहरण के रूप में, हम देखेंगे 24। इस संख्या का विखंडन करने के लिए, हमें सबसे अधिक संख्या में लगातार सकारात्मक पूर्णांकों को खोजना होगा जो कि योग करते हैं N। इस मामले में, यह है 7 + 8 + 9 = 24। इसलिए हम 24तीन नए नंबरों में विभाजित हो गए हैं। लेकिन यह श्रृंखला प्रतिक्रियाओं के बिना एक विखंडन रिएक्टर का ज्यादा हिस्सा नहीं होगा। तो आइए इन घटकों के लिए पुनरावर्ती प्रक्रिया दोहराएं:

       24
       /|\
      / | \
     /  |  \
    7   8   9
   / \     /|\
  3   4   / | \
 / \     /  |  \
1   2   2   3   4
           / \
          1   2

ध्यान दें कि जब भी संख्या लगातार छोटे पूर्णांकों में विघटित नहीं हो सकती है, तो हम इस प्रक्रिया को रोक देते हैं। यह भी ध्यान रखें कि हम लिख सकता 9के रूप में 4 + 5है, लेकिन 2 + 3 + 4अधिक घटक हैं। विखंडन संख्या का Nअब सहित इस प्रक्रिया, में प्राप्त पूर्णांकों की संख्या के रूप में परिभाषित किया गया है Nही। उपरोक्त पेड़ में 13 नोड्स हैं, इसलिए F(24) = 13

यह अनुक्रम OEIS प्रविष्टि A256504 है

से शुरू होने वाले पहले 40 पद N = 1हैं

1, 1, 3, 1, 5, 6, 5, 1, 6, 7, 12, 10, 12, 11, 12, 1, 8, 16, 14, 17, 18, 18,
23, 13, 21, 18, 22, 23, 24, 19, 14, 1, 22, 20, 23, 24, 31, 27, 25, 26

इस पास्टबिन में पहले 1000 शब्द पाए जा सकते हैं ।

चुनौती

एक सकारात्मक पूर्णांक को देखते हुए N, इसकी विखंडन संख्या निर्धारित करें F(N)। (इसलिए आपको 0OEIS पर सूचीबद्ध अग्रणी को कवर करने की आवश्यकता नहीं है ।)

आप STDIN (या निकटतम विकल्प), कमांड-लाइन तर्क या फ़ंक्शन तर्क के माध्यम से इनपुट ले रहे हैं और STDOUT (या निकटतम विकल्प), फ़ंक्शन रिटर्न मान या फ़ंक्शन (आउट) पैरामीटर के माध्यम से परिणाम लिख सकते हैं।

यह कोड गोल्फ है, इसलिए सबसे छोटा उत्तर (बाइट्स में) जीतता है।

बोनस प्रश्न: क्या आप इस क्रम का कोई दिलचस्प गुण पा सकते हैं?


मुझे लगता है कि OEIS को n = 34 में त्रुटि प्रतीत होती है: n = 32 से शुरू होकर, यह 1, 22, 22, 23, 24, 31 की बजाय 1, 22, 20, 23, 24 को सूचीबद्ध करता है। 31.
मैथमंडन

1
@ मिथमांडन अच्छा कैच, मैं शायद एक सुधार (पहले आरेख के साथ) प्रस्तावित करूंगा।
मार्टिन एंडर

संबंधित चुनौती: codegolf.stackexchange.com/questions/5703/… (और math.S पर एक ही सवाल। math.stackexchange.com/questions/139842/… )
इल्मरी करोनेंन

@mathmandan FYI करें, मैंने अनुक्रम और उदाहरण को अब ठीक कर दिया है, और मेरे संदर्भ कार्यान्वयन और पहले 10k शब्दों को भी जोड़ा है।
मार्टिन एंडर

अछा लगता है! आपके काम के लिए धन्यवाद!
mathmandan

जवाबों:


16

पायथ, 23 22 21 बाइट्स

Lh&lJfqbsT.:tUb)syMeJ

यह एक पुनरावर्ती कार्य को परिभाषित करता है y। इसे ऑनलाइन आज़माएँ: प्रदर्शन

स्पष्टीकरण:

L                      define a function y(b): return ...
            tUb          the list [1, 2, ..., b-1]
          .:   )         generate all consecutive sub-sequences
     f                   filter for sub-sequences T, which satisfy:
      qbsT                   b == sum(T)
    J                    and store them in J

                         return 
   lJ                        len(J)
  &                        and (if len(J) == 0 then 0 else ...)
                    eJ       last element of J (=longest sub-sequence) 
                  yM         recursive calls for all these numbers
                 s           sum
 h                         incremented by one (counting the current node)

52

विखंडन , 1328 989 887 797 बाइट्स

यह उत्तर थोड़ा अनुचित रूप से लंबा है (काश हमारे पास समाप्‍त क्षेत्र होते ) ... कृपया इस अतीत को स्‍क्रॉल करना न भूलें और दूसरे जवाबों को थोड़ा प्‍यार करें!

इस कोड पर काम करना इस चुनौती से प्रेरित था। मैं Fission में EOEIS में एक उत्तर जोड़ना चाहता था, जिसने मुझे इस अनुक्रम में ले गया। हालांकि, वास्तव में विखंडन सीखना और इसे लागू करने में कुछ ही हफ्तों का समय लग गया। इस बीच, अनुक्रम वास्तव में मुझ पर बढ़ गया था, इसलिए मैंने इसके लिए एक अलग चुनौती पोस्ट करने का फैसला किया (इसके अलावा, यह विशेष रूप से ईओईआईएस पर पेड़ से बहुत दूर नहीं होगा)।

इसलिए मैं आपके सामने पेश करता हूं, राक्षसी:

 R'0@+\
/  Y@</ /[@ Y]_L
[? % \  / \ J
   \$@  [Z/;[{+++++++++L
UR+++++++++>/;
9\   ;    7A9
SQS  {+L  /$     \/\/\/\/\/   5/ @  [~ &@[S\/ \  D /8/
~4X /A@[  %5                   /; &    K  } [S//~KSA /
  3    \  A$@S  S\/  \/\/\/   \/>\ /S]@A  /  \ { +X
W7           X  X    /> \      +\ A\ /   \ /6~@/ \/
        /   ~A\;     +;\      /@
    ZX [K    / {/  / @  @ }  \ X @
       \AS   </      \V /    }SZS S/
         X   ;;@\   /;X  /> \ ; X X
 ;       \@+  >/ }$S SZS\+;    //\V
           / \\  /\; X X @  @  \~K{
           \0X /     /~/V\V /   0W//
    \        Z      [K \  //\
W       /MJ $$\\ /\7\A  /;7/\/ /
       4}K~@\ &]    @\  3/\
 /     \{   }$A/1 2  }Y~K <\
[{/\  ;@\@  /   \@<+@^   1;}++@S68
@\ <\    2        ;   \    /
$  ;}++ +++++++L
%@A{/
M  \@+>/
~     @
SNR'0YK
  \  A!/

यह उम्मीद करता है कि इनपुट पर कोई अनुगामी न्यूलाइन नहीं है, इसलिए आप इसे पसंद करना चाहते हैं echo -n 120 | ./Fission oeis256504.fis

लेआउट शायद अभी भी अधिक कुशल हो सकता है, इसलिए मुझे लगता है कि अभी भी यहां सुधार के लिए बहुत जगह है (उदाहरण के लिए, इसमें 911 581 461 374 स्थान शामिल हैं)।

इससे पहले कि हम स्पष्टीकरण पर जाएं, इस परीक्षण पर एक नोट: आधिकारिक दुभाषिया पूरी तरह से काम नहीं करता है। क) Mirror.cppकई प्रणालियों पर संकलन नहीं करता है। यदि आप उस समस्या में भाग लेते हैं, तो आपत्तिजनक लाइन पर टिप्पणी करें - इस कोड में प्रभावित घटक (एक यादृच्छिक दर्पण) का उपयोग नहीं किया गया है। बी) कुछ ऐसे कीड़े हैं जो अपरिभाषित व्यवहार का नेतृत्व कर सकते हैं (और इस कार्यक्रम के लिए संभावना होगी)। आप उन्हें ठीक करने के लिए इस पैच को लगा सकते हैं। एक बार जब आप ऐसा कर लेते हैं, तो आपको दुभाषिया को संकलित करने में सक्षम होना चाहिए

g++ -g --std=c++11 *.cpp -o Fission

मजेदार तथ्य: यह कार्यक्रम लगभग हर घटक का उपयोग करता है विखंडन #(यादृच्छिक दर्पण), :(आधा दर्पण), -या |(सादा दर्पण), और "(प्रिंट मोड) को छोड़कर, की पेशकश करनी है ।

पृथ्वी पर क्या?

चेतावनी: यह काफी लंबा होगा ... मुझे लगता है कि आप वास्तव में रुचि रखते हैं कि विखंडन कैसे काम करता है और इसमें कोई कैसे कार्यक्रम कर सकता है। क्योंकि यदि आप नहीं हैं, तो मुझे यकीन नहीं है कि मैं इसे कैसे संक्षेप में बता सकता हूं। (अगला पैराग्राफ हालांकि भाषा का एक सामान्य विवरण देता है।)

विखंडन एक दो-आयामी प्रोग्रामिंग भाषा है, जहां डेटा और नियंत्रण प्रवाह दोनों का प्रतिनिधित्व ग्रिड के माध्यम से जाने वाले परमाणुओं द्वारा किया जाता है। यदि आपने पहले मारबेलस देखा या उपयोग किया है , तो अवधारणा को पूरी तरह से परिचित होना चाहिए। प्रत्येक परमाणु में दो पूर्णांक गुण होते हैं: एक गैर-नकारात्मक द्रव्यमान और एक मनमाना ऊर्जा। यदि द्रव्यमान कभी ऋणात्मक हो जाता है तो परमाणु को ग्रिड से हटा दिया जाता है। ज्यादातर मामलों में आप द्रव्यमान को परमाणु के "मूल्य" के रूप में और ऊर्जा को किसी प्रकार की मेटा-प्रॉपर्टी के रूप में मान सकते हैं जो परमाणुओं के प्रवाह को निर्धारित करने के लिए कई घटकों द्वारा उपयोग किया जाता है (अर्थात अधिकांश प्रकार के स्विच के संकेत पर निर्भर करते हैं) शक्ति)। (m,E)जब आवश्यक हो, मैं परमाणुओं को निरूपित करूंगा । कार्यक्रम की शुरुआत में, ग्रिड एक गुच्छा के साथ शुरू होता है(1,0)आप चार घटकों पर जहां भी जगह रखते हैं वहां से परमाणु UDLR(जहां अक्षर उस दिशा को इंगित करता है जहां परमाणु शुरू में घूम रहा है)। बोर्ड को तब घटकों के एक पूरे समूह के साथ आबाद किया जाता है जो परमाणुओं के द्रव्यमान और ऊर्जा को बदलते हैं, उनकी दिशा बदलते हैं या अन्य अधिक परिष्कृत चीजें करते हैं। पूरी सूची के लिए एसोलैंग्स पेज देखें , लेकिन मैं उनमें से अधिकांश को इस स्पष्टीकरण में पेश करूंगा। एक अन्य महत्वपूर्ण बिंदु (जो प्रोग्राम कई बार उपयोग करता है) यह है कि ग्रिड टॉरॉयडल है: एक परमाणु जो किसी भी तरफ से टकराता है वह विपरीत दिशा में फिर से दिखाई देता है, उसी दिशा में आगे बढ़ रहा है।

मैंने कई छोटे हिस्सों में कार्यक्रम लिखा और अंत में उन्हें इकट्ठा किया, इसलिए मैं स्पष्टीकरण के माध्यम से जाऊंगा।

atoi

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

विखंडन केवल व्यक्तिगत वर्णों से बाइट मानों को पढ़ सकता है, संपूर्ण संख्याओं को नहीं। जबकि यह स्वीकार्य अभ्यास यहाँ है, मुझे लगा कि जब मैं इस पर था, मैं इसे सही कर सकता था और STDIN पर वास्तविक पूर्णांकों को पार्स कर सकता था। यहाँ atoiकोड है:

     ;
 R'0@+\
/  Y@</ /[@ Y]_L
[? % \  / \ J 
   \$@  [Z/;[{+++++++++L
UR+++++++++>/;
           O

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

फ्यूजन रिएक्टर किसी भी YA{}(उपरोक्त कोड का उपयोग करता है Yऔर {) हैं। उनका कार्य समान है: वे एक परमाणु (डिफ़ॉल्ट (1,0)) को स्टोर कर सकते हैं और शीर्ष से हिट होने पर दो नए परमाणुओं को पक्षों पर भेज दिया जाएगा। हालांकि, इस मामले में दो परमाणु समान होंगे, हमेशा आने वाली ऊर्जा को बनाए रखेंगे, और संग्रहीत द्रव्यमान द्वारा आने वाले द्रव्यमान को गुणा करेंगे। यही है, डिफ़ॉल्ट रूप से, संलयन रिएक्टर बस किसी भी परमाणु को उसके शीर्ष को मारता हुआ डुप्लिकेट करता है। जब पक्षों से मारा जाता है, तो फ्यूजन रिएक्टर थोड़ा अधिक जटिल होते हैं: परमाणु भी हैसंग्रहीत (स्वतंत्र रूप से अन्य मेमोरी में) जब तक एक परमाणु विपरीत पक्ष को हिट नहीं करता है। जब ऐसा होता है तो शीर्ष की दिशा में एक नया परमाणु छोड़ा जाता है जिसका द्रव्यमान और ऊर्जा दो पुराने परमाणुओं का योग होता है। यदि एक नया परमाणु एक ही तरफ से टकराता है इससे पहले कि एक मिलान परमाणु विपरीत पक्ष तक पहुंच जाए, तो पुराना परमाणु बस ओवरराइट हो जाएगा। फ्यूजन रिएक्टरों का उपयोग जोड़ और गुणा को लागू करने के लिए किया जा सकता है।

एक और सरल घटक जो मैं बाहर निकलना चाहता हूं वह है [और ]जो क्रमशः परमाणु की दिशा को दाएं और बाएं सेट करता है, क्रमशः (आवक की परवाह किए बिना)। ऊर्ध्वाधर समतुल्य M(नीचे) और W(ऊपर) हैं, लेकिन वे atoiकोड के लिए उपयोग नहीं किए जाते हैं । अपने प्रारंभिक परमाणुओं को छोड़ने के बाद UDLRभी कार्य करते WM][हैं।

वैसे भी, वहाँ कोड को देखते हैं। कार्यक्रम 5 परमाणुओं के साथ शुरू होता है:

  • Rऔर Lतल पर बस (के साथ अपने बड़े पैमाने पर वेतन वृद्धि मिल +) बनने के लिए (10,0)और फिर एक विखंडन और एक संलयन रिएक्टर में जमा हो जाती है, क्रमशः। हम बेस -10 इनपुट पार्स करने के लिए इन रिएक्टरों का उपयोग करेंगे।
  • Lऊपरी दाएं कोने में उसके द्रव्यमान (साथ कम कर जाता है _) बनने के लिए (0,0)और एक संलयन रिएक्टर के पक्ष में संग्रहित है Y। यह उस संख्या पर नज़र रखने के लिए है जिसे हम पढ़ रहे हैं - जैसे ही हम संख्याएँ पढ़ेंगे, हम धीरे-धीरे इसे बढ़ाएँगे और गुणा करेंगे।
  • Rऊपरी बाएँ कोने में उसके द्रव्यमान का चरित्र कोड करने के लिए सेट हो जाता है 0(48) के साथ '0है, तो बड़े पैमाने पर और ऊर्जा के साथ लगा दिया जाता था @और अंत में बड़े पैमाने पर एक बार के साथ बढ़ती +देने के लिए (1,48)। यह तो विकर्ण दर्पण के साथ पुनः निर्देशित किया जाता \है और /एक विखंडन रिएक्टर में संग्रहीत करने के लिए। हम 48ASCII इनपुट को अंकों के वास्तविक मानों में बदलने के लिए घटाव के लिए उपयोग करेंगे । हमें 1विभाजन से बचने के लिए जन को भी बढ़ाना पड़ा 0
  • अंत Uमें, निचले बाएं कोने में वह है जो वास्तव में गति में सब कुछ सेट करता है और शुरू में केवल नियंत्रण प्रवाह के लिए उपयोग किया जाता है।

दाएं पर पुनर्निर्देशित होने के बाद, नियंत्रण परमाणु हिट करता है ?। यह इनपुट घटक है। यह एक चरित्र को पढ़ता है और परमाणु के द्रव्यमान को ASCII मान और ऊर्जा पढ़ने के लिए सेट करता है 0। यदि हम इसके बजाय ईओएफ को हिट करते हैं, तो ऊर्जा को सेट किया जाएगा 1

परमाणु जारी रहता है और फिर हिट होता है %। यह मिरर स्विच है। गैर-सकारात्मक ऊर्जा के लिए, यह /दर्पण की तरह काम करता है । लेकिन सकारात्मक ऊर्जा के लिए यह एक काम करता है \(और 1 से ऊर्जा भी घटाता है)। इसलिए जब हम पात्रों को पढ़ रहे होते हैं, तो परमाणु ऊपर की ओर परावर्तित होगा और हम चरित्र को संसाधित कर सकते हैं। लेकिन जब हम इनपुट के साथ काम करते हैं, तो परमाणु नीचे की ओर परिलक्षित होगा और हम परिणाम को पुनः प्राप्त करने के लिए विभिन्न तर्क लागू कर सकते हैं। FYI करें, विपरीत घटक है &

इसलिए हमें अभी के लिए एक परमाणु मिला है। हम प्रत्येक वर्ण के लिए क्या करना चाहते हैं, उसका अंक मान पढ़ना है, उसे हमारे कुल में जोड़ना है और फिर अगले अंक की तैयारी के लिए कुल 10 से भागना है।

चरित्र परमाणु पहले एक डिफ़ॉल्ट (डिफ़ॉल्ट) फ्यूजन रिएक्टर को हिट करता है Y। यह परमाणु को विभाजित करता है और हम इनपुट घटक में वापस लूप में नियंत्रण परमाणु के रूप में बाईं ओर जाने वाली प्रतिलिपि का उपयोग करते हैं और अगले वर्ण को पढ़ते हैं। राइट-गोइंग कॉपी पर कार्रवाई की जाएगी। उस मामले पर विचार करें जहां हमने चरित्र पढ़ा है 3। हमारा परमाणु होगा (51,0)। हम द्रव्यमान और ऊर्जा को स्वैप करते हैं @, जैसे कि हम अगले विखंडन रिएक्टर के घटाव का उपयोग कर सकते हैं। रिएक्टर 48ऊर्जा (द्रव्यमान को बदले बिना) को घटाता है, इसलिए यह दो प्रतियों को भेजता है (0,3)- ऊर्जा अब हमारे द्वारा पढ़े गए अंक से मेल खाती है। ऊपर जाने वाली प्रतिलिपि के साथ बस छोड़ दिया जाता है ;(एक घटक जो बस आने वाले सभी परमाणुओं को नष्ट कर देता है)। हम नीचे की प्रतिलिपि के साथ काम करते रहेंगे। आपको इसके रास्ते का अनुसरण करना होगा/और \थोड़ा सा दर्पण।

@बस से पहले संलयन रिएक्टर फिर से बड़े पैमाने पर और ऊर्जा अदला-बदली, ऐसा है कि हम जोड़ देंगे (3,0)में हमारे कुल चल रहा है Y। ध्यान दें कि चल रहे कुल में हमेशा 0ऊर्जा होगी।

अब Jएक छलांग है। यह क्या करता है किसी भी आने वाली परमाणु को अपनी ऊर्जा से आगे कूदना है। यदि यह है 0, तो परमाणु बस सीधा चलता रहता है। यदि यह है तो यह 1एक सेल को छोड़ देगा, अगर यह 2दो सेल को छोड़ देगा और इसी तरह। ऊर्जा छलांग में खर्च होती है, इसलिए परमाणु हमेशा ऊर्जा के साथ समाप्त होता है 0। चूंकि रनिंग टोटल में शून्य ऊर्जा होती है, इसलिए अभी के लिए जंप को अनदेखा किया जाता है और परमाणु को फ्यूजन रिएक्टर में पुनर्निर्देशित किया जाता है {जो इसके द्रव्यमान को गुणा करता है 10। डाउनिंग कॉपी को छोड़ दिया जाता है, ;जबकि ऊपर जाने वाली कॉपी को Yनए चलन के रूप में रिएक्टर में वापस भेज दिया जाता है।

जब तक हम ईओएफ को हिट नहीं करते, तब तक उपरोक्त दोहराता रहता है (एक मजाकिया रूप से पाइपलाइज्ड तरीके से जहां नए अंकों को पिछले वाले से पहले संसाधित किया जाता है)। अब %परमाणु को नीचे की ओर भेजेंगे। (0,1)चल रहे कुल रिएक्टर को मारने से पहले इस परमाणु को अब चालू करने का विचार है ताकि (क) कुल प्रभावित न हो (शून्य द्रव्यमान) और बी) हमें 1ऊपर कूदने की ऊर्जा मिलती है [। हम आसानी से ऊर्जा का ध्यान रख सकते हैं $, जिससे ऊर्जा बढ़ती है।

मुद्दा यह है कि ?जब आप ईओएफ को मार रहे हैं तो द्रव्यमान को रीसेट नहीं किया जाता है, इसलिए द्रव्यमान अभी भी पिछले चरित्र को पढ़ा जाएगा, और ऊर्जा होगी 0(क्योंकि वापस %डिक्रिप्टेड 1है 0)। इसलिए हम उस द्रव्यमान से छुटकारा पाना चाहते हैं। ऐसा करने के लिए हम द्रव्यमान और ऊर्जा को @फिर से स्वैप करते हैं।

मुझे इस अनुभाग को पूरा करने से पहले एक और घटक को पेश करने की आवश्यकता है Z:। यह अनिवार्य रूप से %या के समान है &। अंतर यह है कि यह सकारात्मक-ऊर्जा परमाणुओं को सीधे (ऊर्जा में कमी करते हुए) गुजरता है और गैर-सकारात्मक-ऊर्जा परमाणुओं को 90 डिग्री से बाईं ओर विक्षेपित करता है। हम एक परमाणु की ऊर्जा को खत्म करने के लिए इसे Zओवर-ओवर के माध्यम से लूप करके उपयोग कर सकते हैं - जैसे ही ऊर्जा चली जाती है, परमाणु विक्षेपित हो जाएगा और लूप छोड़ देगा। यह पैटर्न है:

/ \
[Z/

एक बार ऊर्जा शून्य होने पर परमाणु ऊपर की ओर बढ़ेगा। मैं इस पैटर्न का उपयोग कार्यक्रम के अन्य भागों में एक रूप या किसी अन्य रूप में कई बार करूंगा।

तो जब परमाणु इस छोटे से पाश छोड़ देता है, यह हो जाएगा (1,0)और को लगा दिया (0,1)द्वारा @इनपुट के अंतिम परिणाम जारी करने के लिए संलयन रिएक्टर से टकराने से पहले। हालाँकि, रनिंग टोटल 10 के एक कारक द्वारा बंद हो जाएगा, क्योंकि हमने इसे पहले ही एक और अंक के लिए अस्थायी रूप से गुणा कर दिया है।

तो अब ऊर्जा के साथ 1, यह परमाणु छोड़ देगा [और अंदर कूद जाएगा /। यह इसे एक विखंडन रिएक्टर में बदल देता है जिसे हमने 10 से विभाजित करने और हमारे बाहरी गुणन को ठीक करने के लिए तैयार किया है। फिर से, हम एक आधे को छोड़ देते हैं ;और दूसरे को आउटपुट के रूप में रखते हैं (यहाँ प्रस्तुत किया गया है Oजिसके साथ बस संबंधित वर्ण को प्रिंट करेंगे और परमाणु को नष्ट कर देंगे - पूर्ण कार्यक्रम में हम इसके बजाय परमाणु का उपयोग करते रहते हैं)।

itoa

           /     \
input ->  [{/\  ;@
          @\ <\   
          $  ;}++ +++++++L
          %@A{/
          M  \@+>/
          ~     @
          SNR'0YK
            \  A!/

बेशक, हमें परिणाम को वापस स्ट्रिंग में बदलने और इसे प्रिंट करने की भी आवश्यकता है। यही हिस्सा है। यह मानता है कि इनपुट 10 या तो टिक करने से पहले नहीं आता है, लेकिन पूर्ण कार्यक्रम में आसानी से दिया जाता है। यह बिट पूर्ण प्रोग्राम के निचले भाग में पाया जा सकता है।

यह कोड एक नया बहुत शक्तिशाली विखंडन घटक पेश करता है: स्टैक K। स्टैक शुरू में खाली है। जब गैर-नकारात्मक ऊर्जा वाला एक परमाणु स्टैक को हिट करता है, तो परमाणु को केवल स्टैक पर धकेल दिया जाता है। जब नकारात्मक ऊर्जा वाला एक परमाणु ढेर से टकराता है, तो उसके द्रव्यमान और ऊर्जा को ढेर के शीर्ष पर परमाणु द्वारा प्रतिस्थापित किया जाएगा (जो कि पॉप हो जाता है)। यदि स्टैक खाली है, हालांकि, परमाणु की दिशा उलट है और इसकी ऊर्जा सकारात्मक हो जाती है (यानी गुणा से गुणा किया जाता है -1)।

ठीक है, वास्तविक कोड पर वापस जाएं। itoaस्निपेट का विचार बार-बार इनपुट मॉडुलो 10 को लेना है ताकि अगले पुनरावृत्ति के लिए इनपुट को 10 से विभाजित करते हुए अगले अंक का पता लगाया जा सके। इससे सभी अंक उल्टे क्रम में (कम से कम महत्वपूर्ण से सबसे महत्वपूर्ण) निकलेंगे। आदेश को ठीक करने के लिए हम एक स्टैक पर सभी अंकों को धक्का देते हैं और अंत में उन्हें एक-एक करके प्रिंट करने के लिए पॉप करते हैं।

कोड का ऊपरी आधा अंक गणना करता है: Lप्लसस के साथ एक 10 देता है जिसे हम क्लोन करते हैं और एक विखंडन और एक फ्यूजन रिएक्टर में फ़ीड करते हैं ताकि हम 10. से विभाजित और गुणा कर सकें। लूप अनिवार्य रूप [से शीर्ष कोने में शुरू होता है । वर्तमान मूल्य विभाजित है: एक प्रति को 10 से विभाजित किया जाता है, फिर 10 से गुणा किया जाता है और एक विखंडन रिएक्टर में संग्रहीत किया जाता है, जो तब शीर्ष पर दूसरी प्रति से मारा जाता है। यह गणना i % 10करता है i - ((i/10) * 10)। ध्यान दें कि Aविभाजन के बाद और गुणा से पहले मध्यवर्ती परिणाम को विभाजित करता है, जैसे कि हम i / 10अगले पुनरावृत्ति में फ़ीड कर सकते हैं ।

%पाश aborts एक बार यात्रा चर 0. हिट के बाद से इस और अधिक या कम एक do-जबकि पाश है, इस कोड को भी मुद्रण के लिए काम करेगा 0(अग्रणी शून्य अन्यथा बनाने के बिना)। एक बार जब हम लूप छोड़ देते हैं तो हम स्टैक को खाली करना चाहते हैं और अंकों को प्रिंट करते हैं। Sके विपरीत है Z, इसलिए यह एक स्विच है जो आने वाली परमाणु को गैर-सकारात्मक ऊर्जा के साथ 90 डिग्री दाईं ओर विक्षेपित करेगा। इसलिए परमाणु वास्तव में एक अंक को पॉप Sकरने के Kलिए सीधे से किनारे पर चला जाता है (ध्यान दें ~कि यह सुनिश्चित करता है कि आने वाले परमाणु में ऊर्जा है -1)। 48संबंधित अंकों के ASCII कोड को प्राप्त करने के लिए उस अंक को बढ़ाया जाता है। Aविभाजन अंक के साथ एक प्रति प्रिंट!और Yअगले अंक के लिए रिएक्टर में वापस दूसरी प्रति फ़ीड करें । जो कॉपी छपी है उसका उपयोग स्टैक के लिए अगले ट्रिगर के रूप में किया जाता है (ध्यान दें कि दर्पण इसे Mबाईं ओर से हिट करने के लिए किनारे के आसपास भी भेजते हैं )।

जब स्टैक खाली होता है, तो Kपरमाणु को प्रतिबिंबित करेगा और अपनी ऊर्जा को +1इस तरह से मोड़ देगा , जैसे कि यह सीधे से गुजरता है SNएक नई रेखा प्रिंट करता है (सिर्फ इसलिए कि यह साफ है :))। और फिर परमाणु थिरुघ में R'0फिर से समाप्त हो जाता है Y। चूंकि आस-पास कोई और परमाणु नहीं हैं, इसलिए इसे कभी जारी नहीं किया जाएगा और कार्यक्रम समाप्त हो जाएगा।

विखंडन संख्या की गणना: रूपरेखा

आइए कार्यक्रम के वास्तविक मांस पर जाएं। कोड मूल रूप से मेरे गणितज्ञ संदर्भ कार्यान्वयन का एक बंदरगाह है:

fission[n_] := If[
  (div = 
    SelectFirst[
      Reverse@Divisors[2 n], 
      (OddQ@# == IntegerQ[n/#] 
       && n/# > (# - 1)/2) &
    ]
  ) == 1,
  1,
  1 + Total[fission /@ (Range@div + n/div - (div + 1)/2)]
]

divअधिकतम विभाजन में पूर्णांकों की संख्या कहां है।

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

यहाँ इस अवधारणा के लिए एक रूपरेखा है:

                      +--- input goes in here
                      v 

                     SQS ---> compute div from n          D /8/
                     ~4X               |                /~KSA /
                       3               +----------->    { +X
initial trigger ---> W                               6~@/ \/
                              4                   
                     W        ^                     /
                              |              3
                     ^     generate range    |
                     |     from n and div  <-+----- S6
                     |         -then-      
                     +---- release new trigger

सबसे महत्वपूर्ण नए घटक अंक हैं। ये टेलीपोर्टर्स हैं। एक ही अंक वाले सभी टेलीपोर्टर्स एक साथ होते हैं। जब कोई परमाणु किसी भी ट्रांसपोर्टर को मारता है तो वह तुरंत उसी समूह में अगले दूरसंचार को स्थानांतरित कर देगा, जहां अगला सामान्य बाएं से दाएं, ऊपर से नीचे के क्रम में निर्धारित होता है। ये आवश्यक नहीं हैं, लेकिन लेआउटिंग (और इसलिए थोड़ा सा गोल्फिंग) के साथ मदद करते हैं। वहाँ भी है Xजो बस एक परमाणु को डुप्लिकेट करता है, एक प्रति को सीधे आगे भेजता है और दूसरे को पीछे की ओर।

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

एक बार जब कतार खाली हो जाती है, तो ट्रिगर को प्रतिबिंबित किया जाएगा, सीधे Sदाएं कोने से गुजर रहा है और शीर्ष दाएं कोने में फिर से दिखाई देगा , जहां से वह काउंटर (अंतिम परिणाम) जारी करता है A, जिसे बाद में टेलीपोर्ट किया itoaजाता है 8

कम्प्यूटिंग संख्या: लूप बॉडी

तो जो कुछ बचा है वह दो वर्गों की गणना divऔर उत्पन्न करने के लिए है। कम्प्यूटिंग divयह हिस्सा है:

 ;    
 {+L  /$     \/\/\/\/\/   5/ @  [~ &@[S\/ \
/A@[  %5                   /; &    K  } [S/
   \  A$@S  S\/  \/\/\/   \/>\ /S]@A  /  \ 
         X  X    /> \      +\ A\ /   \ /
    /   ~A\;     +;\      /@
ZX [K    / {/  / @  @ }  \ X @
   \AS   </      \V /    }SZS S/
     X   ;;@\   /;X  /> \ ; X X
     \@+  >/ }$S SZS\+;    //\V
       / \\  /\; X X @  @  \~K{
       \0X /     /~/V\V /   0W//
\        Z      [K \  //\
           \ /\7\A  /;7/\/

आपने शायद अब बहुत धैर्य के साथ अपने लिए यह पहेली निकालने के लिए पर्याप्त देखा है। उच्च-स्तरीय ब्रेकडाउन यह है: पहले 12 कॉलम या तो डिवाइडर की एक धारा उत्पन्न करते हैं 2n। अगले 10 कॉलम उन लोगों को फ़िल्टर करते हैं जो संतुष्ट नहीं करते हैं OddQ@# == IntegerQ[n/#]। अगले 8 कॉलम उन लोगों को फ़िल्टर करते हैं जो संतुष्ट नहीं करते हैं n/# > (# - 1)/2)। अंत में हम एक स्टैक पर सभी वैध भाजक को धकेल देते हैं, और एक बार जब हम पूरा कर लेते हैं, तो हम पूरे स्टैक को एक फ्यूजन रिएक्टर में खाली कर देते हैं (सभी / अंतिम / सबसे बड़े भाजक को लिखकर) और फिर परिणाम जारी करते हैं, इसके बाद इसकी ऊर्जा को समाप्त कर देते हैं (जो कि गैर थी) -किसान असमानता की जाँच से)।

वहाँ बहुत सारे पागल रास्ते हैं जो वास्तव में कुछ भी नहीं करते हैं। मुख्य रूप से, \/\/\/\/शीर्ष पर पागलपन ( 5एस भी इसका हिस्सा हैं) और नीचे के चारों ओर एक पथ (जो 7एस के माध्यम से जाता है )। कुछ नस्लीय दौड़ की स्थिति से निपटने के लिए मुझे इन्हें जोड़ना पड़ा। विखंडन एक देरी घटक का उपयोग कर सकता है ...

कोड है कि नई सीमा से उत्पन्न करता है nऔर divयह है:

 /MJ $$\
4}K~@\ &]    @\  3/\
\{   }$A/1 2  }Y~K <\
 \@  /   \@<+@^   1;}++@
  2        ;   \    /

हम पहले गणना करते हैं n/div - (div + 1)/2(दोनों शब्द फ़्लॉइड करते हैं, जो समान परिणाम देता है) और बाद के लिए स्टोर करते हैं। फिर हम divनीचे से एक सीमा उत्पन्न 1करते हैं और उनमें से प्रत्येक में संग्रहीत मूल्य जोड़ते हैं।

इन दोनों में दो नए सामान्य पैटर्न हैं, जिनका मुझे उल्लेख करना चाहिए: एक नीचे या (घुमाए गए संस्करणों) से है SXया ZXहिट है। यह एक परमाणु को डुप्लिकेट करने का एक अच्छा तरीका है यदि आप चाहते हैं कि एक प्रतिलिपि सीधे आगे बढ़े (क्योंकि एक फ्यूजन रिएक्टर के आउटपुट को पुनर्निर्देशित करना कभी-कभी बोझिल हो सकता है)। Sया Zमें परमाणु घूमता है Xऔर फिर मिरर प्रति प्रसार की मूल दिशा में वापस घूमता है।

अन्य पैटर्न है

[K
\A --> output

यदि हम किसी भी मूल्य को संचित करते हैं तो हम Kबार-बार इसे Kऊपर से नकारात्मक ऊर्जा के साथ मारकर पुनः प्राप्त कर सकते हैं । जिस Aमान में हम रुचि रखते हैं उसे डुप्लिकेट करता है और अगली बार जब हमें इसकी आवश्यकता होती है, तो स्टैक पर सही प्रतिलिपि बनाता है।

ठीक है, यह काफी ठुमका था ... लेकिन अगर आप वास्तव में इसके माध्यम से आए हैं, तो मुझे आशा है कि आपको यह विचार है कि विखंडन i͢s̟ ̮̩i̢̘̗̗nç̮̩r̸̭̬̱͔e̟̹̟̜͟d̙i̠͙͎̖͓̯b̘̠͎̭̰̼l̶̪̙̮̥̮y̠̠͎̺͜ ͚̬̮f̟͞u an͍ ̜̠̙t̸̳̩̝o ̫͉̙͠p̯̱̭͙̜͙͞ŕ̮͓̜o̢̙̣̭g̩̼̣̝r̤͍͔̘̟ͅa̪̜͇m̳̭͔̤̞ͅ ai͜n̳̯̗̳͇̹.


1
Now with 100% fewer scrollbars.तो आप कहते हैं .. और इसके अभी भी जारी रखने के लिए ...
ऑप्टिमाइज़र

13
अभी भी सबसे अधिक कोड से अधिक पठनीय हमारे कनिष्ठ देवता बाहर पंप करते हैं।
corsiKa

विखंडन के निर्माता के रूप में, यहां तक ​​कि मैंने अभी तक एक कार्यक्रम नहीं लिखा है कि बड़े! मैं प्रसन्न हूँ! आपकी व्याख्या शानदार है और निश्चित रूप से भाषा के लिए एक ट्यूटोरियल के रूप में काम कर सकती है।
C0deH4cker

इसके अलावा, आपके उत्तर थोड़े की अंतिम पंक्ति एक विखंडन कार्यक्रम की तरह दिखती है;)
C0deH4cker

12

CJam, 42 41 बाइट्स

ri]{_{:X,:)_few:+W%{1bX=}=}%{,(},e_}h]e_,

एक साधारण चौड़ाई पहले ट्रैवर्सल और खाली अगले स्तर की एक रोक स्थिति।

यह कैसे काम करता है :

ri]                                       e# This represents the root of the fissile tree
   {                               }h     e# Now we run a do-while loop
    _{                    }%              e# Copy the nodes at the current level and map them
                                          e# via this code block to get next level nodes
      :X,:)                               e# Store the node value in X and get array [1..X]
           _few                           e# Copy the array and get continuous slices of
                                          e# length 1 through X from the array [1..X]
               :+W%                       e# Right now, we have an array of array with each
                                          e# array containing slice of same length. We join
                                          e# those arrays and reverse them to get slices of
                                          e# higher length in front of lower lengths
                   {1bX=}=                e# Choose the first slice whose sum is same as X
                                          e# The reversal above makes sure that we give
                                          e# preference to slice of higher length in case of
                                          e# multiple slices add up to X
                            {,(},         e# Filter out slices of length 1 which basically
                                          e# mean that the current node cannot be split up
                                 e_       e# Join all slices in a single array. This is our
                                          e# next level in the Fissile tree. If this is empty
                                          e# it means that all no further node can be
                                          e# decomposed. In an {}h do-while loop, this fact
                                          e# itself becomes the stopping condition for the
                                          e# loop
                                     ]e_, e# Wrap all levels in an array. Flatten the array
                                          e# and take its length

इसे यहाँ ऑनलाइन आज़माएँ


यह संभवतः लगभग 35 बाइट्स के लिए गोल्फ हो सकता है। मैं यह पता लगाने की कोशिश कर रहा हूं कि कैसे ..
ऑप्टिमाइज़र

10

पायथन 3, 112 बाइट्स

def f(n,c=0):
 d=n-c;s=(n-d*~-d/2)/d
 return(s%1or s<1)and f(n,c+1)or+(d<2)or-~sum(f(int(s)+i)for i in range(d))

4 बाइट ने @FryAmTheEggman को धन्यवाद दिया।

स्पष्टीकरण बाद में आ रहा है ...

बोनस तथ्य: 2 की प्रत्येक शक्ति का विखंडन संख्या 1 है। इसका कारण यह है कि एक समान लंबाई अनुक्रम का योग हमेशा दो मध्य संख्याओं का योग होता है, जो अनुक्रम की आधी लंबाई से विषम, गुणा, जो पूर्णांक है । विषम लंबाई अनुक्रम का योग मध्य लंबाई अनुक्रम लंबाई से गुणा है, जो विषम है। इसलिए क्योंकि 2 की शक्ति में एक अजीब विभाजक नहीं होता है, इसे केवल स्वयं के योग के रूप में व्यक्त किया जा सकता है।


2 + 3 + 4 + 5 = 14 जो विषम नहीं है। यहां तक ​​कि लंबाई के अनुक्रमों के लिए आपके तर्क को "एक समान लंबाई अनुक्रम का योग दो मध्य संख्याओं का योग है, जो विषम है, जो लंबाई में आधी गुणा गुणा है" को बदलना चाहिए। आपका शेष कथन अप्रभावित होकर जाता है।
ब्रूनो ले फ्लोच

@BrunoLeFloch धन्यवाद! सही किया।
यादृच्छिक

क्या आपके शीर्षक में सुधार नहीं होना चाहिए? यानी <स्ट्राइक> 117 </ स्ट्राइक> <स्ट्राइक> 113 </ स्ट्राइक> 112
corsiKa

@ कोर्सीका मैं आमतौर पर केवल प्रमुख सुधारों के लिए करता हूं। अन्यथा बहुत सारी धारीदार संख्याएँ होंगी।
यादृच्छिक

8

पायथन 2, 111 102 97 बाइट्स

कुछ पठनीय:

def f(n,c=0):a=n-c;b=n-a*~-a/2;return 1/a or-~sum(map(f,range(b/a,b/a+a)))if b>b%a<1else f(n,c+1)

नहीं-तो पठनीय:

def f(n,a=0):b=n-a*~-a/2;return b>0and(f(n,a+1)or b%a<1and(1/a or-~sum(map(f,range(b/a,b/a+a)))))

दोनों 97 बाइट्स।

bहै nशून्य से (a-1)thत्रिकोणीय संख्या। यदि b % a == 0, तो लगातार संख्याओं nका योग aहै b


8
जब तक मैं PPCG में शामिल नहीं हुआ, तब तक मैं आमतौर पर पठनीय भाषा पर विचार करता था।
एलेक्स ए।

मुझे लगता है कि आपको अपनी पठनीय परिभाषा को सुधारने की आवश्यकता है ..: पी
ऑप्टिमाइज़र

अजगर 2 अनुमति नहीं देता है 1else। केवल दूसरा समाधान काम करता है। यह पायथन 3 तक नहीं है जो elseतुरंत एक नंबर का पालन कर सकता है।
mbomb007

@ mbomb007 मेरी जानकारी के अनुसार यह 2.7.8 पर ठीक से काम करता है
Sp3000

ठीक है, मैं 2.7.2 का उपयोग कर रहा था।
mbomb007

7

अजगर 2, 86

f=lambda n,R={1}:n-sum(R)and f(n,R^{[min(R),max(R)+1][n>sum(R)]})or-~sum(map(f,R-{n}))

कम गोल्फ वाला:

def f(n,R={1}):
    d=sum(R)-n
    if d==0:return (sum(map(f,R-{n}))
    if d<0:return f(n,R|{max(R)+1})
    if d>0:return f(n,R-{min(R)})

विचार यह है कि लगातार पूर्णांकों के संभावित रनों का परीक्षण करें जो कि योग हैं n। रन को सीधे Rउसके समापन बिंदुओं के बजाय सीधे सेट के रूप में संग्रहीत किया जाता है ।

हम यह जांचते हैं कि वर्तमान रन की राशि nउनके अंतर के माध्यम से वांछित राशि की तुलना कैसे करती है ।

  • यदि योग बहुत बड़ा है, तो हम रन में सबसे छोटे तत्व को काटते हैं।
  • यदि योग बहुत छोटा है, तो हम रन को 1 से बड़ा करके उसका विस्तार करते हैं।
  • यदि योग सही है, तो हम fवर्तमान नोड के लिए रन, योग, मैपिंग और 1 को जोड़कर पुनरावृत्ति करते हैं। यदि रन है {n}, तो हमने सभी गैर-तुच्छ संभावित रकम की कोशिश की है , nपहले हटाकर पुनरावृत्ति को रोकें ।

3 वर्णों को बचाने के लिए Sp3000 का धन्यवाद।


7

अजगर 2, 85

मुझे इस उत्तर पर बहुत गर्व है क्योंकि यह पहले से ही n = 9 के लिए दस सेकंड और n = 10 के लिए 5-10 मिनट लेता है। कोड गोल्फ में यह एक कार्यक्रम का एक वांछनीय विशेषता माना जाता है।

f=lambda n,a=1,d=1:a/n or[f(a)+f(n-a,1+1%d*a)+1/d,f(n,a+d/n,d%n+1)][2*n!=-~d*(2*a+d)]

एक छोटा-परिक्रमा संस्करण भी है जो इतने लंबे समय तक नहीं लेता है और बाइट्स की समान मात्रा का उपयोग करता है:

f=lambda n,a=1,d=1:a/n or~d*(2*a+d)+n*2and f(n,a+d/n,d%n+1)or f(a)+f(n-a,1+1%d*a)+1/d 

यह तेज़ हो सकता है, लेकिन कम से कम यह डिफ़ॉल्ट पुनरावर्तन सीमा से अधिक हो जाता है, जब एन 40 से थोड़ा ऊपर जाता है।

विचार यह है कि संख्या aऔर dइस तरह के लिए a + a+1 + ... + a+d == n, 1 और के बीच के मूल्यों पर एक ब्रूट फोर्स सर्च करें nf(n,a+d/n,d%n+1)रिकर्सियन की शाखा (a, d)जोड़े के माध्यम से छोरों । इस मामले में कि समानता संतुष्ट है, मैं map(range(...))केवल दो शाखाओं में विभाजित करके एक महंगी कॉल से बचने का प्रबंधन करता हूं, भले ही अनुक्रम कितना लंबा हो। के a+1माध्यम से संख्याओं को पैरामीटर सेट करके dएक कॉल में lumped किया जाता है ताकि अनुक्रम को विभाजित करने का एक अलग तरीका उपयोग नहीं किया जा सके।fa


यह कैसे काम करता है?
xnor

"मुझे इस जवाब पर बहुत गर्व है क्योंकि यह पहले से ही n = 9 के लिए दसियों सेकंड लेता है, और n = 10 के लिए 5-10 मिनट। कोड गोल्फ में यह एक कार्यक्रम का वांछनीय विशेषता माना जाता है।" + 1 उसके लिए बस।
सोहम चौधरी

6

हास्केल, 76 69 बाइट्स

f x=head$[1+sum(map f[y..z])|y<-[1..x-1],z<-[y..x],sum[y..z]==x]++[1]

उपयोग:

*Main> map f [1..40]
[1,1,3,1,5,6,5,1,6,7,12,10,12,11,12,1,8,16,14,17,18,18,23,13,21,18,22,23,24,19,14,1,22,20,23,24,31,27,25,26]

यह काम किस प्रकार करता है:

[  [y..z] |y<-[1..x-1],z<-[y..x],sum[y..z]==x]

           make a list of lists with all consecutive integers (at least 2 elements)
           that sum up to x, sorted by lowest number, e.g. 9 -> [[2,3,4],[4,5]].

1+sum(map f[...]) 

           recursively calculate the Fission Number for each list

[...]++[1]

           always append the 1 to the list of Fission Numbers.

head

           take the first element, which is either the Fission Number of the
           longest list or if there's no list, the 1 appended in the step before.  

3

रेटिना , 66 बाइट्स

^|$
,
(`,(1+?)(?=(?<1>1\1)+\D)
$0;
+)`,(1*);1\1
,$1,1$1;
^,|1

.
1

इनपुट लेता है और आउटपुट को प्रिंट करता है।

आप प्रत्येक लाइन को एक फ़ाइल में रख सकते हैं या कोड को चला सकते हैं जैसा कि -sध्वज के साथ है । उदाहरण के लिए:

> echo -n 1111111|retina -s fission
11111

स्पष्टीकरण:

  • हम संख्याओं का अल्पविराम-सीमांकित सूची रखते हैं।
  • हर संख्या के लिए हम सबसे छोटा आरंभिक मूल्य लेते हैं जो एक वैध विभाजन को कम कर सकता है और इसे अर्धविराम के साथ बाकी हिस्सों से हटा सकता है।
  • यदि किसी संख्या के अंदर अर्धविराम होता है तो हम इसे अल्पविराम में बदल देते हैं और संख्या के अगले ठीक आकार (पिछले तत्व + 1 की लंबाई) का परिसीमन करते हैं।
  • हम चरण 2 और 3 को तब तक दोहराते हैं जब तक कि परिवर्तन न हो जाए।
  • हमें प्रत्येक पत्ती के लिए एक अल्पविराम और प्रत्येक आंतरिक नोड के लिए एक अर्धविराम के साथ एक अतिरिक्त अल्पविराम मिलता है क्योंकि हमने दो अल्पविराम के साथ शुरू किया था। इसलिए हम एक अल्पविराम और संख्याओं के हिस्सों ( 1's) को हटाते हैं और बाकी हिस्सों को परिवर्तित करते हैं 1

इनपुट के साथ पूरी प्रक्रिया में स्ट्रिंग की स्थिति 11111111111111 (unary 14):

,11111111111111,
,11;111111111111,
,11,1;11,1111,11;111;,
,11,1,11;,1111,11,1;11;;,
,11,1,11;,1111,11,1,11;;;,
,,;,,,,;;;,
11111111111

चैट में मदद के लिए @MartinButtner के लिए बहुत धन्यवाद!


3

CJam (43 बाइट्स)

qi,{):X),_m*{{_)*2/}/-X=}=~\,>0\{~$+}/)}%W=

ऑनलाइन डेमो

मुझे यकीन है कि मैं उन्नत छोरों के साथ कुछ चालें याद कर रहा हूं, लेकिन यह सीजेएम संपत्ति (जो मुझे पहले से परेशान कर रहा है) का बड़े करीने से शोषण करता है कि एक %नक्शे के अंदर परिणाम स्टैक पर रहते हैं, और इसलिए इसे $ए के साथ उपयोग करके एक्सेस किया जा सकता है नकारात्मक ऑफसेट।


मैं कल करीब देखूंगा, लेकिन शुरुआत के लिए आपको ,शुरुआत में जरूरत नहीं है । /और %कुछ अन्य लोग स्पष्ट रूप से संख्याओं को श्रेणियों में बदलते हैं।
मार्टिन एंडर

,_m*से बदला जा सकता है 2m*। अंकगणितीय प्रगति सूत्र को प्रतिस्थापित किया जा सकता है ~,>:Y_,+:+और ~\,>0\ बन जाता है !Y। अंत में, यदि आप {}#इसके बजाय उपयोग करते हैं, तो आपको इसके बाद की {}=आवश्यकता नहीं है । यह सब एक साथ )Xri{):X2m*{~,>:Y_,+:+X=}#!Y{~$+}/)}%W=
डेनिस

2

जाओ, १३३ बाइट्स

func 算(n int)int{Σ:=1;for i:=0;i<n;i++{for j:=0;j<n;j++{if i*i+i-j*j-j==2*n{for k:=j+1;k<=i;k++{Σ+=算(k)};j,i=n,n}}};return Σ}

यह मेरा पहला कोड गोल्फ है, क्षमा करें यदि मैंने कोई गलती की है।

यह इस विचार का उपयोग करता है कि उच्छृंखल "रचना" को ऑर्डर किए गए पूर्णांकों के दो अनुक्रमों के बीच अंतर के रूप में भी देखा जा सकता है। उदाहरण के लिए संख्या 13 के लिए फिशाइल "रचना" लें। यह 6,7 है। लेकिन इसे पूर्णांक 1 ... 7 के पूर्णांक 1 ... 5 के योग के रूप में देखा जा सकता है

  A: 1 2 3 4 5 6 7  sum = 28
  B: 1 2 3 4 5      sum = 15 
A-B:           6 7  sum = 13, which is also 28-15 = 13

गॉस के स्कूल के दिनों, 1 ... n = (n ^ 2 + n) / 2 से सूत्र को याद करें। इसलिए किसी दिए गए n के लिए अनुक्रमिक पूर्णांकों की एक रचना खोजने के लिए, हम यह भी कह सकते हैं, हम '1 अंक' p और q को सीमा 1 के साथ खोज रहे हैं ... n ताकि (p ^ 2 + p) / 2 - ( q ^ 2 + q) / 2 = n। उपर्युक्त उदाहरण में, हम '5 और 7' को खोज रहे होंगे क्योंकि 7 ^ 2 + 7 = 56/2, 5 ^ 2 + 5 = 30/2, 56 / 2-30 / 2 = 28-15 = 13।

अब एक संख्या को फिजाइल-कंपोज़ करने के कई संभावित तरीके हैं, जैसे मार्टिन ने 9 = 2 + 3 + 4 लेकिन 4 + 5. भी नोट किया, लेकिन यह स्पष्ट प्रतीत होता है कि "सबसे कम" शुरुआती क्रम भी सबसे लंबा होगा, क्योंकि इसमें अधिक लगता है मध्यम संख्या के आकार की तुलना में बड़ी संख्या में योग करने के लिए छोटी संख्या। (मेरे पास दुर्भाग्य से कोई सबूत नहीं है)

तो 9 की संरचना को खोजने के लिए, प्रत्येक 'अंतिम बिंदु जोड़ी', p और q का परीक्षण करें, दोनों p और q को 0 से 9 तक अलग-अलग जाँचें, और p ^ p + 2 / q - 2 + q / 2 = का परीक्षण करें। 9. या, अधिक बस, समीकरण को 2 से गुणा करें, गोलाई के विभाजन के मुद्दों से बचने और पूर्णांक में सभी गणित रखने के लिए। फिर हम p और q की तलाश कर रहे हैं जैसे (p ^ p + p) - (q ^ q + q) = 9 * 2। पहला मैच जो हमें मिलेगा, वह है फिशाइल कम्पोज़िशन एंडपॉइंट्स, क्योंकि जैसा कि नोट किया गया है, सबसे कम संख्या वाला समूह भी सबसे लंबा होगा, और हम निम्न-से-उच्च (0 से 9) खोज रहे हैं। जैसे ही हमें कोई मैच मिलता है हम लूप से बाहर हो जाते हैं।

अब पुनरावर्ती फ़ंक्शन दिए गए n के लिए उन 'फ़िसाइल अंत बिंदुओं' p और q को ढूँढता है, फिर P से q के वृक्ष में प्रत्येक 'बच्चों' के लिए स्वयं को याद करता है। 9 के लिए, यह 1 और 4, (20-2 = 18) पाएगा, फिर यह 2, 3 और 4 को फिर से कॉल करेगा, परिणामों को जोड़ देगा। 4 जैसी संख्याओं के लिए यह बस एक मैच नहीं पाता है, और इसलिए '1' देता है। यह संक्षिप्त हो सकता है लेकिन यह मेरे तीसरे कार्यक्रम की तरह है, और मैं कोई पुनरावृत्ति विशेषज्ञ नहीं हूं।

पढ़ने के लिए धन्यवाद।


अच्छा काम! लेकिन यूनिकोड फ़ंक्शन / चर नाम क्यों। यह अनावश्यक बाइट खर्च करता है और निश्चित रूप से आप बस कुछ सामान्य पत्र का उपयोग कर सकते हैं?
मार्टिन एंडर

आपकी उदार टिप्पणी के लिए धन्यवाद। लेकिन मैंने खुद से पूछा, बाइट्स के बजाय पात्रों को क्यों नहीं गिना जाता है :)
उज्ज्वल उज्ज्वल

क्योंकि वे डिफ़ॉल्ट नियम हैं। :) कारण हम आमतौर पर बाइट्स की गिनती करते हैं और वर्णों के नहीं, क्योंकि अन्यथा ऐसा होता है , जो इसमें शामिल सभी दलों के लिए बहुत कम मजेदार है। ;) (जिसके अनुसार, किसी भी चुनौती का लेखक है बाइट्स की बजाय पात्रों द्वारा गिनती निर्दिष्ट करने के लिए नि: शुल्क है, लेकिन मैं विशेष रूप से नहीं किया था)।
मार्टिन Ender

1

CJam, 40 35 33 बाइट्स

ri{__,f-_few:+{1b1$=}=|{F}*}:F~],

सुझाव देने के लिए @Optimizer का धन्यवाद few, जिसने 2 बाइट्स बचाए।

CJam दुभाषिया में इसे ऑनलाइन आज़माएं ।

यह काम किस प्रकार करता है

ri      e# Read an integer from STDIN.
{       e# Define function F(X):
  _     e# Push X.
  _,    e# Push [0 ... X-1].
  f-    e# Subract each from X. Pushes Y := [X ... 1].
  _few  e# Push all overlapping slices of Y of length in Y.
  :+    e# Consolidate the slices of different lenghts in a single array.
  {     e# Find the first slice S such that...
    1b  e#   the sum of its elements...
    1$= e#   equals X.
  }=    e#   Since Y is in descending order, the first matching slice is also the longest.
  |     e# Set union with [X]. This adds X to the beginning of the S if S != [X].
  {F}*  e# Execute F for each element of S except the first (X).
}:F     e#
~       e# Execute F for the input.
],      e# Count the integers on the stack.

यदि आप अपने पहले हाफ को अपने दूसरे हाफ के साथ जोड़ते हैं, तो आपको 34:ri{_,:)_few:+W%{1b1$=}=|{F}*}:F~],
ऑप्टिमाइज़र

@Optimizer: अच्छा लगा। यह एक अतिरिक्त सुधार की अनुमति देता है। धन्यवाद!
डेनिस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.