Przesunięcie tablicy podobne do 2048


80

Załóżmy, że chcemy przesunąć tablicę, tak jak ma to miejsce w grze 2048 : jeśli mamy dwa równe kolejne elementy w tablicy, scal je w podwójny element wartości. Shift musi zwrócić nową tablicę, w której każda para kolejnych równych elementów jest zastępowana ich sumą, a pary nie powinny się przecinać. Przesunięcie jest wykonywane tylko raz, więc nie musimy ponownie łączyć uzyskanych wartości. Zauważ, że jeśli mamy 3 kolejne równe elementy, musimy zsumować skrajne prawe, więc na przykład [2, 2, 2]powinno się stać [2, 4], a nie [4, 2].

Zadanie polega na napisaniu najkrótszej funkcji, która pobiera tablicę i zwraca tablicę przesuniętą.

Możesz założyć, że wszystkie liczby całkowite będą ściśle dodatnie.

Przykłady:

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

Jestem również bardzo zainteresowany rozwiązaniem wykorzystującym redukcję :)


11
To bardzo miłe pierwsze wyzwanie. Witamy na stronie!
DJMcMayhem

1
Dane wejściowe niekoniecznie są sortowane, a liczby są większe od zera, to jedyne ograniczenie liczb. Myślę, że możemy pozwolić, aby największa wartość mieściła się w standardowych granicach int32. W rezultacie pusta tablica daje pustą tablicę. Dziękujemy za udział, doceniam to :)
greenwolf

3
Dla tych, którzy nadal głosują na zakończenie jako niejasne, wyzwanie zasadniczo sprowadza się do tego: Załóżmy, że masz szereg dodatnich liczb całkowitych. Przejdź przez nią od końca do początku. Jeśli bieżący element jest równy następnemu, zastąp go sumą obu i przejdź do elementu po wymianie, a następnie ponownie wykonaj tę kontrolę dla tego elementu i następnego. Powtarzaj aż do osiągnięcia początku tablicy.
user2428118,

1
@Titus „Zauważ, że jeśli mamy 3 kolejne równe elementy, musimy zsumować skrajne prawe, więc na przykład [2, 2, 2] powinno stać się [2, 4], a nie [4, 2].”
Martin Ender,

1
Orzeczenie dotyczące pustych tablic jest niefortunne; unieważnił kilka odpowiedzi, w tym moją własną.
Dennis,

Odpowiedzi:



19

Haskell, 47 57 50 bajtów

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

Używa reduce(lub foldjak to się nazywa w Haskell, tutaj prawy fold foldr). Przykład użycia: map abs.foldr(#)[] $ [2,2,2,4,4,8]-> [2,4,8,8].

Edycja: +10 bajtów, aby działało również dla nieposortowanych tablic. Połączone liczby są wstawiane jako wartości ujemne, aby zapobiec ponownemu scaleniu. Są one poprawiane przez finał map abs.


Sztuczka z negatywami jest naprawdę fajna!
xnor

14

Brain-Flak , 158 96

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

Wypróbuj online!

Wyjaśnienie:

1 Odwróć listę (przenosząc wszystko na inny stos, ale to nie ma znaczenia)

{({}<>)<>}<>
{        }   #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 Wykonaj kroki 3-6, aż na stosie nie pozostanie nic:

{                                                                                         }

3 Zduplikuj dwa górne elementy (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 Umieść 1 na górze, jeśli dwie pierwsze są równe, 0 w przeciwnym razie (z wiki)

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

5 Jeśli dwie górne były równe (niezerowe u góry), dodaj kolejne dwie i wciśnij wynik

{{}(<({}{})>)}{}
{            }   #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 Przenieś górny element na drugi stos

({}<>)<>

7 Przełącz na drugi stos i drukuj niejawnie

<>

pls dodaj przecinek po nazwie języka, w przeciwnym razie psuje tabelę wyników ty: P
tylko ASCII

9

PHP, 116 bajtów

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

lub

<?$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 Bajtów, jeśli wyjściem może być tablica print_rzamiast „kod_json”

176 bajtów, aby rozwiązać ten problem za pomocą 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
Nie można użyć sortowania, ponieważ wynik nie zawsze jest sortowany: [4, 4, 2, 8, 8, 2] -> [8, 2, 16, 2]
Crypto

@Crypto Masz rację po dodaniu nowych przypadków testowych. Przed użyciem sortowania było w porządku
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));ten sam pomysł, ale krótszy
Crypto

@Crypto Nie jestem pewien co do wyniku jako reprezentacji ciągu lub tablicy. do testu []potrzebuję $r=[];Dziękuję za pomoc
Jörg Hülsermann


8

Retina , 32

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

rw linii 3 aktywuje dopasowanie wyrażenia regularnego od prawej do lewej. A to oznacza, że \1odniesienie musi pojawić się przed (1+)grupą przechwytującą, do której się odwołuje.

