Pergeseran array 2048-seperti


80

Asumsikan kita ingin menggeser array seperti yang dilakukan di game 2048 : jika kita memiliki dua elemen berurutan yang sama dalam array, gabungkan mereka menjadi dua kali elemen nilai. Shift harus mengembalikan array baru, di mana setiap pasangan elemen yang sama berturut-turut diganti dengan jumlah mereka, dan pasangan tidak boleh berpotongan. Pergeseran hanya dilakukan sekali, jadi kita tidak perlu menggabungkan nilai yang dihasilkan lagi. Perhatikan bahwa jika kita memiliki 3 elemen yang sama berturut-turut, kita harus menjumlahkan yang paling kanan, jadi misalnya, [2, 2, 2]harus menjadi [2, 4], bukan [4, 2].

Tugasnya adalah menulis fungsi terpendek yang mengambil array dan mengembalikan array yang digeser.

Anda dapat mengasumsikan bahwa semua bilangan bulat akan benar-benar positif.

Contoh:

[] -> []
[2, 2, 4, 4] -> [4, 8]
[2, 2, 2, 4, 4, 8] -> [2, 4, 8, 8]
[2, 2, 2, 2] -> [4, 4]
[4, 4, 2, 8, 8, 2] -> [8, 2, 16, 2]
[1024, 1024, 512, 512, 256, 256] -> [2048, 1024, 512]
[3, 3, 3, 1, 1, 7, 5, 5, 5, 5] -> [3, 6, 2, 7, 10, 10]

Saya juga sangat tertarik dengan solusi menggunakan :)


11
Ini adalah tantangan pertama yang sangat bagus. Selamat datang di situs ini!
DJMcMayhem

1
Input belum tentu diurutkan dan jumlahnya lebih besar dari nol, itulah satu-satunya batasan angka. Kami mungkin membiarkan nilai terbesar sesuai dengan batas int32 standar saya pikir. Array kosong memberikan array kosong sebagai hasilnya. Terima kasih atas partisipasinya, hargai itu :)
greenwolf

3
Bagi mereka yang masih memilih untuk menutup sebagai tidak jelas, tantangan pada dasarnya bermuara pada ini: Asumsikan Anda memiliki array bilangan bulat positif. Berjalanlah dari ujung ke ujung. Jika elemen saat ini sama dengan yang berikutnya, ganti dengan jumlah keduanya dan pindah ke elemen setelah penggantian, kemudian lakukan pemeriksaan ini lagi untuk elemen itu dan berikutnya. Ulangi sampai awal array tercapai.
user2428118

1
@Titus "Perhatikan bahwa jika kita memiliki 3 elemen yang sama berturut-turut, kita harus menjumlahkan yang paling kanan, jadi misalnya, [2, 2, 2] harus menjadi [2, 4], bukan [4, 2]."
Martin Ender

1
Putusan tentang array kosong sangat disayangkan; itu telah membatalkan beberapa jawaban, termasuk jawaban saya.
Dennis

Jawaban:


21

Jelly , 10 9 8 byte

Œg+2/€UF

TryItOnline atau jalankan semua test case

Bagaimana?

Œg+2/€UF - Main link: a                 e.g. [2,2,2,4,4,8]
Œg       - group runs of equal elements      [[2,2,2],[4,4],[8]]
   2/€   - pairwise reduce for each with
  +      -     addition                      [[4,2],[8],[8]]
      U  - reverse (vectorises)              [[2,4],[8],[8]]
       F - flatten list                      [2,4,8,8]

19

Haskell, 47 57 50 byte

