कल्पना मर्ज सॉर्ट करें


30

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

सूची पर एल्गोरिथ्म का निष्पादन [1,7,6,3,3,2,5]निम्नलिखित तरीके से देखा जा सकता है:

       [1,7,6,3,3,2,5]
       /             \      split
   [1,7,6,3]       [3,2,5]
    /     \        /    \   split
 [1,7]   [6,3]   [3,2]  [5]
 /   \   /   \   /   \   |  split
[1] [7] [6] [3] [3] [2] [5]
 \   /   \   /   \   /   |  merge
 [1,7]   [3,6]   [2,3]  [5]
    \     /         \   /   merge
   [1,3,6,7]       [2,3,5]
       \             /      merge
       [1,2,3,3,5,6,7]

काम

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

[1,7,6,3,3,2,5]
[1,7,6,3][3,2,5]
[1,7][6,3][3,2][5]
[1][7][6][3][3][2][5]
[1,7][3,6][2,3][5]
[1,3,6,7][2,3,5]
[1,2,3,3,5,6,7]

इसके अलावा, कोई भी उचित सूची संकेतन ठीक है, इसलिए निम्नलिखित भी एक मान्य आउटपुट होगा:

1 7 6 3 3 2 5
1 7 6 3|3 2 5
1 7|6 3|3 2|5
1|7|6|3|3|2|5
1 7|3 6|2 3|5
1 3 6 7|2 3 5
1 2 3 3 5 6 7

अंत में, दो छोटी सूचियों में एक सूची को विभाजित करने का तरीका आपके ऊपर है जब तक दोनों परिणामी सूचियों की लंबाई एक-एक करके अलग-अलग होती है। इसका मतलब यह है कि और [3,2,4,3,7]में विभाजित करने के बजाय , आप भी और विषम अनुक्रमित ( और ) पर तत्वों को ले कर विभाजित कर सकते हैं या हर बार विभाजन को यादृच्छिक कर सकते हैं।[3,2,4][3,7][3,4,7][2,3]

यह , इसलिए किसी भी भाषा में सबसे छोटा कोड बाइट्स में मापा जाता है।

परीक्षण के मामलों

जैसा कि ऊपर उल्लेख किया गया है, वास्तविक प्रारूप और सूची को आधे में विभाजित करने का तरीका आपके ऊपर है।

[10,2]
[10][2]
[2,10]

[4,17,1,32]
[4,17][1,32]
[4][17][1][32]
[4,17][1,32]
[1,4,17,32]

[6,5,4,3,2,1]
[6,5,4][3,2,1]
[6,5][4][3,2][1]
[6][5][4][3][2][1]
[5,6][4][2,3][1] <- Important: This step cannot be [5,6][3,4][1,2], because 3 and 4 are on different branches in the the tree
[4,5,6][1,2,3]
[1,2,3,4,5,6]

5
@dylnan आप एक अन्य छँटाई एल्गोरिथ्म का उपयोग कर सकते हैं या छँटाई करने के लिए एक प्रकार के समारोह में बनाया गया है ...
त्रुटी

5
कुछ गोल्फ विचार: परिणाम के निचले आधे भाग को पहले आधे हिस्से में छांटकर और आदेश को उलट कर उत्पन्न किया जा सकता है।
जुंगह्वान मिन

2
@Arnauld [[1,2],[3],[4,5],[6]]मंच वास्तव में सही समाधान है, क्योंकि मर्ज की तरह पुनरावर्ती कार्य कर रहा है। यही कारण है कि अगर हम साथ शुरू है [1,2,3,4,5,6]और यह भागों में विभाजित [1,2,3]और [4,5,6], तो उन सूचियों को स्वतंत्र रूप से कार्रवाई की जाती है, जब तक वे अंतिम चरण में विलय कर रहे हैं।
लैकोनी