Wypróbuj online.


Fajnie ... Ta opcja dopasowania od prawej do lewej jest całkiem przydatna! Czy jest to część funkcji .ge regex lub Retina?
Dada,

Właśnie miałem opublikować mój w wieku 26 lat, używając formatu separacji linii jako formatu wejściowego: retina.tryitonline.net/... z tego pochodzą główne oszczędności i stosując transliterację, aby pozbyć się drugiej zamiany.
Martin Ender

@Dada Jest to funkcja .NET (i jest używana pod maską, aby umożliwić wyświetlanie dowolnych długości). Retina nie ma jeszcze żadnych unikalnych funkcji wyrażenia regularnego (chociaż ma kilka unikalnych funkcji zastępowania).
Martin Ender

1
@MartinEnder Ok dzięki! Wyrażenia regularne .NET są naprawdę świetne! zauważony zazdrosny koder perlowy
Dada

@MartinEnder I twoje rozwiązanie jest na tyle inne, że uzasadnia kolejną odpowiedź
Digital Trauma

8

Perl, 41 bajtów

Obejmuje +1 dla -p

Podaj sekwencję wprowadzania na 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 bajtów

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

Boolean bsprawdza, czy dwa ostatnie elementy powinny się zwinąć, sprawdzając, czy są one równe w sposób bezpieczny dla list o długości 1 lub 0. Ostatni element, jeśli następnie jest dołączony z mnożnikiem 1równości lub 2nierówności. Jest dołączany do wyniku rekurencyjnego na liście z tak wieloma elementami odciętymi na końcu. Dzięki Dennis za 1 bajt!


[l[-1]<<b]zapisuje bajt.
Dennis,

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

2
Potrzebuję go do pracy z listami o rozmiarach 0 i 1.
xnor

7

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

Ton Hospel wymyślił 41 bajtów odpowiedzi , sprawdź to!

-4 dzięki @Ton Hospel!

Edycja : dodano \b, ponieważ bez niego nie udawało się na wejściu, tak jak 24 4na wyjściu 28.

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

Uruchom z -pflagą:

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


Nie widzę innego sposobu niż przy użyciu reversedwukrotnie do prawej-krotnie (jak tylko s/(\d+) \1/$1*2/gebędzie lewy-krotnie, czyli 2 2 2staną 4 2zamiast 2 4). Więc 14 bajtów utraconych dzięki reverse... Nadal myślę, że musi istnieć inny (lepszy) sposób (w końcu perl!), Daj mi znać, jeśli go znajdziesz!


reverse reversewydaje się nieco długi. Nie jestem ekspertem w Perlu, ale czy istnieje sposób, aby zrobić skrót do reverse(jeśli nic innego, [ab] używasz eval)?
Cyoce,

Niezły sexeger. Zauważ, że możesz po prostu pominąć($_)
Ton Hospel

@TonHospel dzięki. Rzeczywiście, dokument reversewygląda na to, że reversenie można go wywołać bez argumentów (no cóż, przykłady pokazują, że można, ale jest tylko jeden prototyp:) reverse LIST, więc zapomniałem o $_domyślnym argumencie;)
Dada,

A LISTmoże być pusty ...
Ton Hospel

@TonHospel rzeczywiście, ale zwykle, gdy operator używa $_domyślnego argumentu, dokument określa prototyp bez parametrów (takich jak printlub lenght...). A może mam po prostu złe wrażenie.
Dada,

7

JavaScript (ES6), 68 bajtów

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
Nieźle, ale zgodnie z wykonanym fragmentem: [1024, 1024, 512, 512, 256, 256]jest rozwiązywany jako [2048, 512, 1024]i nie [2048, 1024, 512]...?
WallyWest,

7

Perl 5.10, 61 50 bajtów ( 49 + 1 dla flagi)

Dzięki Ton Hospel za oszczędność 11 bajtów!

Rozwiązanie wolne od Regex, z -aflagą:

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

Wypróbuj tutaj!


Ładna alternatywna metoda. Tablice szkoda prawie zawsze gubią się w łańcuchach w perlu. Możesz jednak @a=($F[-1]-$b?$b:2*pop@F,@a)while$b=pop@F;say"@a"
podejść

@TonHospel Rzeczywiście, mam tendencję do unikania rozwiązań opartych na łańcuchach znaków (tylko po to, aby pokazać, że Perl może zrobić więcej!). I tak nie gram, żeby wygrać: D Dzięki za wskazówki dotyczące gry w golfa!
Paul Picard,

7

JavaScript (ES6), 68 65 58 57 65 64 bajtów

Zapisano 1 bajt dzięki @ l4m2

