2048 benzeri dizi kayması


80

2048 oyunda olduğu gibi bir diziyi değiştirmek istediğimizi varsayalım : dizide birbirini takip eden iki eşit eleman varsa, bunları değer öğesinin iki katıyla birleştirin. Shift, her ardışık eşit eleman çiftinin toplamı ile değiştirildiği yeni bir dizi döndürmeli ve çiftler kesişmemelidir. Vites değiştirme yalnızca bir kez yapılır, bu nedenle sonuçta elde edilen değerleri tekrar birleştirmemize gerek yoktur. Biz 3 ardışık eşit unsurları varsa, biz örneğin, bu yüzden, en sağdaki olanları özetlemek zorunda dikkat edin [2, 2, 2]haline gelmelidir [2, 4]değil [4, 2].

Görev, bir dizi alan ve değişen bir dizi döndüren en kısa işlevi yazmaktır.

Tüm tam sayıların kesinlikle olumlu olacağını varsayabilirsiniz.

Örnekler:

[] -> []
[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]

Ayrıca azaltmak kullanarak çözümle de ilgileniyorum :)


11
Bu çok güzel bir ilk meydan okuma. Siteye Hoşgeldiniz!
DJMcMayhem

1
Girdi mutlaka sıralanmamıştır ve sayılar sıfırdan büyüktür, bu sayılardaki tek kısıtlamadır. Sanırım en büyük değerin standart int32 sınırlarına sığmasına izin verebiliriz. Boş dizi, sonuç olarak boş dizi verir.
Katıldığınız için

3
Belirsiz olarak kapanmaya oy verenler için, meydan okuma esasen buna bağlıyor: Bir dizi pozitif tamsayıya sahip olduğunuzu varsayalım. Başından sonuna kadar yürüyün. Geçerli eleman bir sonrakine eşitse, her ikisinin toplamı ile değiştirin ve değiştirmeden sonra elemana geçin , ardından bu kontrolü o eleman ve sonraki için tekrar yapın. Dizinin başına ulaşılana kadar tekrarlayın.
user2428118

1
@Titus "Eğer arka arkaya 3 eşit elemanımız varsa, en yakınlarını toplamamız gerektiğine dikkat edin, bu nedenle, [2, 2, 2] [4, 2] değil [2, 4] olmalı."
Martin Ender

1
Boş dizilerin kararı talihsizdir; benimki de dahil olmak üzere birkaç cevabı geçersiz kıldı.
Dennis,

Yanıtlar:



19

Haskell, 47 57 50 bayt

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

Kullanım Alanları reduce(veya foldHaskell'da denildiği gibi, burada bir sağa foldr). Kullanım örneği: map abs.foldr(#)[] $ [2,2,2,4,4,8]-> [2,4,8,8].

Düzenleme: Sıralanmamış dizilerde çalışması için +10 bayt. İkinci bir birleşmeyi önlemek için birleştirilmiş sayılar negatif değerler olarak eklenir. Bir final tarafından düzeltilir map abs.


Olumsuz hileci gerçekten güzel!
xnor

14

Brain-Flak , 158 96

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

Çevrimiçi deneyin!

Açıklama:

1 Listeyi tersine çevirin (her şeyi diğer yığına taşımak, ancak bu önemli değil)

{({}<>)<>}<>
{        }   #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 Bu yığında hiçbir şey kalmayana kadar 3-6. Adımları uygulayın:

{                                                                                         }

3 Üstteki iki öğeyi çoğaltın (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 Eğer ilk ikisi eşitse, üstüne 1 girin, aksi takdirde 0 (wiki'den)

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

5 İlk ikisi eşitse (üstte sıfır olmayan) sonraki ikisini ekleyin ve sonucu itin

{{}(<({}{})>)}{}
{            }   #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 Üst elemanı diğer yığına taşıyın

({}<>)<>

7 Diğer yığına geç ve dolaylı olarak yazdır

<>

pls dilin adından sonra virgül ekleyin, aksi takdirde büyük afiş tipini kırar: P
ASCII-yalnızca

9

PHP, 116 Bayt

<?$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);

veya

<?$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));

