ब्रेनएफ में क्विकॉर्ट लागू करें *** [बंद]


32

स्टैक ओवरफ्लो पर लाउंज रूम में चर्चा के अनुसार:

यदि आप Quicksort एल्गोरिथम को लागू नहीं कर सकते हैं, तो en.wikipedia.org/wiki/Quicksort जिस भाषा में भी आपको कम से कम ज्ञान है, आप एक अलग पेशे पर विचार करना चाह सकते हैं। @स्टेट बैंक ऑफ इंडिया

लेकिन एसबीआई ने यह भी नोट किया कि शायद ब्रेनएफ *** एक अपवाद था।

तो, यहाँ पहेली / चुनौती है: ब्रेनफ़ *** में क्विकॉर्ट को लागू करें । कार्यान्वयन होना चाहिए

  • द्वारा व्याख्या की जा इस और / या दुभाषिया (रों) द्वारा यहां (बड़े स्क्रिप्ट के लिए)
  • विकिपीडिया पर वर्णित एल्गोरिथ्म को लागू करें - यदि संभव हो तो इन-प्लेस सॉर्ट करें
  • पूर्णांकों की निम्नलिखित सूची को क्रमबद्ध करें: [0,4,6,4,2,3,9,2,3,6,5,3] और परिणाम प्रिंट करें

एक बिट के आसपास खोज करना मैं एक कार्यान्वयन खोजने में सक्षम हूं , लेकिन यह 6kB है (और हास्केल से संकलित)।
पीटर टेलर

@Peter वास्तव में brainfuck कार्यान्वयन संग्रह के अंदर 474.2 K है - जो कि मेरी अपेक्षा से थोड़ा बड़ा है (और ऑन-लाइन दुभाषिया के लिए बहुत बड़ा है)। शायद मुझे लक्ष्य दुभाषिया बदलना चाहिए .. (लेकिन मुझे हाथ से लिखा हुआ कुछ देखना अच्छा लगेगा )
रोनाल्ड

22
मुझे यकीन है कि मैं इसके बजाय बबल सॉर्ट कर सकता था और कोड को देखने वाला कोई भी अंतर नहीं जानता होगा ...
पीटर ओल्सन

1
@ इस विचार के साथ वास्तव में क्विकॉर्ट को लागू करना है, न कि किसी भी प्रकार से जो काम करेगा ... :-)
रोनाल्ड

1
@ पेटर ऑफ द कॉर्न: हम खराब प्रदर्शन से बबल-सॉर्ट की खोज करेंगे।
उपयोगकर्ता अज्ञात

जवाबों:


55

ब्रेनफ़ * (697 बाइट्स)

>>>>>>>>,[>,]<[[>>>+<<<-]>[<+>-]<+<]>[<<<<<<<<+>>>>>>>>-]<<<<<<<<[[>>+
>+>>+<<<<<-]>>[<<+>>-]<[>+>>+>>+<<<<<-]>[<+>-]>>>>[-<->]+<[>->+<<-[>>-
<<[-]]]>[<+>-]>[<<+>>-]<+<[->-<<[-]<[-]<<[-]<[[>+<-]<]>>[>]<+>>>>]>[-<
<+[-[>+<-]<-[>+<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]<<<<<<]<<[>>+<<-]>[>[>+>
>+<<<-]>[<+>-]>>>>>>[<+<+>>-]<[>+<-]<<<[>+>[<-]<[<]>>[<<+>[-]+>-]>-<<-
]>>[-]+<<<[->>+<<]>>[->-<<<<<[>+<-]<[>+<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]
<<]>[[-]<<<<<<[>>+>>>>>+<<<<<<<-]>>[<<+>>-]>>>>>[-[>>[<<<+>>>-]<[>+<-]
<-[>+<-]>]<<[[>>+<<-]<]]>]<<<<<<-]>[>>>>>>+<<<<<<-]<<[[>>>>>>>+<<<<<<<
-]>[<+>-]<+<]<[[>>>>>>>>+<<<<<<<<-]>>[<+>-]<+<<]>+>[<-<<[>+<-]<[<]>[[<
+>-]>]>>>[<<<<+>>>>-]<<[<+>-]>>]<[-<<+>>]>>>]<<<<<<]>>>>>>>>>>>[.>]