e#l|a:b<-l,e==a= -2*a:b|1<2=e:l
map abs.foldr(#)[]

Penggunaan reduce(atau foldseperti yang disebut dalam Haskell, ini lipatan kanan foldr). Contoh penggunaan: map abs.foldr(#)[] $ [2,2,2,4,4,8]-> [2,4,8,8].

Edit: +10 byte untuk membuatnya berfungsi untuk array yang tidak disortir juga. Angka yang digabungkan dimasukkan sebagai nilai negatif untuk mencegah penggabungan kedua. Mereka dikoreksi oleh final map abs.


Trik dengan negatif sangat bagus!
xnor

14

Brain-Flak , 158 96

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

Cobalah online!

Penjelasan:

1 Membalikkan daftar (memindahkan semuanya ke tumpukan lain, tetapi itu tidak masalah)

{({}<>)<>}<>
{        }   #keep moving numbers until you hit the 0s from an empty stack
 ({}<>)      #pop a number and push it on the other stack
       <>    #go back to the original stack
          <> #after everything has moved, switch stacks

2 Lakukan langkah 3-6 hingga tidak ada yang tersisa di tumpukan ini:

{                                                                                         }

3 Gandakan dua elemen teratas (2 3 -> 2 3 2 3)

(({}<>)<><(({})<<>({}<>)>)>)

(({}<>)<>                   #put the top number on the other stack and back on the very top
         <(({})             #put the next number on top after:
               <<>({}<>)>   #copying the original top number back to the first stack
                         )>)

4 Letakkan 1 di atas jika dua teratas sama, 0 sebaliknya (dari wiki)

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

5 Jika dua teratas sama (tidak nol di atas) tambahkan dua berikutnya dan dorong hasilnya

{{}(<({}{})>)}{}
{            }   #skip this if there is a 0 on top
 {}              #pop the 1
   (<      >)    #push a 0 after:
     ({}{})      #pop 2 numbers, add them together and push them back on 
              {} #pop off the 0

6 Pindahkan elemen atas ke tumpukan lainnya

({}<>)<>

7 Beralih ke tumpukan lain dan cetak secara implisit

<>

tolong tambahkan koma setelah nama bahasa, kalau tidak rusak leaderboard ty: P
ASCII-hanya

9

PHP, 116 Bytes

<?$r=[];for($c=count($a=$_GET[a]);$c-=$x;)array_unshift($r,(1+($x=$a[--$c]==$a[$c-1]))*$a[$c]);echo json_encode($r);

atau

<?$r=[];for($c=count($a=$_GET[a]);$c--;)$r[]=$a[$c]==$a[$c-1]?2*$a[$c--]:$a[$c];echo json_encode(array_reverse($r));

-4 Bytes jika outputnya bisa berupa array print_rbukan 'json_encode`

176 Bytes untuk menyelesaikan ini dengan Regex

echo preg_replace_callback("#(\d+)(,\\1)+#",function($m){if(($c=substr_count($m[0],$m[1]))%2)$r=$m[1];$r.=str_repeat(",".$m[1]*2,$c/2);return trim($r,",");},join(",",$_GET[a]));

1
Anda tidak dapat menggunakan pengurutan karena hasilnya tidak selalu diurutkan: [4, 4, 2, 8, 8, 2] -> [8, 2, 16, 2]
Crypto

@Crypto Anda benar setelah kasus uji baru ditambahkan. Sebelum penggunaan semacam itu baik
Jörg Hülsermann

for($i=count($a=$argv);--$i;)$b[]=($a[$i]==$a[$i-1])?2*$a[$i--]:$a[$i];print_r(array_reverse($b));ide yang sama tetapi lebih pendek
Crypto

@Crypto Saya tidak yakin tentang output sebagai representasi string atau array. untuk ruang ujian []saya butuh $r=[];Terima kasih atas bantuan Anda
Jörg Hülsermann


8

Retina , 32

\d+
$*
r`\b\1 (1+)\b
$1$1
1+
$.&

ron line 3 mengaktifkan pencocokan regex kanan-ke-kiri. Dan ini berarti bahwa \1referensi harus ada sebelum (1+)kelompok penangkap yang dirujuk.

Cobalah online.


Bagus .. Pilihan kanan-ke-kiri untuk mencocokkan cukup berguna! Apakah itu bagian dari .Net regex atau fitur Retina?
Dada

Saya baru saja akan memposting tambang saya di 26, menggunakan pemisahan-linefeed sebagai format input: retina.tryitonline.net/... penghematan utama berasal dari itu dan menggunakan transliterasi untuk menyingkirkan substitusi kedua.
Martin Ender

@Dada Ini adalah fitur .NET (dan digunakan di bawah tenda untuk memungkinkan tampilan sewenang-wenang di belakang). Retina belum memiliki fitur regex unik (meskipun memiliki beberapa fitur substitusi unik).
Martin Ender

1
@ MartinEnder Ok terima kasih! .NET regex benar-benar hebat! cemburu perl coder terlihat
Dada

@ MartinEnder I solusi Anda cukup berbeda untuk menjamin jawaban lain
Digital Trauma

8

Perl, 41 byte

Termasuk +1 untuk -p

Berikan urutan input pada STDIN:

shift2048.pl <<< "2 2 2 4 4 8 2"

shift2048.pl:

#!/usr/bin/perl -p
s/.*\K\b(\d+) \1\b/2*$1.A/e&&redo;y/A//d

8

Python, 61 byte

def f(l):b=l[-2:-1]==l[-1:];return l and f(l[:~b])+[l[-1]<<b]

Boolean bmemeriksa apakah dua elemen terakhir harus runtuh dengan memeriksa bahwa mereka sama dengan cara yang aman untuk daftar panjang 1 atau 0. Elemen terakhir jika kemudian ditambahkan dengan pengali 1untuk sama atau 2untuk tidak sama. Itu ditambahkan ke hasil rekursif dalam daftar dengan banyak elemen yang dipotong pada akhirnya. Terima kasih kepada Dennis untuk 1 byte!


[l[-1]<<b]menghemat satu byte.
Dennis

l[-2:-1]adalah[l[-2]]
mbomb007

2
Saya membutuhkannya untuk daftar ukuran 0 dan 1.
xnor

7

Perl, 43 + 1 ( -p) = 44 byte

Ton Hospel datang dengan 41 byte jawaban , lihatlah!

-4 Terima kasih kepada @Ton Hospel!

Sunting : ditambahkan \b, karena tanpa itu gagal pada input seperti 24 4di mana output seharusnya 28.

$_=reverse reverse=~s/(\b\d+) \1\b/$1*2/rge

Jalankan dengan -pbendera:

perl -pe '$_=reverse reverse=~s/(\b\d+) \1\b/$1*2/rge' <<< "2 2 2 4 4"


Saya tidak melihat cara lain selain menggunakan reversedua kali lipat kanan (seperti yang s/(\d+) \1/$1*2/geakan kiri-lipat, yaitu 2 2 2akan menjadi 4 2bukan 2 4). Jadi 14 byte hilang berkat reverse... Masih saya pikir harus ada cara lain (lebih baik) (ini perl!), Beri tahu saya jika Anda menemukannya!


reverse reversesepertinya agak panjang. Saya bukan ahli dalam Perl, tetapi apakah ada cara Anda bisa membuat jalan pintas ke reverse(jika tidak ada yang lain, [ab] menggunakan eval)?
Cyoce

Sexeger yang bagus. Perhatikan Anda bisa ($_)
mengabaikan

@TonHospel terima kasih. Memang, dokumen reversesepertinya reversetidak dapat dipanggil tanpa argumen (contohnya menunjukkan, tapi hanya ada satu prototipe :) reverse LIST, jadi saya lupa tentang $_menjadi argumen default;)
Dada

A LISTbisa kosong ...
Ton Hospel

@TonHospel memang, tetapi biasanya ketika operator menggunakan $_sebagai argumen default, doc menentukan prototipe tanpa parameter (suka printatau lenght...). Atau mungkin itu hanya kesan salah yang saya miliki.
Dada

7

JavaScript (ES6), 68 byte

f=a=>a.reduceRight((p,c)=>(t=p[0],p.splice(0,c==t,c==t?c+t:c),p),[])
    
console.log([
  [],
  [2, 2, 4, 4],
  [2, 2, 2, 4, 4, 8],
  [2, 2, 2, 2],
  [4, 4, 2, 8, 8, 2],
  [1024, 1024, 512, 512, 256, 256],
  [3, 3, 3, 1, 1, 7, 5, 5, 5, 5],
].map(f))


2
Tidak buruk, tetapi menurut cuplikan yang dieksekusi: [1024, 1024, 512, 512, 256, 256]apakah diselesaikan sebagai [2048, 512, 1024]dan tidak [2048, 1024, 512]...?
WallyWest

7

Perl 5.10, 61 50 byte ( 49 +1 untuk bendera)

Terima kasih kepada Ton Hospel untuk menghemat 11 byte!

Solusi bebas-regex, dengan -abendera:

@a=($F[-1]-$b?$b:2*pop@F,@a)while$b=pop@F;say"@a"

Coba di sini!


Metode alternatif yang bagus. Sayang sekali array hampir selalu kalah dari string dalam perl. Namun, Anda bisa sedikit lebih dekat dengan memasukkan kode Anda ke @a=($F[-1]-$b?$b:2*pop@F,@a)while$b=pop@F;say"@a"(50 byte)
Ton Hospel

@TonHospel Memang, saya cenderung menghindari solusi berbasis string (hanya untuk menunjukkan bahwa Perl dapat melakukan lebih dari itu!). Saya tidak bermain untuk menang: D Terima kasih atas tips golfnya!
Paul Picard

7

JavaScript (ES6), 68 65 58 57 65 64 byte

Disimpan 1 byte berkat @ l4m2

Diperbaiki untuk array yang tidak disortir sekarang karena telah diklarifikasi bahwa input seperti itu diharapkan.

f=(a,l=[],m)=>(x=a.pop())*!m-l?f(a,x).concat(l):x?f(a,2*x,1):[l]

console.log(f([2, 2, 4, 4]));
console.log(f([2, 2, 2, 4, 4, 8]));
console.log(f([2, 2, 2, 2]));
console.log(f([4, 2, 2]));


1
Saya akan menyarankan hasil edit yang baru saja Anda buat :)
ETHproduksi

a=>(a.reverse()+'').replace(/(.),\1/g,(c,i)=>i*2).split`,`.reverse()?
14m2

@ l4m2 Itu berfungsi untuk input satu digit, tetapi akan gagal [1024, 1024, 512, 512, 256, 256](saya pikir case test ini mungkin telah ditambahkan kemudian).
Arnauld

@Arnauld Yah, milikmu juga gagal ...
l4m2

f=(a,l=[],m)=>(x=a.pop())*!m-l?f(a,x).concat(l):x?f(a,2*x,1):[l]?
14m2

6

05AB1E , 26 byte

D¥__X¸«DgL*ê¥X¸«£vy2ôO})í˜

Cobalah online!

Langkah umum

  1. Kurangi dengan mengurangi untuk menemukan di mana elemen berurutan berbeda
  2. Kurangi dengan mengurangi indeks tempat-tempat itu untuk menemukan panjang elemen yang berurutan
  3. Membagi input menjadi bongkahan dengan panjang tersebut
  4. Bagi potongan menjadi berpasangan
  5. Jumlahkan setiap pasangan
  6. Membalikkan setiap potongan yang dijumlahkan
  7. Ratakan ke daftar 1 dimensi

5

Mathematica, 53 byte

Join@@(Reverse[Plus@@@#~Partition~UpTo@2]&/@Split@#)&

Penjelasan

Split@#

Membagi input menjadi sub daftar yang terdiri dari run dari elemen yang identik. yaitu {2, 2, 2, 4, 8, 8}menjadi {{2, 2, 2}, {4}, {8, 8}}.

#~Partition~UpTo@2

Partisi masing-masing sublist menjadi panjang partisi paling banyak 2. yaitu {{2, 2, 2}, {4}, {8, 8}}menjadi {{{2, 2}, {2}}, {{4}}, {{8, 8}}}.

Plus@@@

Totalkan setiap partisi. yaitu {{{2, 2}, {2}}, {{4}}, {{8, 8}}}menjadi {{4, 2}, {4}, {16}}.

Reverse

Membalikkan hasil karena Partitionperintah Mathematica bergerak dari kiri ke kanan, tetapi kami ingin partisi berada di arah lain. yaitu {{4, 2}, {4}, {16}}menjadi {{2, 4}, {4}, {16}}.

Join@@

Ratakan hasilnya. yaitu {{2, 4}, {4}, {16}}menjadi {2, 4, 4, 16}.


Hai JHM! Terima kasih atas jawabannya. Saya tidak mengerti Mathematica dengan baik, jadi bisakah Anda menambahkan sedikit penjelasan tentang apa yang terjadi?
isaacg

Plus@@@adalah Tr/@dan saya pikir Anda dapat menghindari tanda kurung dan Join@@jika Anda menggunakan ##&@@pada hasil Reverse(belum mencobanya).
Martin Ender

5

Java 7, 133 byte

Object f(java.util.ArrayList<Long>a){for(int i=a.size();i-->1;)if(a.get(i)==a.get(i-1)){a.remove(i--);a.set(i,a.get(i)*2);}return a;}

Input adalah ArrayList, dan itu hanya loop mundur, menghapus dan menggandakan jika diperlukan.

Object f(java.util.ArrayList<Long>a){
    for(int i=a.size();i-->1;)
        if(a.get(i)==a.get(i-1)){
            a.remove(i--);
            a.set(i,a.get(i)*2);
        }
    return a;
}

Anda membandingkan Longreferensi pada baris 3 dengan ==. Pertimbangkan a.get(i)-a.get(i-1)==0.
Jakob

4

Perl, 37 byte

Termasuk +4 untuk -0n

Jalankan dengan input sebagai baris terpisah pada STDIN:

perl -M5.010 shift2048.pl
2
2
2
4
4
8
2
^D

shift2048.pl:

#!/usr/bin/perl -0n
s/\b(\d+
)(\1|)$//&&do$0|say$1+$2

4

Haskell, 56 byte

g(a:b:r)|a==b=a+b:g r|l<-b:r=a:g l
g x=x
r=reverse
r.g.r

4

PHP, 86 100 99 94 byte

for($r=[];$v=+($p=array_pop)($a=&$argv);)array_unshift($r,end($a)-$v?$v:2*$p($a));print_r($r);

membutuhkan PHP 7.0; mengambil nilai dari argumen baris perintah.

Jalankan dengan -nratau coba online .


2
[2, 2, 2] mengembalikan [4,2] alih-alih [2,4]
Crypto

for($r=[];$v=($p=array_pop)($a=&$_GET[a]);)array_unshift($r,end($a)-$v?$v:2*$p($a));print_r($r);lebih pendek 1 Byte
Jörg Hülsermann

3

Julia 205 byte

t(x)=Val{x}
s(x)=t(x)()
f^::t(1)=f
^{y}(f,::t(y))=x->f(((f^s(y-1))(x)))
g()=[]
g{a}(::t(a))=[a]
g{a}(::t(a),B...)=[a;g(B...)]
g{a}(::t(a),::t(a),B...)=[2a;g(B...)]
K(A)=g(s.(A)...)
H(A)=(K^s(length(A)))(A)

Fungsi yang akan dipanggil adalah H

misalnya H([1,2,2,4,8,2,])

Ini sama sekali bukan cara terpendek dalam hal ini di julia. Tapi itu sangat keren, saya ingin membagikannya.

  • t(a) adalah tipe-nilai, mewakili nilai (a).
  • s(a) adalah turunan dari tipe nilai itu
  • gadalah fungsi yang mengirimkan nilai perbedaan (menggunakan tipe nilai) dan jumlah parameternya. Dan itu keren
  • Khanya membungkus gsehingga

Bagian ekstra keren:

f^::t(1)=f
^{y}(f,::t(y))=x->f(((f^s(y-1))(x)))

Ini mendefinisikan ^operator untuk diterapkan ke fungsi. Sehingga K^s(2)(X)sama seperti K(K(X)) jadi Hhanya menelepon Kpada Ksekelompok kali - cukup kali untuk tentu runtuh setiap kasus bersarang

Ini bisa dilakukan jauh lebih singkat, tetapi cara ini sangat menyenangkan.


3

PowerShell v2 +, 81 byte

param($n)($b=$n[$n.count..0]-join','-replace'(\d+),\1','($1*2)'|iex)[$b.count..0]

Mengambil input sebagai array eksplisit $n, membalikkannya $n[$n.count..0], -joins elemen bersama dengan koma, kemudian regex -replacepasangan digit yang cocok dengan elemen pertama, a *2, dan dikelilingi dalam parens. Pipa yang menghasilkan (yang untuk input @(2,2,4,4)akan terlihat seperti (4*2),(2*2)) ke iex(kependekan Invoke-Expressiondan mirip dengan eval), yang mengubah perkalian menjadi angka aktual. Menyimpan array yang dihasilkan ke dalam $b, merangkum bahwa dalam parens untuk meletakkannya di pipa, kemudian membalikkan $bdengan [$b.count..0]. Meninggalkan elemen yang dihasilkan pada pipa, dan output tersirat.


Uji Kasus

NB - Dalam PowerShell, konsep "mengembalikan" sebuah array kosong tidak ada artinya - itu dikonversi menjadi$nullbegitu meninggalkan ruang lingkup - dan itu sama dengan mengembalikan apa-apa, yang dilakukan di sini pada contoh pertama (setelah beberapa kesalahan verbose jahat). Selain itu, output di sini dipisahkan dengan ruang, karena itulah pemisah default untuk array yang diketikkan.

PS C:\Tools\Scripts\golfing> @(),@(2,2,4,4),@(2,2,2,4,4,8),@(2,2,2,2),@(4,4,2,8,8,2),@(1024,1024,512,512,256,256),@(3,3,3,1,1,7,5,5,5,5)|%{"$_ --> "+(.\2048-like-array-shift.ps1 $_)}
Invoke-Expression : Cannot bind argument to parameter 'Command' because it is an empty string.
At C:\Tools\Scripts\golfing\2048-like-array-shift.ps1:7 char:67
+   param($n)($b=$n[$n.count..0]-join','-replace'(\d+),\1','($1*2)'|iex)[$b.count. ...
+                                                                   ~~~
    + CategoryInfo          : InvalidData: (:String) [Invoke-Expression], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.InvokeExpressionCommand

Cannot index into a null array.
At C:\Tools\Scripts\golfing\2048-like-array-shift.ps1:7 char:13
+   param($n)($b=$n[$n.count..0]-join','-replace'(\d+),\1','($1*2)'|iex)[$b.count. ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

 --> 
2 2 4 4 --> 4 8
2 2 2 4 4 8 --> 2 4 8 8
2 2 2 2 --> 4 4
4 4 2 8 8 2 --> 8 2 16 2
1024 1024 512 512 256 256 --> 2048 1024 512
3 3 3 1 1 7 5 5 5 5 --> 3 6 2 7 10 10

3

Javascript - 103 byte

v=a=>{l=a.length-1;for(i=0;i<l;i++)a[l-i]==a[l-1-i]?(a[l-i-1]=a[l-i]*2,a.splice(l-i,1)):a=a;return a}

Disimpan 16 byte berkat tips @ MayorMonty di halaman ini
Alexis_A

Ini tidak bekerja Pengujian dengan [2,2,4,4]hasil [2,2,4,4].
Conor O'Brien

1
ya. Node v6.2.1
Conor O'Brien

Buruk saya .. Saya menjalankannya dengan kode JS lain di file yang sama dan variabel global ikut campur.
Alexis_A

3

Brain-Flak , 60 byte

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

Cobalah online!

Penjelasan:

{({}<>)<>}<>   Reverse stack

{   While input exists
  (
    ({}<>)   Push copy of last element to the other stack
    <>[({})] And subtract a copy of the next element
  )   Push the difference
  {   If the difference is not 0
    ((<{}>)) Push two zeroes
  }{}  Pop a zero
  {   If the next element is not zero, i.e the identical element
    ({}<>{})  Add the element to the copy of the previous element
    (<>)      Push a zero
  }{}    Pop the zero
}<>  End loop and switch to output stack


2

Julia, 73 82 Bytes

f(l)=l==[]?[]:foldr((x,y)->y[]==x?vcat(2x,y[2:end]):vcat(x,y),[l[end]],l[1:end-1])

Gunakan lipatan kanan untuk membuat daftar dari belakang ke depan (orang juga dapat menggunakan lipatan kiri dan membalikkan daftar di awal dan akhir).

Jika kepala daftar saat ini tidak sama dengan elemen berikutnya untuk ditambahkan sebelumnya, maka tambahkan saja.

Lain menghapus kepala daftar (terdengar agak kejam) dan menambahkan elemen kali 2.

Contoh

f([3,3,3,1,1,7,5,5,5,5]) 
returns a new list:
[3,6,2,7,10,10]

2

Racket 166 byte

(λ(l)(let g((l(reverse l))(o '()))(cond[(null? l)o][(=(length l)1)(cons(car l)o)]
[(=(car l)(second l))(g(drop l 2)(cons(* 2(car l))o))][(g(cdr l)(cons(car l)o))])))

Tidak Terkumpul:

(define f
  (λ (lst)
    (let loop ((lst (reverse lst)) 
               (nl '()))
      (cond                            ; conditions: 
        [(null? lst)                   ; original list empty, return new list;
               nl]
        [(= (length lst) 1)            ; single item left, add it to new list
              (cons (first lst) nl)]
        [(= (first lst) (second lst))  ; first & second items equal, add double to new list
              (loop (drop lst 2) 
                    (cons (* 2 (first lst)) nl))]
        [else                          ; else just move first item to new list
              (loop (drop lst 1) 
                    (cons (first lst) nl))]  
        ))))

Pengujian:

(f '[])
(f '[2 2 4 4]) 
(f '[2 2 2 4 4 8]) 
(f '[2 2 2 2]) 
(f '[4 4 2 8 8 2])
(f '[1024 1024 512 512 256 256]) 
(f '[3 3 3 1 1 7 5 5 5 5])
(f '[3 3 3 1 1 7 5 5 5 5 5])

Keluaran:

'()
'(4 8)
'(2 4 8 8)
'(4 4)
'(8 2 16 2)
'(2048 1024 512)
'(3 6 2 7 10 10)
'(3 6 2 7 5 10 10)

1

Japt , 12 byte

ò¦ ®ò2n)mxÃc

Cobalah online!

Dibongkar & Cara kerjanya

Uò!= mZ{Zò2n)mx} c

Uò!=    Partition the input array where two adjacent values are different
        i.e. Split into arrays of equal values
mZ{     Map the following function...
Zò2n)     Split into arrays of length 2, counting from the end
          e.g. [2,2,2,2,2] => [[2], [2,2], [2,2]]
mx        Map `Array.sum` over it
}
c       Flatten the result

Dapatkan beberapa ide dari solusi Jelly Jonathan Allan's .


0

Mathematica, 51 byte

Abs[#//.{Longest@a___,x_/;x>0,x_,b___}:>{a,-2x,b}]&

{Longest@a___,x_/;x>0,x_,b___}mencocokkan daftar yang berisi dua angka positif identik berurutan dan mengubah dua angka menjadi -2x. Longestmemaksa pertandingan terjadi selambat mungkin.

Proses ini digambarkan langkah demi langkah:

   {3, 3, 3, 1, 1, 7, 5, 5, 5, 5}
-> {3, 3, 3, 1, 1, 7, 5, 5, -10}
-> {3, 3, 3, 1, 1, 7, -10, -10}
-> {3, 3, 3, -2, 7, -10, -10}
-> {3, -6, -2, 7, -10, -10}
-> {3, 6, 2, 7, 10, 10}

0

Vim, 28 byte

G@='?\v(\d+)\n\1<C-@>DJ@"<C-A>-@=<C-@>'<CR>

Makro yang regex mencari mundur untuk pencocokan angka berurutan, dan menambahkannya bersama-sama.

Array input harus satu angka per baris. Format ini menyelamatkan saya pukulan, yang bagus, tetapi alasan sebenarnya adalah untuk bekerja di sekitar pertandingan regex yang tumpang tindih. Diberikan string 222, jika Anda /22hanya akan cocok dengan pasangan pertama, bukan pasangan kedua yang tumpang tindih. Aturan tumpang tindih berbeda ketika kedua pasangan mulai pada garis yang berbeda. Dalam tantangan ini [2, 2, 2]menjadi [2, 4], jadi mencocokkan pasangan yang tumpang tindih sangat penting.

CATATAN: Tantangan hanya meminta satu pass. Untuk alasan itu, Anda harus memilikinya :set nowrapscan. Dengan :set wrapscansaya bisa membuat versi yang menyelesaikan pekerjaan pada beberapa lintasan, meskipun solusi ini sebagai tertulis tidak akan selalu melakukan itu.

  • <C-@>: Biasanya, di baris perintah, untuk mengetik literal <CR>tanpa menjalankan perintah, Anda harus menghindarinya <C-V>. Tapi Anda bisa mengetik tidak <C-@>terhapus dan itu akan diperlakukan sebagai <C-J>/ <NL>, yang akan seperti <CR>ketika Anda menjalankan makro tetapi tidak saat Anda mengetik. Coba baca :help NL-used-for-Nul.
  • @=: Saya tidak bisa menggunakan makro yang direkam dengan mudah kali ini karena ada kemungkinan input mungkin tidak memiliki pasangan yang cocok. Jika itu terjadi saat menjalankan makro, pencarian yang gagal akan gagal makro. Tetapi jika itu terjadi selama pass perekaman (implisit pertama), sisa perintah mode normal akan berjalan, merusak file. Kelemahannya @=adalah saya kehilangan satu byte pada panggilan rekursif; terkadang Anda dapat menggunakan @@sebagai panggilan rekursif, tetapi itu akan berjalan @"dari 4 byte sebelumnya dalam kasus ini.
  • DJ@"<C-A>-: DJmenghapus baris dan memasukkan nomor (tidak ada baris baru) dalam register, jadi saya dapat menjalankannya sebagai makro untuk argumen nomor <C-A>. Saya harus -sesudahnya jadi saya tidak mendapatkan pertandingan kedua dalam kasus seperti [4, 2, 2].

0

Perl6, 92 byte

{my @b;loop ($_=@^a-1;$_>=0;--$_) {@b.unshift($_&&@a[$_]==@a[$_-1]??2*@a[$_--]!!@a[$_])};@b}

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.