मैं अपनी सरणी को कितना कठिन बना सकता हूं?


30

चलो संख्याओं की एक सरणी को कुचलने की प्रक्रिया को परिभाषित करते हैं। एक क्रश में हमने दायें से बायें सरणी को पढ़ा। अगर एक बिंदु पर हम एक ही तत्व के दो का सामना करते हैं तो हम पहले एक को हटाते हैं और दूसरे को दोगुना करते हैं। उदाहरण के लिए यहाँ निम्नलिखित सरणी को कुचलने की प्रक्रिया है

[5,2,2,3]
 ^
[5,2,2,3]
   ^
[5,2,2,3]
     ^
[5,4,3]
   ^
[5,4,3]
     ^

एक ही तत्व, कई बार ध्वस्त हो जा सकती है, उदाहरण के लिए [1,1,2]हो जाता है[4] जब कुचला ।

जब हम उस सरणी को कुचलने की प्रक्रिया को नहीं बदलते हैं, तो हम किसी सरणी को अनचाहे कहेंगे। उदाहरण के लिए [1,2,3]अभी भी है[1,2,3] कुचले जाने के बाद ।

आपका काम एक सरणी लेना है और इसे अनचाहे बनाने के लिए आवश्यक क्रशों की संख्या निर्धारित करना है। आपको केवल 0 से 2 32 की सीमा पर पूर्णांक का समर्थन करने की आवश्यकता है -1

यह इसलिए उत्तर बाइट में कम बाइट के साथ बेहतर स्कोर किए जाएंगे।

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

[1] -> 0
[1,1] -> 1
[2,1,1] -> 2
[4,2,1,1] -> 3
[2,2,2,1,1] -> 3
[0,0,0,0] -> 1
[4,0,0,0,4] -> 1
[4,0,0,0,0,4] -> 1
[] -> 0

5
[1,1,2,4,8]1 या 4 वापस करना चाहिए ?
मॉसबॉयज

2
@ ThePirateBay ठीक है मैं इसे कम कर दूँगा। लेकिन मुझे लगता है कि रिकॉर्ड के लिए जावास्क्रिप्ट बल्कि गूंगा है जिस तरह से यह संभालता है।
गेहूं जादूगर

2
यदि आपने [१ १ १ २ २] को कुचलने की कोशिश की है, तो आप [२ १ २] को समाप्त कर देंगे यदि आप लिखित रूप में कल्पना का अनुसरण करते हैं, लेकिन यदि आप इसे और अधिक समझदारी से करते हैं तो आप [१ ४] के साथ समाप्त हो सकते हैं। [1 1 1 2 2] में क्या परिणाम होना चाहिए?
latias1290

4
@ latias1290। "एक क्रश में हम दायें से बायें सरणी को पढ़ते हैं।"

11
शायद यह सिर्फ मुझे है, लेकिन मुझे यह पता लगाने में एक सेकंड लगा कि 0,0,0,0केवल क्यों था 1। यह स्पष्ट रूप से कहीं उल्लेख करने के लिए एक विचार हो सकता है कि हम एक सरणी के माध्यम से लूप की संख्या की गिनती कर रहे हैं जिसे पूरी तरह से कुचलने के लिए हमें लूप करना है और नहीं , जैसा कि मैंने शुरू में सोचा था, कुल बार हम 2 नंबरों को एक साथ क्रश करते हैं।
शैगी

जवाबों:


12

x86 असेंबली (64-बिट), 66 65 बाइट्स

31 c0 57 59 56 51 56 5f 4d 31 c0 48 83 c6 08 48
83 e9 01 76 1b fc f2 48 a7 75 15 48 d1 67 f8 51
56 57 f3 48 a5 5f 5e 59 fd 48 a7 49 ff c0 eb e5
59 5e 4c 29 c1 48 ff c2 4d 85 c0 75 c7 48 ff c8
c3

स्ट्रिंग निर्देश सहायक थे। 64-बिट वातावरण में ऑफ-बाय-वन त्रुटियों के लिए सही होने के लिए नहीं था।