Çıktı print_r, 'json_encode' yerine bir dizi olabilirse -4 Bayt

Bunu bir Regex ile çözmek için 176 Bayt

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
Sonuç her zaman sıralanmadığından sıralama kullanamazsınız: [4, 4, 2, 8, 8, 2] -> [8, 2, 16, 2]
Kripto

@Crypto Yeni test senaryoları eklendikten hemen sonra sizsiniz. Sıralama kullanımının tamamlanmasından önce
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));Aynı fikir ama daha kısa
Crypto

@Crypto Çıktı hakkında dize temsili veya bir dizi olarak emin değilim. testcase için []İhtiyacım $r=[];Yardımlarınız için teşekkür ederiz
Jörg Hülsermann


8

Retina , 32

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

r3. satırda sağdan sola regex eşleşmesini etkinleştirir. Bu, \1referansın referans aldığı (1+)yakalama grubundan önce gelmesi gerektiği anlamına gelir .

Çevrimiçi deneyin.


Güzel .. Sağdan sola doğru eşleşme seçeneği oldukça kullanışlıdır! .Net regex'in veya bir Retina özelliğinin bir parçası mı?
Dada

Benim girişimi neredeyse 26 olarak yazdım , giriş biçimi olarak satır besleme ayrımı kullanarak: retina.tryitonline.net/… ana tasarruf bundan kaynaklanacak ve ikinci ikameden kurtulmak için harf çevirisi kullanıldı.
Martin Ender

@Dada Bir .NET özelliğidir (ve keyfi uzunluktaki görünümleri etkinleştirmek için kaputun altında kullanılır). Retina'nın henüz benzersiz bir regex özelliği yoktur (bazı benzersiz değiştirme özelliklerine sahip olmasına rağmen).
Martin Ender

1
@MartinEnder Tamam, teşekkürler! .NET regex's gerçekten harika! kıskanç perl kodlayıcı benekli
Dada

@MartinEnder I, çözümünüz başka bir cevabı garanti edecek kadar farklı
Digital Trauma

8

Perl, 41 bayt

İçin +1 içerir -p

STDIN'de giriş sırası ver:

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 bayt

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

Boolean b, son iki öğenin, uzunluk 1 veya 0 listeleri için güvenli bir şekilde eşit olup olmadıklarını denetleyerek daraltılması gerekip gerekmediğini denetler. Son öğe 1, eşit veya 2eşit olmayan bir çarpanla eklenmişse son öğedir . Listedeki yinelemeli sonuca, birçok elemanın kesildiği şekilde eklenmiştir. 1 bayt için Dennis'e teşekkürler!


[l[-1]<<b]bir bayt kaydeder.
Dennis,

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

2
0 ve 1 beden listeleri için çalışmalıyım.
xnor

7

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

Ton Hospel 41 byte cevap ile geldi , bir göz atın !

-4 @Ton Hospel'e teşekkürler!

Düzenleme : eklendi \b, 24 4çıktının olacağı gibi girdi üzerinde başarısız oldu 28.

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

-pBayrakla çalıştır :

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


Ben kullanmaktan daha başka bir yol görmüyorum reverse(tıpkı sağ kat için iki kez s/(\d+) \1/$1*2/gekat dönüyorlardı, yani 2 2 2olacaktı 4 2yerine 2 4). Yani 14 bayt sayesinde kaybettik reverse... Yine de başka bir (daha iyi) yol olmalı (sonuçta perl!), Bulursan haberim olsun!


reverse reversebiraz uzun görünüyor. Perl konusunda uzman değilim, ancak kısayol yapmanın bir yolu var mı reverse(eğer başka bir şey yoksa, [ab] kullanarak eval)?
Cyoce

