আমি কীভাবে আমার অ্যারে পিষ্ট করতে পারি?


30

সংখ্যার অ্যারে ক্রাশ করার প্রক্রিয়াটি সংজ্ঞায়িত করা যাক। ক্রাশে আমরা অ্যারেটি বাম থেকে ডানে পড়ি। যদি এক পর্যায়ে আমরা পরপর একই দুটি উপাদানের মুখোমুখি হয়ে থাকি তবে আমরা প্রথমটি সরিয়ে ফেলি এবং দ্বিতীয়টি দ্বিগুণ করি। উদাহরণস্বরূপ, এখানে নিম্নলিখিত অ্যারে ক্রাশ করার প্রক্রিয়াটি রয়েছে

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

একই উপাদানটি একাধিকবার ভেঙে যেতে পারে, উদাহরণস্বরূপ, যখন পিষ্ট হয় [1,1,2]becomes[4]

সেই অ্যারে ক্রাশ করার প্রক্রিয়াটি যখন পরিবর্তন না করে তখন আমরা একটি অ্যারেটিকে অনিবার্য বলে ডাকব। উদাহরণ হিসেবে বলা যায় [1,2,3]এখনও [1,2,3]চূর্ণ হওয়ার পর।

আপনার কাজটি একটি অ্যারে নেওয়া এবং এটি অনিবার্য করতে প্রয়োজনীয় ক্রাশের সংখ্যা নির্ধারণ করা determine আপনার 0 থেকে 2 32 -1 এর মধ্যে কেবল পূর্ণসংখ্যার সমর্থন দরকার support

এটি তাই কম বাইট ভাল হওয়ার সাথে উত্তরগুলি বাইটে স্কোর করা হবে।

পরীক্ষার মামলা