2
@ l4m2 ठीक है, अंतिम उत्तर के लिए प्रयास करें: 1. आपको सीमांकक की आवश्यकता है क्योंकि पूर्णांक> 9 का समर्थन किया जाना चाहिए। 2. यह उसी कारण के लिए मान्य नहीं है जैसा कि ऊपर मेरी टिप्पणी में दिया गया है। यदि हम अलग हो जाते हैं [3]और [2,1]फिर, वे अलग-अलग शाखाओं पर होते हैं, तो हम विलय नहीं कर सकते हैं [3]और [2]बाद [2,1]में विभाजित होते हैं [2]और [1]
लैकोनी

1
वास्तव में उसके बाद का वाक्य मेरे प्रश्न का सटीक उत्तर देता है। लापता होने के लिए क्षमा करें। : पी
ज़र्गब

जवाबों:


8

हास्केल , 137 128 127 125 121 109 106 बाइट्स

(-2) + (- ४) = (- ६) बाइट्स निम्मी को धन्यवाद ! एक सूची में सभी चरणों को इकट्ठा करने के लिए इसे बदलना (फिर से नीमी के कारण) 12 और बाइट्स बचाता है।

Laikoni के कारण एक और 3 बाइट्स , पैटर्न गार्ड बाइंडिंग के साथ और लिस्ट का चतुर उपयोग गार्ड को एन्कोड करने के लिए।

import Data.List
g x|y<-x>>=h=x:[z|x/=y,z<-g y++[sort<$>x]]
h[a]=[[a]]
h x=foldr(\x[b,a]->[x:a,b])[[],[]]x

इसे ऑनलाइन आज़माएं!

सूचियों को विषम और सम-विषम तत्वों में विभाजित करना दो अनुक्रमिक हिस्सों की तुलना में एक छोटा कोड है, क्योंकि हम इसे मापने के लिए बख्शे हुए हैं length

सूचियों को "प्रिंट" करके काम करता है, फिर विभाजित सूचियों के साथ पुनरावृत्ति करता है ( x >>= h) यदि वास्तव में कोई विभाजन किया गया था, और छांटे गए सूचियों को "मुद्रण" करता है; एक इनपुट सूची के साथ शुरू; गैर-रिक्त इनपुट ग्रहण करना। और वास्तविक मुद्रण के बजाय, बस उन्हें एक सूची में इकट्ठा करना।

g[[6,5..1]]मुद्रित लाइन-बाय-लाइन द्वारा निर्मित सूची है:

[[6,5,4,3,2,1]]
[[6,4,2],[5,3,1]]
[[6,2],[4],[5,1],[3]]
[[6],[2],[4],[5],[1],[3]]
[[2,6],[4],[1,5],[3]]
[[2,4,6],[1,3,5]]
[[1,2,3,4,5,6]]

1
... p=printऔर तीन बार pइसे ऑनलाइन आज़माएं!
नीमी

@ महान, फिर से, और बहुत धन्यवाद! अब यह वास्तव में गोल्फ दिखता है । :)
विल नेस

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

3
मुझे नहीं लगता कि हमारे पास "विज़ुअलाइज़िंग" की उचित परिभाषा है। अधिक सामान्य चुनौतियां सूचियों को "आउटपुट" करने के लिए कहती हैं और हमारी चूक के अनुसार यह एक फ़ंक्शन के रिटर्न वैल्यू के माध्यम से किया जा सकता है । अन्य उत्तर, उदाहरण 1 , 2 इसे इस तरह से भी करते हैं। - मुझे नहीं लगता कि मेरा सुझाव इतना अलग है, यह सिर्फ उन्हें मुद्रित करने के बजाय मध्यवर्ती सूची एकत्र करता है। इसे बेझिझक संपादित करें।
nimi

3
g x|y<-x>>=h=x:[z|x/=y,z<-g y++[sort<$>x]]कुछ और बाइट्स बचाता है।
लकोनी

7

वोल्फ्राम लैंग्वेज (गणितज्ञ) , 146 127 111 102 बाइट्स