पूरी तरह से टिप्पणी स्रोत कोड:

.globl crush
crush:
/* return value */
xor %eax, %eax
/* save our length in rcx */
push %rdi
pop %rcx
pass:
/* save the start of the string and the length */
push %rsi
push %rcx
/* this is the loop */
/* first copy source to dest */
push %rsi
pop %rdi
/* and zero a variable to record the number of squashes we make this pass */
xor %r8, %r8
/* increment source, and decrement ecx */
add $8,%rsi
sub $1,%rcx
/* if ecx is zero or -1, we're done (we can't depend on the code to take care of this
automatically since dec will leave the zero flag set and cmpsq won't change it) */
jbe endpass
compare:
/* make sure we're going forward */
cld
/* compare our two values until we find two that are the same */
repne cmpsq
/* if we reach here, we either found the end of the string, or
we found two values that are the same. check the zero flag to
find out which */
jne endpass
/* okay, so we found two values that are the same. what we need
to do is double the previous value of the destination, and then
shift everything leftwards once */
shlq $1, -8(%rdi)
/* easiest way to shift leftwards is rep movsq, especially since
our ecx is already right. we just need to save it and the rsi/rdi */
push %rcx
push %rsi
push %rdi
rep movsq
pop %rdi
pop %rsi
pop %rcx
/* problem: edi and esi are now one farther than they should be,
since we can squash this dest with a different source. consequently
we need to put them back where they were. */
std
cmpsq
/* we don't need to put ecx back since the list is now one shorter
than it was. */
/* finally, mark that we made a squash */
inc %r8
/* okay, once we've reached this point, we should have:
 edi and esi: next two values to compare
 ecx: number of comparisons left
so we just jump back to our comparison operation */
jmp compare
endpass:
/* we reached the end of the string. retrieve our old ecx and esi */
pop %rcx
pop %rsi
/* rsi is accurate, but rcx is not. we need to subtract the number of squashes
that we made this pass. */
sub %r8, %rcx
/* record that we performed a pass */
inc %rax
/* if we did make any squashes, we need to perform another pass */
test %r8, %r8
jnz pass
/* we reached the end; we've made as many passes as we can.
decrement our pass counter since we counted one too many */
dec %rax
/* and finally return it */
ret

मैं 32-बिट में ऐसा करने की कोशिश कर सकता हूं, अगर केवल मनोरंजन के लिए, क्योंकि उन आरईएक्स उपसर्गों ने वास्तव में मुझे मार डाला।

संपादित करें: दर्ज करें,% rdx के साथ% rax के साथ, और दो cld के एक में ढहने के साथ एक बाइट को बदल दिया।


9

Jeebus! क्या आप पहले एक ट्रांसपिलर का उपयोग करते हैं और फिर इसे हाथ से संपादित करते हैं, या क्या आप वास्तव में शुरुआत से पायथ लिखते हैं?
ऑलिगॉफ्रेन

2
@oligofren उत्तरार्द्ध।
लीक नून

6

हास्केल , 66 बाइट्स

f(a:b:x)|a==b=f$a+a:x|1>0=a:f(b:x)
f x=x
g x|f x==x=0|1>0=1+g(f x)

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

व्याख्या

fएक फ़ंक्शन है जो किसी सूची को क्रश करता है। यह प्रश्न में क्रश के रूप में क्रश करता है। gएक ऐसा कार्य है जो क्रश की संख्या को गिनता है। यदि f x==x, g x=0अन्यथा g x=1+g(f x)


1
एक बाइट को बदलकर शेव g(f x)करेंg$f x
ApproachingDarknessFish

3
@ApproachingDarknessFish से काम नहीं चलता क्योंकि +इसकी उच्च प्राथमिकता है$
गेहूं जादूगर

आह, मेरी बुर। मजेदार यह कि मैंने पहले कभी भी उस त्रुटि में भाग नहीं लिया था।
ApproachingDarknessFish

