Spostamento di array simile a 2048


80

Supponiamo di voler spostare un array come nel gioco del 2048 : se abbiamo due elementi consecutivi uguali in array, uniscili in due volte l'elemento value. Shift deve restituire un nuovo array, in cui ogni coppia di elementi uguali consecutivi viene sostituita con la loro somma e le coppie non devono intersecarsi. Lo spostamento viene eseguito una sola volta, quindi non è necessario unire nuovamente i valori risultanti. Si noti che se abbiamo 3 elementi uguali consecutivi, dobbiamo sommare quelli più a destra, quindi ad esempio [2, 2, 2]dovrebbe diventare [2, 4], no [4, 2].

Il compito è scrivere la funzione più breve che accetta un array e restituisce un array spostato.

Puoi presumere che tutti i numeri interi saranno strettamente positivi.

Esempi:

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

Sono anche molto interessato alla soluzione che utilizza la riduzione :)


11
Questa è una prima bella sfida. Benvenuti nel sito!
DJMcMayhem

1
L'input non è necessariamente ordinato e i numeri sono maggiori di zero, questa è l'unica restrizione ai numeri. Potremmo lasciare che il valore più grande si adatti ai limiti int32 standard, penso. La matrice vuota fornisce di conseguenza una matrice vuota. Grazie per la partecipazione, che apprezza :)
greenwolf

3
Per coloro che votano ancora per chiudere come poco chiaro, la sfida si riduce essenzialmente a questo: supponiamo di avere una matrice di numeri interi positivi. Attraversalo dall'inizio alla fine. Se l'elemento corrente è uguale al successivo, sostituiscilo con la somma di entrambi e passa all'elemento dopo la sostituzione, quindi esegui nuovamente questo controllo per quell'elemento e il successivo. Ripetere fino a quando non viene raggiunto l'inizio dell'array.
user2428118,

1
@Titus "Nota che se abbiamo 3 elementi uguali consecutivi, dobbiamo sommare quelli più a destra, quindi ad esempio [2, 2, 2] dovrebbe diventare [2, 4], non [4, 2]."
Martin Ender,

1
La sentenza su array vuoti è sfortunata; ha invalidato alcune risposte, inclusa la mia.
Dennis,

Risposte:



19

Haskell, 47 57 50 byte

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

Usi reduce(o foldcome viene chiamato in Haskell, qui una piega a destra foldr). Esempio di utilizzo: map abs.foldr(#)[] $ [2,2,2,4,4,8]-> [2,4,8,8].

Modifica: +10 byte per farlo funzionare anche per array non ordinati. I numeri uniti vengono inseriti come valori negativi per impedire una seconda unione. Sono corretti da un finale map abs.


Il trucco con i negativi è davvero bello!
xnor

14

Brain-Flak , 158 96

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

Provalo online!

Spiegazione:

1 Invertire l'elenco (spostare tutto sull'altro stack, ma non importa)

{({}<>)<>}<>
{        }   #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 Esegui i passaggi 3-6 fino a quando non rimane più nulla su questo stack:

{                                                                                         }

