मेरे मोजे सॉर्ट करने में मेरी मदद करें!


30

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

यदि मोजे का प्रारंभिक ढेर है

1 2 3 3 2 1

फिर मुझे कोई विभाजन नहीं करना है। मैं दोनों 1मोजे, फिर दोनों 2मोजे, फिर दोनों 3मोजे निकाल सकता हूं ।

यदि इसके बजाय प्रारंभिक ढेर है

1 2 3 2 3 1

फिर मुझे पहले इसे अलग करना होगा क्योंकि मैं सभी मोज़ों को केवल अंत से हटाकर जोड़ी नहीं बना पाऊंगा। एक संभावना इसे दो बवासीर में विभाजित करने की है

1 2 3 and 2 3 1

अब मैं 1मोजे निकाल सकता हूं , छोड़ कर 2 3 and 2 3, उसके बाद 3मोजे, छोड़ कर 2 and 2आखिर में 2मोजे।

आपका काम

मोजे के शुरुआती ढेर को देखते हुए, एक प्रोग्राम लिखें जो इसे छोटे ढेर में विभाजित करेगा जो मुझे मोज़े को सॉर्ट करने की अनुमति देगा। आपके कार्यक्रम को ढेर के सबसे कम संख्या में ढेर को विभाजित करना चाहिए (यदि कई सर्वश्रेष्ठ समाधान हैं, तो आपको केवल एक खोजने की आवश्यकता है)।

इनपुट को एक सूची, सीमांकित स्ट्रिंग, या अन्य सुविधाजनक रूप में दिया जाएगा। इसमें केवल पूर्णांकों के बीच 1और कुछ अधिकतम मान होंगे n, प्रत्येक पूर्णांक में दो बार होगा।

आउटपुट में इनपुट लिस्ट शामिल होनी चाहिए जो किसी भी सुविधाजनक रूप में दी गई छोटी सूचियों में विभाजित हो।

उदाहरण

Input             Sample Output
1 1               1 1
1 2 1 2           1; 2 1 2
1 3 2 4 3 2 1 4   1 3 2; 4 3 2 1 4
1 2 3 4 3 4 1 2   1; 2 3; 4 3 4 1 2
1 1 2 2 3 3       1 1 2; 2 3 3
4 3 4 2 2 1 1 3   4 3 4 2; 2 1 1 3

ध्यान दें कि इनमें से अधिकांश इनपुट के लिए यह एकमात्र अनुमत आउटपुट नहीं है। दूसरे मामले के लिए, उदाहरण के लिए, आउटपुट 1 2; 1 2या 1 2 1; 2भी स्वीकार किए जाएंगे।

कुछ परीक्षण सुझावों के लिए Sp3000 के लिए धन्यवाद!

मुझे अपने कपड़ों को छांटने में काफी समय लगता है, इसलिए अपने कोड को जितना संभव हो उतना कम करें। बाइट्स जीत में सबसे छोटा जवाब!

टिप्पणियाँ

  • मैं यह देखने के लिए नहीं चाहता कि यह देखने के लिए है कि इसकी मिलान करने वाली जोड़ी है या नहीं, इसलिए एक ही छोर से एक जोड़ी में दोनों मोजे लेने की अनुमति नहीं है। उदाहरण के लिए, यदि ढेर है 1 1 2 2तो आप इसे एक ढेर के रूप में छोड़ नहीं सकते हैं और 1बाएं सिरे से दोनों मोज़े ले सकते हैं ।

5
मैं कह सकता हूं कि पीपीसीजी कार्मिस्टर में आपका स्वागत है। यह एक बहुत अच्छी पहली चुनौती है +1।
लॉजिक नाइट

1
PPCG में आपका स्वागत है! यह एक बहुत अच्छा पहला प्रश्न है। यद्यपि यह प्रश्न किसी भी बड़े मुद्दे के लिए प्रकट नहीं होता है, हम उपयोगकर्ताओं को पोस्ट करने से पहले उनकी चुनौतियों पर प्रतिक्रिया प्राप्त करने के लिए सैंडबॉक्स का उपयोग करने के लिए प्रोत्साहित करते हैं।
Mego

तो 123213क्या 1; 23; 213( 1; 23; 213-> 1; 2; 21-> ; 2; 2) में विभाजित किया जा सकता है ?
आर। कप