Güzel sexeger. Sadece dışarıda bırakabileceğinizi unutmayın($_)
Ton Hospel

@TonHospel teşekkürler. Gerçekten de, reversebenzeyen dokümanlar reverseargüman olmadan çağrılamaz (iyi örnekler gösterebilir, ancak tek bir prototip var:) reverse LIST, bu yüzden $_varsayılan argüman olmayı unuttum ;)
Dada

Bir LISTboş olabilir ...
Ton Hospel

@TonHospel gerçekten, ancak genellikle bir operatör $_varsayılan argüman olarak kullandığında , doc parametresiz bir parametre belirler (like printya da lenght...). Ya da belki bu yanlış bir izlenim var.
Dada

7

JavaScript (ES6), 68 bayt

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
Kötü değil, ama idam pasajı göre: [1024, 1024, 512, 512, 256, 256]olarak çözümlediğinden [2048, 512, 1024]değil [2048, 1024, 512]...?
WallyWest,

7

5.10 Perl, 61 50 bayt ( bayrak için 49 + 1)

11 byte tasarruf ettiğin için Ton Hospel'e teşekkürler !

Regex içermeyen çözüm, -abayraklı:

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

Burada dene!


Güzel alternatif yöntem. Yazık diziler neredeyse her zaman perl'deki karakterleri kaybederler. Yine de, kodunuzu @a=($F[-1]-$b?$b:2*pop@F,@a)while$b=pop@F;say"@a"(50 byte) golf yaparak biraz daha yakına
gelebilirsiniz

@TonHospel Gerçekten, string tabanlı çözümlerden kaçınma eğilimindeyim (sadece Perl'in bundan daha fazlasını yapabileceğini göstermek için!). Zaten kazanmak için oynamıyorum: D Golf önerileri için teşekkürler!
Paul Picard,

7

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

@ L4m2 sayesinde 1 bayt kaydedildi

Sıralanmamış diziler için bu tür girdilerin beklenebileceği açıklığa kavuştuğu tespit edildi.

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
Yaptığın düzenlemeyi önermek
üzereydim

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

@ l4m2 Bu tek basamaklı girişler için işe yarar, ancak başarısız olur [1024, 1024, 512, 512, 256, 256](Bu test durumunun daha sonra eklenmiş olabileceğini düşünüyorum).
Arnauld,

@Arnauld Peki seninki de başarısız ...
l4m2

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

6

05AB1E , 26 bayt

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

Çevrimiçi deneyin!

Genelleştirilmiş adımlar

  1. Ardışık elemanların nerede değiştiğini bulmak için çıkarma ile azaltın
  2. Ardışık elemanların uzunluğunu bulmak için bu yerlerin endeksleri üzerinden çıkartarak azaltın
  3. Girdiyi bu uzunluktaki parçalara böl
  4. Topakları çiftlere ayırma
  5. Her çifti topla
  6. Toplanan her bir parçayı ters çevir
  7. 1 boyutlu listeye düzleştir

5

Mathematica, 53 bayt

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

açıklama

Split@#

Girdiyi aynı elemanlardan oluşan alt listelere ayırın. yani {2, 2, 2, 4, 8, 8}olur {{2, 2, 2}, {4}, {8, 8}}.

#~Partition~UpTo@2

Alt listenin her birinin bölüm uzunluğuna bölünmesi en fazla 2. {{2, 2, 2}, {4}, {8, 8}}olur {{{2, 2}, {2}}, {{4}}, {{8, 8}}}.

Plus@@@

Her bölümün toplamı. yani {{{2, 2}, {2}}, {{4}}, {{8, 8}}}olur {{4, 2}, {4}, {16}}.

Reverse

Sonuçları ters çevirin, çünkü Mathematica'nın Partitionemri soldan sağa gider, fakat bölümlerin başka yönde olmasını istiyoruz. yani {{4, 2}, {4}, {16}}olur {{2, 4}, {4}, {16}}.

Join@@

Sonucu düzeltin. yani {{2, 4}, {4}, {16}}olur {2, 4, 4, 16}.


Selam JHM! Cevap için teşekkürler. Mathematica'yı çok iyi anlamıyorum, neler olup bittiğiyle ilgili bir açıklama ekler misiniz?
isaacg

Plus@@@olduğunu Tr/@ve sana parantez önleyebilirsiniz düşünmek ve Join@@kullanmak eğer ##&@@sonucuna Reverse(gerçi aCoolFunction).
Martin Ender,

5

Java 7, 133 bayt

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

Giriş, bir ArrayList'tir ve gerektiğinde kaldırarak ve iki katına çıkarak geriye doğru yalnızca döngüler oluşturur.

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

Long3. satırdaki referansları ile karşılaştırıyorsunuz ==. Düşünün a.get(i)-a.get(i-1)==0.
Jakob

4

Perl, 37 bayt

İçin +4 içerir -0n

STDIN'de giriş ile ayrı satırlar halinde çalıştırın:

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 bayt

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 bayt

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

PHP 7.0 gerektirir; komut satırı argümanlarından değer alır.

Çevrimiçi olarak çalıştırın -nrveya deneyin .


2
[2, 2, 2] [2,4] yerine [4,2] döndürür
Kripto

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

3

Julia 205 bayt

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)