नीचे एक एनोटेट संस्करण है। इसे विकसित करते समय क्या होना चाहिए था, इसका ट्रैक रखने के लिए, मैंने एक टिप्पणी नोटेशन का उपयोग किया जो इस तरह दिखता है:|a|b=0|c=A0|@d|A0|A1|```|

|a| represents a named cell
|b=X| means we know the cell has value X, where X can be a constant or a variable name
|@d|  means the data pointer is in this cell
|A0|A1|```| is variable length array. (using ``` for ... because . is a command)

स्मृति को बाईं ओर प्रक्रिया करने के लिए विभाजन के बाएं बढ़ते स्टैक के साथ रखा गया है, केंद्र में एक स्क्रैच स्पेस है, और सरणी को दाईं ओर सॉर्ट किया जा रहा है। सरणी के माध्यम से सूचकांक और कार्यशील स्थान युक्त "डेटा बस" को स्थानांतरित करके एरे इंडेक्सिंग को नियंत्रित किया जाता है। उदाहरण के लिए, 3-वाइड बस का |i|data|0|A0|A1|A2, |A0|i-1|data|0|A1|A2एक के बाद एक शिफ्टिंग के बाद बन जाएगा । विभाजन को उच्च और निम्न तत्वों के बीच बस को रखकर किया जाता है।
यहाँ पूर्ण संस्करण है:

Get input
>>>>>>>> ,[>,]                      |A0|A1|```|An|@0|
Count items
<[ [>>>+<<<-]>[<+>-]<+ <]  |@0|n|0|0|A0|A1|```
Make 8wide data bus w/ stack on left
>[<<<<<<<<+>>>>>>>>-]  ```|K1=n|K0=0|Z=0|a|b|c|d|e|@f|g|X=0|A0|A1|```
K1 and K0 represent the first index to process (I) and one past the last (J)
Check if still partitions to process
<<<<<<<<[
  Copy K1 to a&c via Z
  [>>+>+>>+<<<<<-]>>[<<+>>-] ```|K1=J|K0=I|@Z=0|a=J|b|c=J|d|e|f|g|X=0|A0|A1|```
  Copy K0 to b&d via Z
  <[>+>>+>>+<<<<<-]>[<+>-] ```|K1|K0|@Z=0|a=J|b=I|c=J|d=I|e|f|g|X=0|A0|A1|```
  Check if J minus I LE 1 : Subtract d from c
  >>>>[-<->]                    |a=J|b=I|c=JminusI|@d=0|e|f|g|
  d= c==0; e = c==1
  +<[>- >+<<-[>>-<<[-]]]        |a=J|b=I|@c=0|d=c==0|e=c==1|f|g|
  if d or e is 1 then J minus I LE 1: partition empty
  >[<+>-]>[<<+>>-]<+<      |a=J|b=I|@c=isEmpty|d=1|e=0|f|g|
  If Partition Empty;
  [->-                      |a=J|b=I|@c=0|d=0|c=0|f|g|
    pop K0: Zero it and copy the remaining stack right one; inc new K0
    <<[-]<[-]<<[-]<[[>+<-]<]>>[>]<+    ``|K1|@Z=0|a=J|b=I|c=0|d=0|e|f|g|
  Else:
  >>>>]>[-                   Z|a=J|b=I|c=isEmpty=0|@d=0|e|f|g|X|A0|A1
    Move Bus right I plus 1 frames; leaving first element to left
    <<+[ -[>+<-]<-[>+<-]>>>>>>>>      (dec J as we move)
      [<<<<<<<<+>>>>>>>>-]<<<<<< ]      Z|Ai|a=J|@b=0|c=0|d|e|f|g|X|Aq
    first element becomes pivot Ap; store in b
    <<[>>+<<-]            Z|@0|a=J|b=Ap|c=0|d|e|f|g|X|Aq
    While there are more elements (J GT 0);
    >[                    Z|0|@a=J|b=Ap|c=0|d|e|f|g|X|Aq
      copy Ap to e via c
      >[>+>>+<<<-]>[<+>-]  Z|0|a=J|b=Ap|@c=0|d=0|e=Ap|f|g|X=0|Aq
       copy Aq to g via X
      >>>>>>[<+<+>>-]<[>+<-] |c|d=0|e=Ap|f|g=Aq|@X=0|Aq
      Test Aq LT Ap:  while e; mark f; clear it if g 
      <<<[ >+>[<-]<[<]           |@d=0|e|f=gLTe|g|
        if f: set d and e to 1; dec e and g 
        >>[<<+>[-]+>-]>-<<-]
      set g to 1; if d: set f 
      >>[-]+<<< [->>+<<]
      If Aq LT Ap move Aq across Bus
      >>[->- <<<<<[>+<-] <[>+<-] >>>>>>>>
        [<<<<<<<<+>>>>>>>>-] <<]  Z|0|Aq|a=J|b=Ap|c|d|e|@f=0|g=0|X=0|Ar
      Else Swap AQ w/ Aj: Build a 3wide shuttle holding J and Aq                
      >[[-] <<<<<<[>>+>>>>>+<<<<<<<-]>>[<<+>>-] |@c=0|d|e|f=0|g=0|X=J|Aq|Ar|```
      If J then dec J
      >>>>>[-
        & While J shuttle right
        [>>[<<<+>>>-]<[>+<-]<-[>+<-]>] |a=J|b=Ap|c|d|e|f|Ar|```|Aj|g=0|@X=0|Aq|
        Leave Aq out there and bring Aj back
        <<[ [>>+<<-] < ]              |a=J|b=Ap|c|d|e|@f=0|g|X=0|Ar|```|Aj|Aq|
      ]>]
    Either bus moved or last element swapped; reduce J in either case
    <<<<<<-]                 |Aq|@a=0|b=Ap|c|d|e|f|g|X|Ar|```|
    Insert Ap To right of bus
    >[>>>>>>+<<<<<<-]        |Aq|a=0|@b=0|c|d|e|f|g|Ap|Ar|```|
    Move the bus back to original location tracking pivot location
    <<[ [>>>>>>>+<<<<<<<-]>[<+>-]<+ <]     
    <[ [>>>>>>>>+<<<<<<<<-]>>[<+>-]<+ <<] |K1|K0|@Z=0|a=0|b=p|c|d|e|f|g|X|Ar|```
    if p is not 0:  put new partition on stack between K0 and K1:
    >+>[<-                                 |K1|K0|Z=0|@a=pEQ0|b=p|
      move K0 to Z; search for last K
      <<[>+<-] <[<]                           |@0|Kn|```|K1|0|Z=K0|a=0|b=p| 
      shift left until return to 0 at K0;
      >[ [<+>-] >]                            |Kn|```|K1|0|@0|Z=K0|a=0|b=p|
      put p one left of there making it K1; restore K0 from Z;
      >>>[<<<<+>>>>-]<<[<+>-]                 |Kn|```|K2|K1=p|K0|@Z=0|a=0|b=0|
    else increment K0 (special case when first partition empty) 
    >>]<[- <<+>>]              
  >>>]  End if !empty