5

पारदोक (v0.2.10), 16 बाइट्स (CP-1252)

{—1\ε=k+x}]»}IL(

इसे ऑनलाइन आज़माएं! / हेडर / फुटर के साथ जो सभी परीक्षण मामलों की जांच करते हैं

स्टैक पर एक सूची लेता है, और स्टैक पर एक संख्या में परिणाम होता है।

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

स्पष्टीकरण:

{            }I  .. Iterate this block: repeatedly apply it until a fixed
                 .. point is reached, and collect all intermediate results
 —1              ..   Push -1 (note that that's an em dash)
   \             ..   Swap it under the current list of numbers
    ε    }       ..   Execute this block for each element in the list:
     =           ..     Check if it's equal to the next element on the stack...
      k          ..       ... while keeping (i.e. not popping either of) them
       +         ..     Add the top two elements of the stack...
        x        ..       ... that many times (so, do add them if they were
                 ..       equal, and don't add them if they weren't)
          ]      ..   Collect all elements pushed inside the block that
                 ..     we're iterating into a list
           »     ..   Tail: take all but the first element (gets rid of the -1)
              L  .. Compute the length of the number of intermediate results
               ( .. Subtract 1

यदि हम यह मान सकते हैं कि इनपुट नॉन खाली था, तो हमें प्रहरी की आवश्यकता नहीं होगी और 2 बाइट शेव कर सकते हैं: {(\ε=k+x}]}IL(

एक और मजेदार तथ्य: हम केवल 2 बाइट्स खो देते हैं यदि हम खुद को केवल ASCII का उपयोग करने के लिए मजबूर करते हैं: {1m\{=k+x}e]1>}IL(


4

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

f=a=>a.length>eval("for(i=0;a[i]>-1;)a[i]==a[++i]&&a.splice(--i,2,a[i]*2);i")?1+f(a):0

अनगढ़ और समझाया हुआ

f=a=>                           // function taking array a
    a.length > eval("           // if a.length > the result of the following...
        for(i=0; a[i]>-1;)      //   loop from 0 until the current value is undefined (which is not > -1)
            a[i] == a[++i] &&   //     if the current value equals the next one...
                a.splice(--i,   //       splice the array at the first index of the pair...
                    2,          //       by replacing 2 items...
                    a[i]*2);    //       with the current item * 2
                                //       this also decrements the counter, which means the current value is now the next
    i")                         //   return the counter, which is new a.length
        ? 1+f(a)                // if that was true, the array was crushed. add 1 and recur with the new array
        : 0                     // otherwise just return 0

टेस्ट


a.length>nके रूप में ही है a[n]!=[]._। इस मामले में (चूंकि सरणी में सभी आइटम -1 से बड़ी संख्या हैं), यह उसी तरह है a[n]>-1। इसके अलावा, के a[i]==a[++i]&&xरूप में ही है a[i]-a[++i]||x
ल्यूक

मुझे लगता है कि 1/a[i]एक अन्य बाइट को बचाने के लिए भी काम करता है।
नील


3

ब्रेन-फ्लैक , 144 बाइट्स

([])({<{}>(<(([][()]){[{}]<({}[({})]<(())>){({}<{}>({})<>)((<>))}>{}{{}(<(({}){})>)}{}([][()])})>{()(<{}>)}{}{}<><([]){{}({}<>)<>([])}>{}<>)}<>)

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

व्याख्या

([])                                                                 Push stack height (starts main loop if list nonempty)
     {                                                       }       Do while the last iteration involved at least one crush:
      <{}>                                                           Remove crush indicator
           <(...)>                                                   Do a crush iteration
                  {()(<{}>)}                                         Evaluate to 1 if list was changed
                            {}{}                                     Remove zeroes
                                <>                        <>         On other stack:
                                  <([]){{}        ([])}>{}           Do while stack is nonempty:
                                          ({}<>)<>                   Move to first stack
          (                                                 )        Push 1 if crush worked, 0 otherwise
    (                                                         <>)    Push sum of results on other stack and implicitly print

क्रश फ़ंक्शन उन वस्तुओं के जोड़े की संख्या का मूल्यांकन करता है जिन्हें एक साथ कुचल दिया गया था:

([][()]){[{}]                                                            ([][()])}    Do while stack height isn't 1:
              ({}[({})]      )                                                        Calculate difference between top two elements
                       <(())>                                                         Push a 1 below difference
                              {                    }                                  If difference was nonzero (don't crush this pair)
                               ({}    ({})<>)                                         Reconstruct top element and place on other stack
                                  <{}>       ((<>))                                   Push zeros to exit this conditional and skip next
             <                                      >{}                               Evaluate as zero
                                                       {              }{}             If difference was zero (crush this pair):
                                                        {}                            Evaluate as previously pushed 1
                                                          (<(({}){})>)                Double top of stack

3

जावा 8, 120 बाइट्स

से एक लैम्ब्डा List<Long>के लिए Integer। इनपुट सूची को लागू करना चाहिए remove(int)(जैसे ArrayList)। को सौंपे Function<List<Long>, Integer>

l->{int c=-1,i,f=1;for(;f>0;c++)for(f=i=0;++i<l.size();)if(l.get(i)-l.get(i-1)==0)l.set(i-=f=1,2*l.remove(i));return c;}

यह ऑनलाइन की कोशिश करो

अघोषित लंबोदर

l -> {
    int
        c = -1,
        i,
        f = 1
    ;
    for (; f > 0; c++)
        for (f = i = 0; ++i < l.size(); )
            if (l.get(i) - l.get(i - 1) == 0)
                l.set(i -= f = 1, 2 * l.remove(i));
    return c;
}

cअब तक क्रशों की संख्या को गिना iजाता है, सूची में सूचकांक है, और fइंगित करता है कि क्या पुनरावृति समाप्त होने पर सूची को क्रश करना जारी रखना है या नहीं। छोरों के अंदर, प्रत्येक आसन्न जोड़ी की तुलना की जाती है। iबिना शर्त बढ़ा दिया जाता है, इसलिए यदि किसी तत्व को कुचलने से हटा दिया जाता है, iतो वेतन वृद्धि रद्द करने के लिए पहले डिक्रिप्ट किया जाता है। पूर्व तत्व को सूची से हटा दिया गया है।

स्वीकृतियाँ

  • ओलिवियर ग्रेजायर के लिए बगफिक्स धन्यवाद: बॉक्सिंग समानता परीक्षण

काम नहीं करता है जब लोंगो ने valueOfकैश नहीं मारा । उदाहरण: {128L, 128L}। इसकी वजह है l.get(i)==l.get(i-1), जिसे बदल दिया जाना चाहिए l.get(i).equals(l.get(i-1))
ओलिवियर ग्रेगोइरे

वाह, शर्मनाक ... सौभाग्य l.get(i)-l.get(i-1)==0से काम होगा। धन्यवाद!
जैकब


2

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

f=(a,j=m=0,t=[])=>a.map(e=>t[e==t[j-1]?(e*=m=2,j-1):j++]=e)&&m&&1+f(t)

स्पष्टीकरण:

f=(
  a,                  //the input
  j=m=0,              //j is the index into t; m starts out falsey
  t=[]                //t will hold the crushed array
)=>
  a.map(e=>           //for each element in the array
    t[e==t[j-1] ?     //if the element repeats:
      (e*=m=2,        //... multiply it by two, set m to truthy,
       j-1) :         //... and index the previous element of t.
      j++             //else append to t, and increment its index.
    ]=e               //set this index of t to the current value of e
  ) &&                //map is always truthy
  m &&                //if m is falsey, return 0
  1+f(t)              //else return 1 plus the recurse on t

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


1
हम्म .. ऐसा लगता है कि हम बहुत ही विचार के साथ आए थे :)। मेरा जवाब गोल्फ के बाद मुझे एहसास हुआ कि यह आपके समान है।

2

पायथन 2 , 112 110 108 107 105 100 बाइट्स

संपादित करें:or रिटर्न स्टेटमेंट में हटाकर 2 बाइट्स सहेजे गए

संपादित करें: सहेज कर 2 बाइट्सi के लिए दो तत्वों के दूसरे के सूचकांक के रूप में

संपादित करें: @ Mr.Xcoder को 1 बाइट धन्यवाद दिया गया

संपादित करें: @jferard के लिए 7 बाइट्स सहेजे गए

def f(x):
 i=e=1
 while x[i:]:
	if x[~-i]==x[i]:del x[i];i-=1;x[i]*=2;e=2
	i+=1
 return~-e and-~f(x)

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


2

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

f=([x,y,...a],b=[],c)=>1/x?x==y?f([x+y,...a],b,1):f([y,...a],[...b,x],c):c?1+f(b):0

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


1

जे, 54 बाइट्स

[:<:@#[:".@":@(,`(+:@[,}.@])@.({.@]=[))/^:a:@".@":_,|.

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

किसी भी तरह से मेरा सबसे अच्छा गोल्फ नहीं। निश्चित रूप से एक सूची को एक आइटम के साथ एक परमाणु में परिवर्तित करने का एक बेहतर तरीका होना चाहिए।

व्याख्या

crush =. ,`(+:@[ , }.@])@.({.@] = [)/
times =. <:@# [: ".@":@crush^:a:@".@": _ , |.

क्रश

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

,`(+:@[ , }.@])@.({.@] = [)/
                           /  Fold/reduce from the right
                  {.@] = [    Head of the running array equals the left argument?
   +:@[ ,                     If so, prepend double the argument to 
          }.@]                the array minus its head
,                             Else, prepend the left argument.

बार

यह काफी सीधा है: हमारे परिणाम को बदलने तक सरणी पर क्रश लागू करें, लेकिन कुछ मुद्दे हैं जिन्हें मुझे अनुमान से अधिक कोड में उस परिणाम से निपटना था।

सबसे पहले, जब क्रशिंग किसी एक तत्व को कम कर देता है, तो वह तत्व वास्तव में एक आइटम सूची में होता है (यानी यह गैर-परमाणु है), इसलिए फ़ंक्शन को फिर से लागू किया जाता है जिसके परिणामस्वरूप ओवरकाउंटिंग होती है। इसे ठीक करने के लिए, मैंने एक हैक का उपयोग किया जिसके साथ मैं एक तत्व सूची को एक परमाणु तक कम करने के लिए आया हूं जो कि है ".@":(स्ट्रिंग में कनवर्ट करें और फिर मूल्यांकन करें)।

दूसरी, crushखाली सूची पर त्रुटियां। मुझे लगता है कि आप यह परिभाषित कर सकते हैं कि किसी फ़ंक्शन को इन्सर्ट के साथ खाली इनपुट प्राप्त करने का व्यवहार कैसे करना चाहिए ( /), लेकिन मैं सरसरी नज़र के बाद कुछ भी नहीं पा सका, इसलिए मैं एक और वर्कअराउंड का उपयोग कर रहा हूं। यह वर्कअराउंड सूची के लिए प्रीफ़ेंड _(अनन्तता) है क्योंकि यह कभी भी सरणी को कुचलने ( _ > 2^64) की संख्या को प्रभावित नहीं करेगा । हालाँकि , एकल सूची में यह परिणाम होता है _जब खाली सूची दी जाती है, इसलिए हमें कुचलने से पहले एक परमाणु को फिर से बदलना होगा ।

<:@# [: ".@":@crush^:a:@".@": _ , |.
                                  |.  Reverse input
                              _ ,     Prepend infinity
                        ".@":         Convert single-element list to atom
              crush                   Crush the list and after
        ".@":                         Convert single-element list to atom 
                   ^:a:               until it converges, storing each 
                                      iteration in an array
<:@#                                  Length of the resulting list minus 1


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