Naprawiono nieposortowane tablice teraz, gdy wyjaśniono, że takich danych należy się spodziewać.

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
Już miałem zasugerować dokonaną właśnie edycję :)
ETHproductions

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

@ l4m2 Działa to w przypadku danych jednocyfrowych, ale zawiedzie [1024, 1024, 512, 512, 256, 256](myślę, że ten przypadek testowy mógł zostać dodany później).
Arnauld

@Arnauld Cóż, twoje też się nie udaje ...
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 bajtów

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

Wypróbuj online!

Uogólnione kroki

  1. Zmniejszaj przez odejmowanie, aby znaleźć różnice między kolejnymi elementami
  2. Zmniejsz, odejmując indeksy tych miejsc, aby znaleźć długość kolejnych elementów
  3. Podziel dane wejściowe na części o tych długościach
  4. Podziel kawałki na pary
  5. Zsumuj każdą parę
  6. Odwróć każdy zsumowany fragment
  7. Spłaszcz do listy 1-wymiarowej

5

Mathematica, 53 bajty

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

Wyjaśnienie

Split@#

Podziel dane wejściowe na listy podrzędne składające się z serii identycznych elementów. tzn . {2, 2, 2, 4, 8, 8}staje się {{2, 2, 2}, {4}, {8, 8}}.

#~Partition~UpTo@2

Podziel każdą podlistę na partycje o długości maksymalnie 2. tzn . Stanie {{2, 2, 2}, {4}, {8, 8}}się {{{2, 2}, {2}}, {{4}}, {{8, 8}}}.

Plus@@@

Łącznie każda partycja. tzn . {{{2, 2}, {2}}, {{4}}, {{8, 8}}}staje się {{4, 2}, {4}, {16}}.

Reverse

Odwróć wyniki, ponieważ Partitionpolecenie Mathematiki idzie od lewej do prawej, ale chcemy, aby partycje były w innym kierunku. tzn . {{4, 2}, {4}, {16}}staje się {{2, 4}, {4}, {16}}.

Join@@

Spłaszcz wynik. tzn . {{2, 4}, {4}, {16}}staje się {2, 4, 4, 16}.


Cześć JHM! Dziękuję za odpowiedź. Nie rozumiem dobrze Mathematiki, więc czy mógłbyś dodać trochę wyjaśnienia, co się dzieje?
isaacg

Plus@@@jest Tr/@i myślę, że możesz uniknąć nawiasów i Join@@jeśli użyjesz ##&@@wyniku Reverse(choć go nie przetestowałem).
Martin Ender

5

Java 7, 133 bajty

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 jest ArrayList i po prostu zapętla się do tyłu, usuwając i podwajając w razie potrzeby.

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

Porównujesz Longodniesienia w linii 3 z ==. Zastanów się a.get(i)-a.get(i-1)==0.
Jakob

4

Perl, 37 bajtów

Obejmuje +4 za -0n

Uruchom z danymi wejściowymi jako osobnymi liniami na 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 bajtów

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 bajty

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

wymaga PHP 7.0; pobiera wartości z argumentów wiersza poleceń.

Uruchom -nrlub wypróbuj online .


2
[2, 2, 2] zwraca [4,2] zamiast [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);jest o 1 bajt krótszy
Jörg Hülsermann

3

Julia 205 bajtów

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)

Wywoływaną funkcją jest H

na przykład H([1,2,2,4,8,2,])

Nie jest to w żaden sposób najkrótszy sposób na zrobienie tego w Julii. Ale to jest tak fajne, że i tak chciałem się tym podzielić.

  • t(a) jest typem wartości reprezentującym wartość (a).
  • s(a) jest instancją tego typu wartości
  • gjest funkcją, która wywołuje wartości różnic (przy użyciu typów wartości) i liczby jego parametrów. I to jest fajne
  • Kpo prostu owija się gtak, że

Bardzo fajna część:

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

To definiuje ^operatora do zastosowania do funkcji. Tak, że K^s(2)(X)jest taki sam jak K(K(X)) tak Hjest po prostu dzwoniąc Kna Kpęczek razy - tyle razy, aby na pewno zwinąć żadnej zagnieżdżony przypadek

Można to zrobić znacznie krócej, ale ten sposób jest po prostu zabawny.


3

PowerShell v2 +, 81 bajtów

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

Pobiera dane wejściowe jako jawną tablicę $n, odwraca je $n[$n.count..0], -joins elementy wraz z przecinkiem, a następnie regex -replacesa pasującą parę cyfr z pierwszym elementem a *2i otoczoną znakami. Rurki, które wynikają (które @(2,2,4,4)będą wyglądać na wejściu (4*2),(2*2)) do iex(skrót dla Invoke-Expressioni podobne do eval), co konwertuje mnożenie na liczby rzeczywiste. Przechowuje wynikową tablicę w $b, hermetyzuje ją w parens, aby umieścić ją w potoku, a następnie odwraca za $bpomocą [$b.count..0]. Pozostawia powstałe elementy w potoku, a dane wyjściowe są niejawne.