<<<<<<] End If Partitions remaining   @K1=0|K0=0|Z=0|a|b|c|d|e|f|g|X=0|A0|A1|```
Print the Results
>>>>>>>>>>>[.>]

मैं एक समान समाधान पर काम कर रहा था, लेकिन यह काम नहीं कर सका। इस तरह से विभाजन करने के लिए बहुत बढ़िया विचार। मैं एक समय में एक तत्व को बाहर निकाल रहा था और इसे प्रतिस्थापित कर रहा था, और यह काफी जल्दी बोझिल हो गया। मैं भी इसमें 1.5k का था, इसलिए आपने मुझे दक्षता पर भी नष्ट कर दिया।

1
बीएफ में सब कुछ बहुत जल्दी बोझिल हो जाता है :) यहां तक ​​कि प्रतीत होता है कि साधारण चीजें जैसे कैसे एक कुशल if (i<j) {} else {}करने के लिए कई ने सही पाने की कोशिश की। और धार के मामले हत्यारे हैं। मुझे नहीं पता कि मैंने कितनी बार सोचा "बस यह एक छोटी सी चीज बची है ..." और फिर एक परीक्षण मामले की खोज की जिसके कारण एक और कई घंटे काम करने में सक्षम थे। मुझे लगता है कि मैं इसे कुछ दर्जन पात्रों द्वारा कम कर सकता हूं, लेकिन मुझे यकीन नहीं है कि मैं प्रयास में रखना चाहता हूं।
एएसएचली

एक शब्द: वाह! मैंने ईमानदारी से नहीं सोचा था कि यह मानवीय रूप से संभव था। मैं इसके माध्यम से कुछ इनपुट चलाने जा रहा हूं, यह देखने के लिए कि यह कैसे काम करता है :-)
रोनाल्ड

महाकाव्य! बस महाकाव्य!
18 अगस्त को vsz

केवल कहने के लिए "पवित्र च * सीके है!"
मठ चिलर

11

ब्रेनफक (178 बाइट्स)

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

हमेशा की तरह, मेरा पहला काम करने का संस्करण दो बार था जब तक कि यह 392 बाइट्स की आवश्यकता थी। कई संशोधनों और दो या तीन प्रमुख पुनर्लेखनों ने इस तुलनात्मक रूप से सुशोभित 178-बाइट संस्करण का उत्पादन किया। (हालांकि आश्चर्यजनक रूप से एक रैखिक-समय की छँटाई केवल 40 बाइट्स है।)

>+>>>>>,[>+>>,]>+[--[+<<<-]<[[<+>-]<[<[->[<<<+>>>>+<-]<<[>>+>[->]<<[<]
<-]>]>>>+<[[-]<[>+<-]<]>[[>>>]+<<<-<[<<[<<<]>>+>[>>>]<-]<<[<<<]>[>>[>>
>]<+<<[<<<]>-]]+<<<]]+[->>>]>>]>[brainfuck.org>>>]

इनपुट मानों को हर तीन सेल में स्थान दिया गया है: प्रत्येक (V) एल्यु सेल के लिए, (L) एबेल सेल (नेविगेशन के लिए उपयोग किया जाता है) और (S) क्रैच स्पेस के लिए एक और सेल है। सरणी का समग्र लेआउट है

0 1 0 0 0 SVLSVL ... SVL 0 0 0 0 0 0 ...

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

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

>+>>>>>,[>+>>,]>+[                      set up; for each subarray:
    --[+<<<-]<[                         find the subarray; if it exists:
        [<+>-]<[                        S=pivot; while pivot is in S:
            <[                          if not at end of subarray
                ->[<<<+>>>>+<-]         move pivot left (and copy it) 
                <<[>>+>[->]<<[<]<-]>    move value to S and compare with pivot
            ]>>>+<[[-]<[>+<-]<]>[       if pivot greater then set V=S; else:
                [>>>]+<<<-<[<<[<<<]>>+>[>>>]<-]     swap smaller value into V
                <<[<<<]>[>>[>>>]<+<<[<<<]>-]        swap S into its place
            ]+<<<                       end else and set S=1 for return path
        ]                               subarray done (pivot was swapped in)
    ]+[->>>]>>                          end "if subarray exists"; go to right
]>[brainfuck.org>>>]                    done sorting whole array; output it

1
बहुत बढ़िया। जब आप बीएफ के मुहावरों के साथ काम करते हैं तो यह बहुत साफ होता है, बजाय इसके कि मैं एक प्रक्रियात्मक भाषा की तरह काम करने के लिए मजबूर करूं, जैसे मैंने किया।
एएसएचली

यह है; लेकिन 392 बाइट्स में संस्करण 4 भी मुहावरेदार ब्रेनफक था। यह संस्करण 39 या तो है। :)
डैनियल क्रिस्टोफ़ानी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.