Çağrılacak işlev H

Örneğin H([1,2,2,4,8,2,])

Bu, Julia’da bunu en kısa yoldan yapmaz. Ama o kadar havalı ki, yine de paylaşmak istedim.

  • t(a) (a) değerini temsil eden bir değer türüdür.
  • s(a) bu değer türünün bir örneğidir
  • gfark değerlerini (değer türlerini kullanarak) ve parametrelerinin sayılarını gönderen bir işlevdir. Ve bu harika
  • KSadece sarar g, böylece

Ekstra serin kısım:

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

Bu, ^fonksiyonlara uygulanacak operatörü tanımlar . Yani K^s(2)(X)aynıdır K(K(X)) bu yüzden Hsadece çağırıyor KüzerindeK zamanlarda bir demet - Yeterince zaman kesinlikle herhangi yuvalanmış durumda çökmeye

Bu çok daha kısa yapılabilir, ancak bu yol çok eğlenceli.


3

PowerShell v2 +, 81 bayt

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

Girdiyi açık bir dizi olarak alır $n, tersine çevirir $n[$n.count..0], -joinvirgülle birlikte öğeleri, daha sonra -replaceeşleştirilen bir rakam çiftini ilk öğe olan a *2ile eşler ve parenslerle çevrelenir. Neden Borular (giriş için hangi @(2,2,4,4)benzeyecek (4*2),(2*2)üzerinde) iex(kısa Invoke-Expressionve benzer evalgerçek sayılar içine çarpma dönüştürür). Mağazalar içine çıkan dizi $b, Pars sonra tersine çevirir, boru hattı üzerinde yerleştirmek için bu kapsüller $bile [$b.count..0]. Elde edilen elemanları boru hattında bırakır ve çıktı açıktır.


Test Kılıfları

Not - PowerShell'de boş bir diziyi "geri döndürme" kavramı anlamsızdır -$nullkapsam bıraktıktan hemen sonradönüştürülür- ve böylece hiçbir şey döndürmeme eşdeğeridir, burada ilk örnekte ne yapılır (Bazı kötü ayrıntılı hatalardan sonra). Ek olarak, buradaki çıktı, dizili diziler için varsayılan ayırıcı olduğundan boşlukla ayrılmıştır.

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 bayt

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}


Bu işe yaramıyor. İle test [2,2,4,4]verim [2,2,4,4].
Conor O'Brien,

1
Evet. Düğüm v6.2.1
Conor O'Brien,

Benim hatam .. Aynı dosyada başka bir JS kodu ile çalıştırıyordum ve global değişkenler karışıyordu.
Alexis_A