@ मेगो धन्यवाद! मैं भविष्य में ऐसा करना सुनिश्चित करूंगा। @ R.Kap यह विभाजित करने के लिए एक मान्य तरीका होगा, लेकिन जवाब को एक विभाजन देना चाहिए जो इसे सबसे कम संख्या में ढेर में विभाजित करता है। चूंकि 123213केवल दो बवासीर का उपयोग करके विभाजित करना संभव है , इसलिए आपके उत्तर को दो-पाइल विभाजन में से एक देना होगा।
कार्मिस्टर

1
@ मैं पूरी तरह से आश्वस्त नहीं हूं कि मैं आपके प्रश्न को समझ सकता हूं, लेकिन लेने के लिए उपलब्ध मोज़े प्रत्येक ढेर की शुरुआत में हैं और प्रत्येक ढेर के अंत में।
कारमिस्टर 11

जवाबों:


6

पायथ, 25 बाइट्स

hf!u #-R.-F{BhMs_BMGGT)./

परीक्षण सूट

स्पष्टीकरण:

hf!u #-R.-F{BhMs_BMGGT)./
                       ./    Form all partitions (implicitly) of the input.
 f                           Filter the permutations on
   u                 T)      Run the following function on the partition
                             until it reaches a fixed point:
                _BMG         Bifurcate the lists on reversal
               s             Concatenate
             hM              Take the first element of each list. 
                             These elements are all the ones on the ends of lists.
           {B                Bifurcate on deduplication
        .-F                  Bagwise subtraction.
                             Only elements repeated in ends of lists remain.
      -R            G        Remove these elements from each list.
   ' #'                      Filter out empty lists.
  !                          Negate. Only an empty list as fixed point succeeds.
h                            Output the first successful partition.

5

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

ऐसी भाषा के लिए कोई आसान काम नहीं है जिसमें कोई कॉम्बिनेटरिक्स बिल्डिंग्स नहीं हैं।

शायद अधिक sligthly अधिक गोल्फ।

नोट: सभी विभाजन कम से कम 2 आकार के होते हैं, क्योंकि एक तत्व के साथ एक विभाजन हमेशा कम उपयोगी होता है।

Example: [1] [2 3 4] // can take 1 or 2 or 4  
Better: [1 2] [3 4] // can take 3 too  
a=>{G=(v,i,u=v)=>{if(i--){for(;r[i]=--u;)if(G(u,i))return 1;}else for(w=[...r,n=l].map((x,i)=>a.slice(z,z=x-~i),z=0),y=w.join`;`;w.map(b=>[0,1].map(q=>(x=b[q*=~-b.length])&&(t[x]?([c,p]=t[x],n-=2,p?c.pop():c.shift(),q?b.pop():b.shift()):t[x]=[b,q])),c=0,t=[]),c;)if(!n)return 1};for(l=a.length,r=[],k=0;!G(l-k-1,k);k++);return y}

भागों में व्याख्या

(यह अत्यधिक क्रिया है, लेकिन मुझे यह समझाने में मुश्किल हुई - अंततः "इसे सभी को एक साथ रखना" छोड़ें)

किसी पुनरावर्ती फ़ंक्शन किसी सरणी के सभी संभावित विभाजन को एन्यूमरेट करने के लिए

// v: array length
// i number of splits
// fill the global array r that must exists
G=(v,i,u=v)=>
{
  if(i--)
  {
    for(;r[i]=--u;)
      G(u,i)
  }
  else
  {
    // the current split position are in r, ready to use
    // for instance...
    parts = [...r,a.length].map(x=>a.slice(z,z=x),z=0)
    console.log(r, parts)
  }
};

r=[]
a=['A','B','C','D']
G(4, 2)

// output in console (firebug)
[2, 3] [["A", "B"], ["C"], ["D"]]
[1, 3] [["A"], ["B", "C"], ["D"]]
[1, 2] [["A"], ["B"], ["C", "D"]]

अब, मुझे आकार 2 या अधिक के विभाजनों की आवश्यकता है, इसलिए मुझे इस फ़ंक्शन का उपयोग sligtly विभिन्न मापदंडों के साथ करना होगा। पैरामीटर v "सरणी आकार - वांछित विभाजन की संख्या - 1" है। फिर मुझे कुछ अलग तरीके से विभाजन का निर्माण करना होगा।

// Same call (4,2), same r, but the array b is of size 7
part = [...r,b.length].map((x,i)=>
          b.slice(z,z=x+i+1) // add 1 more element to each partition
       ,z=0))