3 Duplica i primi due elementi (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 Metti un 1 in cima se i primi due sono uguali, uno 0 altrimenti (dal wiki)

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

5 Se i primi due erano uguali (diverso da zero in alto) aggiungere i due successivi e spingere il risultato

{{}(<({}{})>)}{}
{            }   #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 Spostare l'elemento superiore sull'altro stack

({}<>)<>

7 Passare all'altra pila e stampare in modo implicito

<>

per favore aggiungi la virgola dopo il nome della lingua, altrimenti rompe la classifica ty: P
ASCII

9

PHP, 116 byte

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

o

<?$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 byte se l'output può essere un array print_ranziché 'json_encode`

176 byte per risolvere questo problema con un 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
Non puoi utilizzare l'ordinamento poiché il risultato non è sempre ordinato: [4, 4, 2, 8, 8, 2] -> [8, 2, 16, 2]
Crypto

@Crypto Hai ragione subito dopo l'aggiunta dei nuovi casi di test. Prima dell'uso dell'ordinamento andava bene
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));stessa idea ma più breve
Crypto

@Crypto Non sono sicuro dell'output come rappresentazione di stringa o array. per la prova []ho bisogno di $r=[];grazie per il vostro aiuto
Jörg Hülsermann,


8

Retina , 32

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

rsulla riga 3 attiva la corrispondenza regex da destra a sinistra. Ciò significa che il \1riferimento deve precedere il (1+)gruppo di acquisizione a cui fa riferimento.

Provalo online.


Bello .. Quell'opzione da destra a sinistra da abbinare è abbastanza utile! Fa parte di .Net regex o una funzione Retina?
Dada,

Stavo per pubblicare il mio a 26 anni, usando la separazione della linea di alimentazione come formato di input: retina.tryitonline.net/… i principali risparmi derivano da questo e usando la traslitterazione per sbarazzarsi della seconda sostituzione.
Martin Ender,

@Dada È una funzionalità .NET (ed è utilizzata sotto il cofano per abilitare lookbehind di lunghezza arbitraria). Retina non ha ancora caratteristiche regex uniche (sebbene abbia alcune caratteristiche di sostituzione uniche).
Martin Ender,

1
@MartinEnder Ok grazie! I regex di .NET sono davvero fantastici! geloso programmatore perl avvistato
Dada,

@MartinEnder I la tua soluzione è abbastanza diversa da giustificare un'altra risposta
Digital Trauma,

8

Perl, 41 byte

Include +1 per -p

Fornisci la sequenza di input su 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]

Il valore booleano bverifica se gli ultimi due elementi devono collassare verificando che siano uguali in un modo sicuro per gli elenchi di lunghezza 1 o 0. L'ultimo elemento viene quindi aggiunto con un moltiplicatore di 1uguale o 2uguale. Viene aggiunto al risultato ricorsivo nell'elenco con quel numero di elementi tagliati alla fine. Grazie a Dennis per 1 byte!


[l[-1]<<b]salva un byte.
Dennis,

l[-2:-1]è[l[-2]]
mbomb007,

2
Ho bisogno che funzioni per elenchi di dimensioni 0 e 1.
xnor

7

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

Ton Hospel ha trovato 41 byte di risposta , dai un'occhiata!

-4 grazie a @Ton Hospel!

Modifica : aggiunto \b, poiché senza di esso non funzionava sull'input come 24 4su quale sarebbe stato l'output 28.

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

Esegui con -pbandiera:

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


Non vedo altro che usare reversedue volte per piegare a destra (come s/(\d+) \1/$1*2/gefarebbe per piegare a sinistra, cioè 2 2 2diventerebbe 4 2invece di 2 4). Quindi 14 byte persi grazie a reverse... Continuo a pensare che ci debba essere un altro (migliore) modo (dopo tutto è perl!), Fammi sapere se lo trovi!


reverse reversesembra un po 'lungo. Non sono un esperto di Perl, ma c'è un modo in cui puoi fare una scorciatoia reverse(se non altro, [ab] usando eval)?
Cyoce,

Bello sexeger. Nota che puoi semplicemente lasciare fuori($_)
Ton Hospel il

@TonHospel grazie. In effetti, il documento di reverseaspetto reversenon può essere chiamato senza argomento (bene gli esempi mostrano che può essere, ma c'è solo un prototipo:) reverse LIST, quindi ho dimenticato di $_essere l'argomento predefinito;)
Dada

A LISTpuò essere vuoto ...
Ton Hospel il

@TonHospel in effetti, ma di solito quando un operatore utilizza $_come argomento predefinito, il documento specifica un prototipo senza parametri (come printo lenght...). O forse è solo un'impressione sbagliata che ho.
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
Non male, ma secondo lo snippet eseguito: si [1024, 1024, 512, 512, 256, 256]sta risolvendo come [2048, 512, 1024]e non [2048, 1024, 512]...?
WallyWest,

7

Perl 5.10, 61 50 byte ( 49 + 1 per bandiera)

Grazie a Ton Hospel per aver salvato 11 byte!

Soluzione senza Regex, con -abandiera:

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

Prova qui!


Bel metodo alternativo. Una matrice di peccato quasi sempre perde a stringhe in perl. Tuttavia, puoi avvicinarti un po 'giocando a golf il tuo codice a @a=($F[-1]-$b?$b:2*pop@F,@a)while$b=pop@F;say"@a"(50 byte)
Ton Hospel

@TonHospel In effetti, tendo a evitare soluzioni basate su stringhe (solo per dimostrare che Perl può fare di più!). Non gioco per vincere comunque: D Grazie per i consigli sul golf!
Paul Picard,

7

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

Salvato 1 byte grazie a @ l4m2

Risolto il problema con gli array non ordinati ora che è stato chiarito che tali input sono prevedibili.

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
Stavo per suggerire la modifica che hai appena fatto :)
ETHproductions

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

@ l4m2 Funziona con input a una cifra, ma fallirebbe [1024, 1024, 512, 512, 256, 256](penso che questo caso di test potrebbe essere stato aggiunto in seguito).
Arnauld,

@Arnauld Beh, anche il tuo fallisce ...
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 byte

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

Provalo online!

Passaggi generalizzati

  1. Ridurre per sottrazione per trovare dove differiscono gli elementi consecutivi
  2. Ridurre per sottrazione sugli indici di quei luoghi per trovare la lunghezza degli elementi consecutivi
  3. Dividi l'input in blocchi di quelle lunghezze
  4. Dividi i pezzi in coppie
  5. Somma ogni coppia
  6. Invertire ogni blocco sommato
  7. Appiattire all'elenco monodimensionale

5

Mathematica, 53 byte

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

Spiegazione

Split@#

Dividere l'input in elenchi secondari costituiti da sequenze di elementi identici. cioè {2, 2, 2, 4, 8, 8}diventa {{2, 2, 2}, {4}, {8, 8}}.

#~Partition~UpTo@2

Partizionare ciascuna lista secondaria in lunghezza delle partizioni al massimo 2. cioè {{2, 2, 2}, {4}, {8, 8}}diventa {{{2, 2}, {2}}, {{4}}, {{8, 8}}}.

Plus@@@

Totale di ogni partizione. cioè {{{2, 2}, {2}}, {{4}}, {{8, 8}}}diventa {{4, 2}, {4}, {16}}.

Reverse

Invertire i risultati perché il Partitioncomando di Mathematica va da sinistra a destra, ma vogliamo che le partizioni siano nella direzione opposta. cioè {{4, 2}, {4}, {16}}diventa {{2, 4}, {4}, {16}}.

Join@@

Appiattire il risultato. cioè {{2, 4}, {4}, {16}}diventa {2, 4, 4, 16}.


Ciao JHM! Grazie per la risposta. Non capisco molto bene Mathematica, quindi potresti aggiungere qualche spiegazione su cosa sta succedendo?
isaacg,

Plus@@@è Tr/@e penso che tu possa evitare le parentesi e Join@@se usi ##&@@il risultato di Reverse(non l'ho provato però).
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;}

L'input è una ArrayList e si sposta semplicemente indietro, rimuovendo e raddoppiando dove necessario.

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

Stai confrontando i Longriferimenti alla riga 3 con ==. Prendere in considerazione a.get(i)-a.get(i-1)==0.
Jakob,

4

Perl, 37 byte

Include +4 per -0n

Esegui con l'input come righe separate su 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);

richiede PHP 7.0; accetta valori dagli argomenti della riga di comando.

Corri con -nro provalo online .


2
[2, 2, 2] restituisce [4,2] invece di [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);è di 1 byte più breve
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)

La funzione da chiamare è H

per esempio H([1,2,2,4,8,2,])

Questo non è in alcun modo il modo più breve per farlo in julia. Ma è così bello, che volevo condividerlo comunque.

  • t(a) è un tipo di valore, che rappresenta il valore (a).
  • s(a) è un'istanza di quel tipo di valore
  • gè una funzione che invia i valori di differenza (usando i tipi di valore) e i numeri dei suoi parametri. E questo è bello
  • Kavvolge solo gcosì

Parte extra cool:

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

Questo definisce l' ^operatore da applicare alle funzioni. In modo che K^s(2)(X)sia uguale a K(K(X)) così Hè solo chiamando Ksu Kun mucchio di volte - abbastanza volte al collasso certamente ogni caso nidificato

Questo può essere fatto molto più breve, ma in questo modo è così divertente.


3

PowerShell v2 +, 81 byte

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

Prende l'input come un array esplicito $n, lo inverte $n[$n.count..0], -joins gli elementi insieme a una virgola, quindi regex -replaceuna coppia di cifre corrispondente con il primo elemento, a *2e racchiuso tra parentesi. Tubi che risultano (che per l' @(2,2,4,4)aspetto appariranno (4*2),(2*2)) sopra iex(abbreviato Invoke-Expressione simile a eval), che converte la moltiplicazione in numeri reali. Memorizza l'array risultante in $b, incapsula che nella parentesi di immissione in pipeline, poi inverte $bcon [$b.count..0]. Lascia gli elementi risultanti sulla pipeline e l'output è implicito.


Casi test

NB: in PowerShell, il concetto di "restituzione" di un array vuoto non ha senso - viene convertito$nullnon appena lascia l'ambito - e quindi equivale a non restituire nulla, che è ciò che viene fatto qui nel primo esempio (dopo alcuni errori malvagi verbosi). Inoltre, l'output qui è separato dallo spazio, in quanto è il separatore predefinito per gli array stringiti.

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}

16 byte salvati grazie ai suggerimenti di @MayorMonty in questa pagina
Alexis_A

Questo non funziona Test con [2,2,4,4]rese [2,2,4,4].
Conor O'Brien,

1
Sì. Nodo v6.2.1
Conor O'Brien,

Mio cattivo .. Lo stavo eseguendo con un altro codice JS nello stesso file e le variabili globali si sono confuse.
Alexis_A

3

Brain-Flak , 60 byte

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

Provalo online!

Spiegazione:

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

Python 2, 94 byte

def f(a,r=[]):
 while a:
    if len(a)>1and a[-1]==a[-2]:a.pop();a[-1]*=2
    r=[a.pop()]+r
 print r

Provalo online


2

Julia, 73 82 byte

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

Usa la piega a destra per costruire la lista da dietro a avanti (puoi anche usare piega a sinistra e invertire la lista all'inizio e alla fine).

Se la testa dell'elenco corrente non è uguale all'elemento successivo da anteporre, allora basta anteporre.

Altrimenti rimuovi la testa dell'elenco (sembra un po 'crudele) e anteponi l'elemento 2 volte.

Esempio

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

2

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

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:

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

Produzione:

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

Provalo online!

Disimballato e come funziona

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

Ho avuto qualche idea dalla soluzione Jelly di Jonathan Allan .


0

Mathematica, 51 byte

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

{Longest@a___,x_/;x>0,x_,b___}corrisponde a un elenco contenente due numeri positivi identici consecutivi e trasforma questi due numeri in -2x. Longestimpone che le partite avvengano il più tardi possibile.

Il processo è illustrato passo dopo passo:

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

Una macro che regex cerca all'indietro i numeri consecutivi corrispondenti e li somma insieme.

L'array di input deve essere un numero per riga. Questo formato mi salva i tratti, il che è carino, ma il vero motivo è aggirare le combinazioni di regex sovrapposte. Data la stringa 222, se /22corrisponderai solo alla prima coppia, non alla seconda coppia sovrapposta. Le regole di sovrapposizione sono diverse quando le due coppie iniziano su linee diverse. In questa sfida [2, 2, 2]diventa [2, 4], quindi l'abbinamento della coppia sovrapposta è fondamentale.

NOTA: la sfida ha richiesto un solo passaggio. Per questo motivo, devi averlo :set nowrapscan. Con :set wrapscanho potuto creare una versione che termina il lavoro su più passaggi, anche se questa soluzione scritta non lo farà sempre.

  • <C-@>: Normalmente, in una riga di comando, digitare un valore letterale <CR>senza eseguire il comando con cui dovresti scappare <C-V>. Ma puoi digitare senza caratteri di <C-@>escape e verrà trattato come <C-J>/ <NL>, che sarà come <CR>quando esegui la macro ma non durante la digitazione. Prova a leggere :help NL-used-for-Nul.
  • @=: Questa volta non riesco a usare facilmente una macro registrata perché esiste la possibilità che l'input non abbia coppie corrispondenti. Se ciò accade durante l'esecuzione di una macro, la ricerca non riuscita avrà esito negativo. Ma se accade durante il passaggio di registrazione (implicito per primo), il resto dei normali comandi in modalità verrà eseguito, danneggiando il file. Il rovescio della medaglia di @=è che perdo un byte sulla chiamata ricorsiva; a volte è possibile utilizzare @@come chiamata ricorsiva, ma @"in questo caso verrebbe eseguito da 4 byte in precedenza.
  • DJ@"<C-A>-: DJelimina la riga e inserisce il numero (nessuna nuova riga) in un registro, quindi posso eseguirlo come macro per un argomento numerico <C-A>. Devo -dopo, quindi non ricevo una seconda partita in casi come [4, 2, 2].

0

Perl6, 92 byte

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.