Join[u=Most[#/.a:{_,b=__Integer}:>TakeDrop[a,;;;;2]&~FixedPointList~#],Reverse@Most@u/.a:{b}:>Sort@a]&

इसे ऑनलाइन आज़माएं!

रिटर्न ए List जिसमें चरण शामिल हैं।

व्याख्या

#/.a:{_,b=__Integer}:>TakeDrop[a,;;;;2]&

एक इनपुट में, Listआधे में 2 या अधिक पूर्णांकों वाले सभी s विभाजित करें । पहले सबलिस्ट में विषम-अनुक्रमित तत्व (1-अनुक्रमित) होते हैं, और दूसरे में सम-अनुक्रमित तत्व होते हैं।

u=Most[... &~FixedPointList~#]

दोहराएं कि जब तक कुछ भी नहीं बदलता (यानी सभी उप-लंबाई लंबाई -1 हैं)। सभी मध्यवर्ती परिणाम रखें। इसे ( Listसभी चरणों में) संग्रहीत करें u

Reverse@Most@u

के अंतिम तत्व को छोड़ें uऔर इसे उल्टा करें।

... /.a:{b}:>Sort@a

उपरोक्त परिणाम से, पूर्णांकों की सूची की सभी घटनाओं को क्रमबद्ध करें।


6

क्लीन , 228 206 168 157 140 121 104 बाइट्स

इस तथ्य के उपयोग से चरणों की सूची को अंदर की ओर बनाता है, इस तथ्य का उपयोग करता है कि nअंत से -थ्यू तत्व का सॉर्ट किया गया संस्करण हैn -थ तत्व शुरुआत से -थ तत्व ।

जंगवान मिन की टिप्पणी से आइडिया

import StdEnv
@u#(a,b)=splitAt(length u/2)u
=if(a>[])[[u]:[x++y\\y<- @b&x<- @a++ @a++ @a]][]++[[sort u]]

इसे ऑनलाइन आज़माएं!


4

चारकोल , 145 133 123 122 बाइट्स

≔⟦⪪S ⟧θW⊖L§θ⁰«⟦⪫Eθ⪫κ ¦|⟧≔EE⊗Lθ§θ÷λ²✂κ﹪λ²Lκ²θ»⟦⪫ΦEθ⪫ι ι|⟧W⊖Lθ«≔⮌θη≔⟦⟧θWη«≔⊟ηε≔⟦⟧ζF⊟η«≔εδ≔⟦⟧εFδ⊞⎇‹IμIλζεμ⊞ζλ»⊞θ⁺ζε»⟦⪫Eθ⪫κ ¦|

इसे ऑनलाइन आज़माएं! लिंक कोड के वर्बोज़ संस्करण के लिए है। अभी भी चारकोल कीड़े के आसपास काम कर रहे हैं ... संपादित करें: Mapएक गरीब आदमी की सरणी समझ के रूप में एक डबल का उपयोग करके 5 बाइट्स सहेजे गए । Popकिसी सरणी पर डबल पुनरावृति का उपयोग करके 4 बाइट्स सहेजे गए । के बजाय का उपयोग करके 3 बाइट्स सहेजे गए Push। एक गोल्फ की whileस्थिति के साथ आने वाले 10 बाइट्स को बचाया जो एक चारकोल बग से बचा जाता है। 1 बाइट की बचत करके पता चलता है कि चारकोल वास्तव में एक फिल्टर ऑपरेटर है। स्पष्टीकरण:

≔⟦⪪S ⟧θ

रिक्त स्थान पर इनपुट को विभाजित करें, और फिर परिणाम को एक बाहरी सरणी में लपेटें, जिससे इसे बचाया जा सके q

W⊖L§θ⁰«

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

⟦⪫Eθ⪫κ ¦|⟧

qरिक्त स्थान और ऊर्ध्वाधर लाइनों के साथ शामिल होने के तत्वों को प्रिंट करें । (सरणी परिणाम को अपनी लाइन पर प्रिंट करने का कारण बनती है। उसी बाइट काउंट के लिए इसे प्राप्त करने के अन्य तरीके हैं।)

≔EE⊗Lθ§θ÷λ²✂κ﹪λ²Lκ²θ»

के प्रत्येक तत्व को डुप्लिकेट करके एक सूची बनाएं q, फिर उस सूची पर मैप करें और प्रत्येक सूची का आधा हिस्सा लें (वैकल्पिक तत्व दृष्टिकोण का उपयोग करके), जिसके परिणामस्वरूप परिणाम वापस आ जाएगा q

⟦⪫ΦEθ⪫ι ι|⟧

qरिक्त स्थान और ऊर्ध्वाधर लाइनों के साथ शामिल होने के तत्वों को प्रिंट करें । दरअसल, इस बिंदु पर तत्व qया तो खाली हैं या एकल-तत्व सूचियां हैं, इसलिए उन्हें शामिल करना उन्हें खाली तारों या उनके तत्वों में परिवर्तित करता है। खाली तार अनावश्यक अनुगामी रेखाएँ जोड़ते हैं ताकि वे फ़िल्टर हो जाएं। एक चपटा ऑपरेटर भले ही गोल्फर रहा हो (कुछ ऐसा ही ⟦⪫Σθ|⟧)।

W⊖Lθ«

qएक से अधिक तत्व होने पर दोहराएं । (निम्नलिखित कोड को तत्वों की एक समान संख्या की आवश्यकता होती है।)

≔⮌θη≔⟦⟧θ

कॉपी qकरें h, लेकिन उलट (नीचे देखें), और qखाली सूची पर रीसेट करें।

Wη«

hखाली होने तक दोहराएं ।

≔⊟ηε

के अगले तत्व निकालें hमें e। ( Popअंत से अर्क, जिसके कारण मुझे उल्टा करना पड़ता है q।)

≔⟦⟧ζ

आरंभ zएक खाली सूची के लिए ।

F⊟η«

के अगले तत्व के तत्वों पर लूप करें h

≔εδ≔⟦⟧ε

कॉपी eकरें dऔर eएक खाली सूची पर रीसेट करें।

Fδ

के तत्वों पर पाश d

⊞⎇‹IμIλζεμ

उन्हें धक्का zयाe इस पर निर्भर करें कि वे अगले तत्व के वर्तमान तत्व से छोटे हैं नहीं h

⊞ζλ»

के अगले तत्व के वर्तमान तत्व को पुश करें h करने के लिए z

⊞θ⁺ζε»

zशेष किसी भी तत्व के साथ संबंध बनाएं eऔर उस पर धकेलेंq । यह दो तत्वों के विलय को पूरा करता है h

⟦⪫Eθ⪫κ ¦|

qरिक्त स्थान और ऊर्ध्वाधर लाइनों के साथ शामिल होने के तत्वों को प्रिंट करें ।


डटे रहो। एक और बग है? : /
केवल

@ ASCII- केवल नहीं, यह वह while (...Map(...)...)बग था जिसके बारे में मैंने आपको पहले ही बताया था।
नील

3

पायथन 2 , 145 144 बाइट्स

जुंगहवान मिन की टिप्पणी से आइडिया -1 जोनाथन फ्रीच
को धन्यवाद

p=input()
l=[[p]]
i=0
while 2**i<len(p):l[i+1:i+1]=[sum([[x[1::2],x[::2]][len(x)<2:]for x in l[i]],[]),map(sorted,l[i])];i+=1
for s in l:print s

इसे ऑनलाइन आज़माएं!


मैं पूरी तरह से निश्चित नहीं हूं, हालांकि आप इसके बजाय उपयोग <2करने में सक्षम हो सकते हैं==1
जोनाथन फ्रीच

2

जावास्क्रिप्ट (ईएस 6), 145 बाइट्स

f=a=>a.join`|`+(a[0][1]?`
${f([].concat(...a.map(b=>b[1]?[b.slice(0,c=-b.length/2),b.slice(c)]:[b])))}
`+a.map(b=>b.sort((x,y)=>x-y)).join`|`:``)

एक सरणी के भीतर एक सरणी के रूप में इनपुट लेता है, अर्थात f([[6,5,4,3,2,1]])। आउटपुट की पहली और अंतिम पंक्तियों को उत्पन्न करके काम करता है, फिर बंटवारा और फिर से खुद को कॉल करना, जब तक कि हर उप-सरणी की लंबाई 1 नहीं है। यहां एक बुनियादी प्रदर्शन है कि यह कैसे काम करता है:

f([[6,5,4,3,2,1]]):
  6,5,4,3,2,1
  f([[6,5,4],[3,2,1]]):
    6,5,4|3,2,1
    f([[6,5],[4],[3,2],[1]]):
      6,5|4|3,2|1
      f([[6],[5],[4],[3],[2],[1]]):
        6|5|4|3|2|1
      end f
      5,6|4|2,3|1
    end f
    4,5,6|1,2,3
  end f
  1,2,3,4,5,6
end f

2
तो, क्या कोई बिंदु था जहां 145 बाइट्स पर तीन उत्तर बंधे थे?
नील

2

भूसी , 14 बाइट्स

S+ȯ†O↔hUmfL¡ṁ½

एकल सरणी वाला एक सरणी लेता है। इसे ऑनलाइन आज़माएं!

व्याख्या

S+ȯ†O↔hUmfL¡ṁ½  Implicit input, say A = [[4,17,32,1]].
           ¡    Iterate this function on A:
            ṁ½   Split each array in two, concatenate results: [[4,17],[32,1]]
                Result is [[[4,17,32,1]],
                           [[4,17],[32,1]],
                           [[4],[17],[32],[1]],
                           [[4],[],[17],[],[32],[],[1],[]],
                           ...
        mfL     Map filter by length, removing empty arrays.
                Result is [[[4,17,32,1]],
                           [[4,17],[32,1]],
                           [[4],[17],[32],[1]],
                           [[4],[17],[32],[1]],
                           ...
       U        Longest prefix of unique elements:
                       P = [[[4,17,32,1]],[[4,17],[32,1]],[[4],[17],[32],[1]]]
      h         Remove last element: [[[4,17,32,1]],[[4,17],[32,1]]]
     ↔          Reverse: [[[4,17],[32,1]],[[4,17,32,1]]]
   †O           Sort each inner array: [[[4,17],[1,32]],[[1,4,17,32]]]
S+ȯ             Concatenate to P:
                           [[[4,17,32,1]],
                            [[4,17],[32,1]],
                            [[4],[17],[32],[1]],
                            [[4,17],[1,32]],
                            [[1,4,17,32]]]
                Implicitly print.

अंतर्निहित ½एक सरणी लेता है और इसे बीच में विभाजित करता है। यदि इसकी लंबाई विषम है, तो पहला भाग एक तत्व द्वारा लंबा है। एक एकल सरणी में [a]परिणाम होता है [[a],[]]और एक खाली सरणी []देता है [[],[]], इसलिए आवेदन करने से पहले खाली सरणियों को निकालना आवश्यक है U


1

स्टैक्स , ११६ (> 3>) 38 29 बाइट्स CP437

-9 बाइट्स प्रति टिप्पणी @recursive द्वारा। अब इनपुट एक सिंगलटन के रूप में दिया गया है जिसका एकमात्र तत्व क्रमबद्ध होने वाली संख्याओं की एक सरणी है।

ƒ3s}óºE/ßB╢↕êb∩áαπüµrL╞¶è,te+

इसे ऑनलाइन आज़माएं!

35 बाइट्स के साथ अनपैक्ड संस्करण:

{c{Jm'|*Pc{2Mm:f{fc{Dm$wW{{eoJm'|*P

व्याख्या

कोड को दो भागों में विभाजित किया जा सकता है। पहला भाग विभाजन को दर्शाता है और दूसरा विलय को दर्शाता है।

विभाजन को देखने के लिए कोड:

{                      w    Do the following while the block generates a true value
 c                          Copy current nested array for printing
  {Jm                       Use spaces to join elements in each part
     '|*                    And join different parts with vertical bar 
        P                   Pop and print

         c                  Copy current nested array for splitting
          {2Mm              Separate each element of the array to two smaller parts with almost the same size
                                That is, if the number of elements is even, partition it evenly.
                                Otherwise, the first part will have one more element than the second.
              :f            Flatten the array once
                {f          Remove elements that are empty arrays

                  c         Copy the result for checking 
                   {Dm$     Is the array solely composed of singletons?
                            If yes, ends the loop.

विलय की कल्पना करने के लिए कोड:

W              Execute the rest of the program until the stack is empty
 {{eoJm        For each part, sort by numeric value, then join with space
       '|*     Join the parts with vertical bar
          P    Pop and print the result

पुराना संस्करण, वास्तव में नेस्टेड सूची संरचना का निर्माण कर रहा है।

{{cc0+=!{x!}Mm',*:}}Xd;%v:2^^{;s~{c^;<~sc%v,*{2M{s^y!svsm}M}YZ!x!Q,dmU@e;%v:2^{;%v:2^-N~0{c;={scc0+=Cc%v!C:f{o}{scc0+=C{s^y!svsm}?}Y!cx!P,dcm

cc0+= यह देखने के लिए कोड में तीन बार उपयोग किया जाता है कि क्या स्टैक के शीर्ष एक अदिश या एक सरणी है।

{{cc0+=!{x!}Mm',*:}}Xएक ब्लॉक बनाता है जो पुनरावर्ती रूप से संख्याओं के नेस्टेड सरणी को ठीक से आउटपुट करने के लिए कहता है। (Stax में डिफ़ॉल्ट आउटपुट मुद्रण से पहले एक नेस्टेड सरणी को सदिश करता है)।

{                  }X    Store the code block in X
 {           m           Map each element in the list with block
  cc                     Make two copies of the element
    0+                   + 0. If the element is a scalar, nothing will change
                              If the element is an array, the element 0 will be appended
      =!{  }M            If the element has changed after the `0+` operation
                             Which means it is an array
         x!              Recursively execute the whole code block on the element

              ',*        Join the mapped elements with comma
                 :}      Bracerizes the final result

दो अन्य ब्लॉक हैं जो क्रमशः विभाजन और विलय करते हैं। वे बहुत अधिक क्रियाशील हैं और मुझे समझाने की परवाह नहीं है (इस पोस्ट के ऐतिहासिक संस्करण में थोड़ी अधिक जानकारी है लेकिन बहुत उम्मीद नहीं है)।


बहुत अच्छा सुधार। मैं अभी तक इसे पूरी तरह से नहीं समझता, लेकिन मुझे लगता है कि cH!इसका इस्तेमाल किया जा सकता है cH%!
पुनरावर्ती

{Nd}Mद्वारा Tभी प्रतिस्थापित किया जा सकता है ।
पुनरावर्ती

मैंने कुछ और अनुकूलन किए। staxlang.xyz/… भूसी उत्तर एक सरणी में एक सरणी के रूप में इनपुट लेता है, इसलिए मुझे लगता है कि यह कानूनी है।
पुनरावर्ती

मुझे एक समाधान मिला जो 2 एसेसी वर्णों का छोटा होना चाहिए, लेकिन मुझे सरणी संक्रमण में बग का पता चला। विशेष रूप से, यह सरणी पंक्तियों को बदल देता है। मैं इसे 1.0.4 के लिए बैकलॉग में जोड़ूंगा
पुनरावर्ती

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