// output in console (firebug) 
[2, 3] [["A", "B", "C"], ["D", "E"], ["F", "G"]]
[1, 3] [["A", "B"], ["C", "D", "E"], ["F", "G"]]
[1, 2] [["A", "B"], ["C", "D"], ["E", "F", "G"]]

तो, मैं विभाजन की सूची में कोई विभाजन, 1 विभाजन, 2 विभाजन और इतने पर गणना कर सकता हूं। जब मुझे एक काम करने वाला विभाजन मिलता है तो मैं रोक दिया और पाया परिणाम का उत्पादन होगा।

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

t = []; // array to note the repeated values
// t[x] == [
//           subarray holding value x, 
//           position of value x (I care zero or nonzero)
//         ]
n = a.length // counter start, must reach 0
// remember part just in case, because this check will destroy it 
result = part.join(';') // a string representation for return value
do
{
  // in the golfed code there is a forr loop
  // all this body is inside the for condition
  c = 0; // init c to a falsy, if a pair is found c becomes truthy
  part.forEach(b=> // b: array, current partition
    [0,1].forEach(q=> ( // exec for 0 (start), 1 (end)
      q *= b.length-1, // now q is the correct index
      x = b[q]) // x is the value at start or end
      x && ( // b could be empty, check that x is not 'undefined'
        t[x] ? // is there a value in t at position x?
           ( // yes, remove the pair
             n-=2, // pair found, decrement counter
             [c, p] = t[x], // get stored array and position
             p ? c.pop() : c.shift(), // remove from c at start or end
             q ? b.pop() : b.shift()  // remove twin value from b
           )
           : // no, remember the value in t
             t[x] = [b, q]
    )) // end [0,1].forEach
  ) // end part.forEach
}
while (c) // repeat until nothing can be removed
if(!n) return 1 // wow, result found (in 'result' variable)

फिर, लापता भाग विभाजन फ़ंक्शन को बढ़ाते हुए जी फ़ंक्शन को शांत करने वाला एक लूप है। परिणाम मिलने पर लूप बाहर निकल जाता है।

इसे एक साथ रखें

F=a=>{
  G=(v,i,u=v)=>{
    if (i--)
    {
      for(; r[i]=--u; )
        if (G(u,i)) 
          return 1;
    }
    else
    {
      w = [...r,n=l].map((x,i)=>a.slice(z, z = x-~i), z = 0);
      y = w.join`;`;
      for(; // almost all the for body is inside the condition
        w.map(b=>
          [0,1].map(q=>
            (x=b[q*=~-b.length])
             &&(t[x]
                ?([c,p]=t[x],n-=2,
                   p?c.pop():c.shift(),
                   q?b.pop():b.shift())
                :t[x]=[b,q])) // end [0,1].map
          ,c=0,t=[] // init variables for w.map
        ),c; // the loop condition is on c
      )
        if(!n)return 1 // this is the for body
    }
  };
  for(l = a.length, r = [], k = 0; !G(l-k-1, k); k++);
  return y
}

परीक्षा

F=a=>{G=(v,i,u=v)=>{if(i--){for(;r[i]=--u;)if(G(u,i))return 1;}else for(w=[...r,n=l].map((x,i)=>a.slice(z,z=x-~i),z=0),y=w.join`;`;w.map(b=>[0,1].map(q=>(x=b[q*=~-b.length])&&(t[x]?([c,p]=t[x],n-=2,p?c.pop():c.shift(),q?b.pop():b.shift()):t[x]=[b,q])),c=0,t=[]),c;)if(!n)return 1};for(l=a.length,r=[],k=0;!G(l-k-1,k);k++);return y}

console.log=x=>O.textContent+=x+'\n'

TestData=[[1,1],[1,2,1,2],[1,3,2,4,3,2,1,4],[1,2,3,4,3,4,1,2],[1,1,2,2,3,3],[4,3,4,2,2,1,1,3]]

TestData.forEach(t=>console.log(t+' -> '+F(t)))

function RandomTest() {
  var l=I.value*2
  var a=[...Array(l)].map((_,i)=>1+i/2|0)
  a.map((v,i)=>a[a[i]=a[j=0|i+Math.random()*(a.length-i)],j]=v) // shuffle
  Q.textContent=a+''+'\n\n'+F(a).replace(/;/g, ';\n') // better readability
}
Base test
<pre id=O></pre>
Random test. Number of pairs: <input id=I value=15><button onclick="RandomTest()">-></button>
<pre id=Q></pre>

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