Przypadki testowe

Uwaga: W programie PowerShell koncepcja „zwracania” pustej tablicy jest bez znaczenia - jest konwertowana do$nullmomentu, gdy opuści zakres - a więc jest to odpowiednik braku zwracania, co dzieje się tutaj w pierwszym przykładzie (po kilku złośliwie pełnych błędach). Dodatkowo dane wyjściowe są tutaj oddzielone spacjami, ponieważ jest to domyślny separator dla tablic strunowych.

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 bajty

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}

Oszczędność 16 bajtów dzięki wskazówkom @MayorMonty na tej stronie
Alexis_A

To nie działa Testowanie [2,2,4,4]wydajności [2,2,4,4].
Conor O'Brien,

1
tak. Węzeł v6.2.1
Conor O'Brien

Mój zły .. Uruchomiłem go z innym kodem JS w tym samym pliku i zmienne globalne się pomieszały.
Alexis_A,

3

Brain-Flak , 60 bajtów

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

Wypróbuj online!

Wyjaśnienie:

{({}<>)<>}<>   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 bajtów

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

Użyj prawej klapki, aby zbudować listę od tyłu do przodu (można również użyć klapki w lewo i odwrócić listę na początku i na końcu).

Jeśli nagłówek bieżącej listy nie jest równy następnemu elementowi do dodania, po prostu wstaw go.

W przeciwnym razie usuń nagłówek listy (brzmi trochę okrutnie) i wstaw element razy 2.

Przykład

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

2

Rakieta 166 bajtów

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

Nie golfowany:

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

Testowanie:

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

Wynik:

'()
'(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 bajtów

ò¦ ®ò2n)mxÃc

Wypróbuj online!

Rozpakowane i jak to działa

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

Wpadłem na pomysł z galaretką Jonathana Allana .


0

Mathematica, 51 bajtów

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

{Longest@a___,x_/;x>0,x_,b___}dopasowuje listę zawierającą dwie kolejne identyczne liczby dodatnie i przekształca te dwie liczby w -2x. Longestzmusza mecze do spóźnienia się.

Proces ilustruje krok po kroku:

   {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 bajtów

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

Makro, które regex wyszukuje wstecz pasujące kolejne liczby, i dodaje je do siebie.

Tablica wejściowa musi mieć jedną liczbę w wierszu. Ten format oszczędza mi uderzeń, co jest miłe, ale prawdziwym powodem jest obejście nakładających się dopasowań wyrażeń regularnych. Biorąc pod uwagę ciąg 222, jeśli /22dopasujesz tylko pierwszą parę, a nie nakładającą się drugą parę. Zasady nakładania się są różne, gdy dwie pary zaczynają się na różnych liniach. W tym wyzwaniu [2, 2, 2]staje się [2, 4], więc dopasowanie nakładającej się pary ma kluczowe znaczenie.

UWAGA: Wyzwanie wymagało tylko jednego podania. Z tego powodu musisz mieć :set nowrapscan. Z :set wrapscanMógłbym stworzyć wersję, która kończy pracę na wielu przejściach, chociaż to zapisane rozwiązanie nie zawsze to robi.

  • <C-@>: Zwykle w wierszu polecenia należy wpisać literał <CR>bez uruchamiania polecenia, za pomocą którego trzeba by go uciec <C-V>. Ale możesz wpisać <C-@>nieskalowany, a zostanie on potraktowany jako <C-J>/ <NL>, co będzie jak <CR>podczas uruchamiania makra, ale nie podczas pisania. Spróbuj przeczytać :help NL-used-for-Nul.
  • @=: Tym razem nie mogę łatwo użyć zarejestrowanego makra, ponieważ istnieje możliwość, że dane wejściowe mogą nie mieć pasujących par. Jeśli tak się stanie podczas uruchamiania makra, nieudane wyszukiwanie zakończy się niepowodzeniem. Ale jeśli zdarzy się to podczas (domyślnie pierwszego) przebiegu nagrywania, uruchomione zostaną pozostałe polecenia trybu normalnego, uszkadzając plik. Minusem @=jest to, że tracę bajt na rekurencyjnym wezwaniu; czasami można użyć @@jako wywołania rekurencyjnego, ale @"w tym przypadku byłoby to uruchamiane wcześniej z 4 bajtów.
  • DJ@"<C-A>-: DJusuwa linię i umieszcza liczbę (bez nowej linii) w rejestrze, dzięki czemu mogę uruchomić ją jako makro dla argumentu liczby <C-A>. Muszę -później, żeby nie dostać drugiego meczu w takich przypadkach [4, 2, 2].

0

Perl6, 92 bajty

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.