[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
@ পাইরেট বে ঠিক আছে আমি এটিকে কম করব। তবে রেকর্ডটির জন্য আমি মনে করি জাভাস্ক্রিপ্ট যেভাবে এটি কীটগুলি পরিচালনা করে তাতে বোবা।
গম উইজার্ড

2
আপনি যদি [1 1 1 2] পিষ্ট করার চেষ্টা করে থাকেন তবে আপনি [2 1 2] এর সমাপ্তিটি লিখেছিলেন যদি আপনি সেই লিখিতভাবে ঠিক লিখিতভাবে অনুসরণ করেন তবে আপনি যদি আরও বুদ্ধিমানের সাথে এটি করেন তবে [1 4] দিয়ে শেষ হতে পারেন। [1 1 1 2] এর ফলাফল কী হওয়া উচিত?
latias1290

4
@ latias1290। "ক্রাশে আমরা অ্যারেটি বাম থেকে ডানে পড়ি" "

11
হতে পারে এটি কেবল আমি তবে এটি 0,0,0,0কেবল কেন ছিল তা নির্ধারণের জন্য আমাকে এক সেকেন্ড লাগল 1। এটি কোথাও স্পষ্টভাবে উল্লেখ করার একটি ধারণা হতে পারে যে আমরা এটির পুরোপুরি চূর্ণ করতে একটি অ্যারের মধ্য দিয়ে কত বার লুপ করতে হবে তার সংখ্যা গণনা করছি এবং না , যেমনটি আমি প্রথমদিকে ভেবেছিলাম, আমরা 2 টি সংখ্যা একসাথে পিষ্ট করেছিলাম তার মোট সংখ্যা।
শেগি

উত্তর:


12

x86 সমাবেশ (-৪-বিট), 65 66 65 বাইট 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-বিটে এটি করার চেষ্টা করতে পারি, যেহেতু এই REX উপসর্গগুলি আমাকে সত্যিই হত্যা করেছিল।

সম্পাদনা করুন: লডস্কিউ অ্যাডের সাথে প্রতিস্থাপন,% আরডিএক্সকে% র্যাক্স এবং দুটি সিএলটি একটিতে ভেঙে দিয়ে শেভ করা একটি বাইট বন্ধ করুন।


9

Jeebus! আপনি কি প্রথমে কোনও ট্রান্সপ্লার ব্যবহার করেন এবং তারপরে এটি হ্যান্ড-এডিট করেন, বা আপনি কি প্রথম থেকেই পাইথটি লিখেন?
অলিগোফ্রেন

2
উত্তর পরের দিন
লিকি নুন

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
অ্যাপ্রোচিংডার্কনেস

3
@ অ্যাপোরিচিং ডার্কনেস ফিশ যা কাজ করে না কারণ +তার চেয়ে বেশি অগ্রাধিকার রয়েছে$
গম উইজার্ড ২

আহ, আমার খারাপ। মজার যে আমি আগে কখনও ত্রুটি মধ্যে চালানো হয়নি।
ApproachingDarknessFish

5

প্যারাডোক (v0.2.10), 16 বাইট (সিপি-1252)

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

এটি অনলাইন চেষ্টা করুন! / শিরোনাম / পাদচরণ সহ যা সমস্ত পরীক্ষার কেস পরীক্ষা করে

স্ট্যাকের জন্য একটি তালিকা নেয় এবং স্ট্যাকের একটি সংখ্যাতে ফলাফল।

বেশ সরল বাস্তবায়ন, বেশ সৎ হতে। একটি সেন্ডিনেল -১ দিয়ে শুরু করে তালিকাটি ক্রাশ করে, তালিকার মধ্য দিয়ে লুপ করে প্রতিটি উপাদানকে পুশ করে এবং যদি তারা সমান হয় তবে এর নীচে উপাদানগুলিতে এটি যুক্ত করে। শেষে আমরা -1 কেটে ফেলেছি। আমরা কেবল সমান সংখ্যাকে একসাথে ক্রাশ করব এবং সমস্ত সমস্যার নম্বর ননজেটিভ, সুতরাং -1 সেন্ডিনেল ক্রাশিং প্রক্রিয়াটিকে প্রভাবিত করবে না। ক্রাশ কার্যকর করা সহ, এটির নির্দিষ্ট স্থানে পুনরাবৃত্তি গণনা করার বিষয় of

ব্যাখ্যা:

{            }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

জাভাস্ক্রিপ্ট (ES6), 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কাজ করবে। ধন্যবাদ!
Jakob


2

জাভাস্ক্রিপ্ট (ES6), 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 বাইট সংরক্ষণ করা হয়েছে

সম্পাদনা:i অ্যাক্সেসের জন্য দুটি উপাদানের দ্বিতীয়টির সূচক হিসাবে 2 বাইট সংরক্ষণ করা হয়েছে

সম্পাদনা: 1 বাইট ধন্যবাদ সংরক্ষণ করা হয়েছে @ মিস্টার এক্সকোডারকে

সম্পাদনা করুন: @ জেফেরার্ডকে ধন্যবাদ 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

জাভাস্ক্রিপ্ট (ES6), 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:@".@": _ , |.

পিষা

এটি একবারে একটি অ্যারে ক্রাশ করে। জে'র সন্নিবেশ ডান থেকে বামে কাজ করে (যেটি আমি আজ শিখেছি) তার বিপরীতে অ্যারে দেওয়া দরকার । এটি বিশেষত গুরুত্বপূর্ণ নয়, যেহেতু আমাদের আউটপুটের প্রয়োজন কেবল আমরা অ্যারে ক্রাশ করতে পারি তার সংখ্যা।

,`(+:@[ , }.@])@.({.@] = [)/
                           /  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


0

আর , 142 বাইট

f=function(l,r=l,k=0,T=1)"if"(sum(l|1)<2,k,{while(T<sum(r|1))"if"(r[T]-r[T+1],T<-T+1,{r<-r[-T]
r[T]<-2*r[T]})
"if"(all(r==l),k,f(r,r,k+1,1))})

ভয়াবহ, আমি নিশ্চিত যে আরও চতুর উপায় আছে।

আর পূর্ণসংখ্যা আসলে সবচেয়ে বেশি 2^31-1

এটি অনলাইন চেষ্টা করুন!

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.