3

Beyin Flak , 60 bayt

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

Çevrimiçi deneyin!

Açıklama:

{({}<>)<>}<>   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 Bayt

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

Listeyi arkadan öne doğru oluşturmak için sağdaki katlamayı kullanın (biri sola katlamayı kullanabilir ve listeyi başında ve sonunda tersine çevirebilir).

Geçerli listenin başı bir sonraki öğeye eşit değilse, hazırlanın.

Aksi halde, listenin başını çıkarın (kulağa acımasız geliyor) ve eleman zamanlarını 2 hazırlayın.

Örnek

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

2

Raket 166 bayt

(λ(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))])))

Ungolfed:

(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))]  
        ))))

Test yapmak:

(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])

Çıktı:

'()
'(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 bayt

ò¦ ®ò2n)mxÃc

Çevrimiçi deneyin!

Ambalajsız ve Nasıl Çalışır?

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

Jonathan Allan'ın Jelly çözümünden bir fikir aldım .


0

Mathematica, 51 bayt

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

{Longest@a___,x_/;x>0,x_,b___}iki ardışık aynı pozitif sayı içeren bir listeyle eşleşir ve bu iki sayıyı dönüştürür -2x.LongestKarşılaşmaları olabildiğince geç olmaya zorlar.

İşlem adım adım gösterilmektedir:

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

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

Düzenli bir makro, ardışık sayıları eşleştirmek için geriye doğru arama yapar ve bunları birbirine ekler.

Giriş dizisinin satır başına bir sayı olması gerekir. Bu format beni vuruşlardan kurtarıyor, bu hoş, ama asıl sebep üst üste gelen regex eşleşmeleri etrafında çalışmak. Dize 222verilirse /22, üst üste binen ikinci çifti değil, yalnızca ilk çifti eşleştirirseniz. Örtüşme kuralları, iki çift farklı çizgilerden başladığında farklıdır. Bu meydan okumaya [2, 2, 2]gelir [2, 4], bu nedenle örtüşen çiftin eşleştirilmesi kritik öneme sahiptir.

NOT: Meydan okuma sadece tek bir geçiş istedi. Bu nedenle sahip olmanız gerekir :set nowrapscan. İle :set wrapscanben yazıldığı gibi bu çözüm her zaman bunu yapmayacağım ama birkaç geçişle ilgili iş bitiren bir sürümünü yapabiliriz.

  • <C-@>: Normalde, bir komut satırında, <CR>komutu çalıştırmadan bir hazır bilgi yazmak için, onu kullanmak zorunda kalmanız gerekir <C-V>. Ancak, <C-@>unescaped yazabilirsiniz ve bu, <C-J>/ <NL>, <CR>makroyu çalıştırdığınızda yazacağınız gibi olacak şekilde yazılacaktır . Okumayı deneyin :help NL-used-for-Nul.
  • @=: Kayıtlı bir makroyu bu sefer kolayca kullanamıyorum çünkü girişin eşleşen çiftleri olmayabilir. Bir makro çalışırken bu gerçekleşirse, başarısız arama makroyu bozar. Ancak (önce örtülü) kayıt geçişi sırasında gerçekleşirse, normal mod komutlarının geri kalanı çalışır ve dosyaya zarar verir. Olumsuz tarafı @=, özyinelemeli aramada bir bayt kaybediyorum; Bazen @@özyinelemeli bir çağrı olarak kullanabilirsiniz , ancak @"bu durumda bu 4 bayttan itibaren çalışır .
  • DJ@"<C-A>-: DJsatırı siler ve sayıyı (yeni satır yok) bir sicile koyar, böylece sayı argümanı için bir makro olarak çalıştırabilirim <C-A>. Daha -sonra yapmak zorundayım, bu yüzden ikinci durumlarda eşleşemiyorum [4, 2, 2].

0

Perl6, 92 bayt

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.