Changement de tableau de type 2048

80

Supposons que nous voulions déplacer un tableau comme dans le jeu 2048 : si nous avons deux éléments consécutifs égaux dans un tableau, fusionnez-les en deux fois l'élément value. Shift doit retourner un nouveau tableau, où chaque paire d'éléments égaux consécutifs est remplacée par leur somme, et les paires ne doivent pas se croiser. Le décalage est effectué une seule fois. Il n'est donc pas nécessaire de fusionner à nouveau les valeurs résultantes. Notez que si nous avons 3 éléments égaux consécutifs, nous devons additionner les éléments les plus à droite. Ainsi, par exemple, [2, 2, 2]devrait devenir [2, 4], pas [4, 2].

La tâche consiste à écrire la fonction la plus courte qui prend un tableau et retourne un tableau décalé.

Vous pouvez supposer que tous les entiers seront strictement positifs.

Exemples:

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

Je suis aussi très intéressé par la solution qui utilise réduire :)

loup vert
la source
11
C'est un très beau premier défi. Bienvenue sur le site!
DJMcMayhem
1
L'entrée n'est pas nécessairement triée et les nombres sont supérieurs à zéro, c'est la seule restriction sur les nombres. Je pense que nous pouvons laisser la plus grande valeur dans les limites standard int32. Un tableau vide donne un tableau vide à la suite. Merci pour la participation, appréciez cela :)
greenwolf
3
Pour ceux qui votent encore pour clore de manière peu claire, le défi se résume essentiellement à ceci: Supposons que vous avez un tableau d’entiers positifs. Parcourez-le de bout en bout. Si l'élément en cours est égal au suivant, remplacez-le par la somme des deux et passez à l'élément après le remplacement, puis effectuez cette vérification à nouveau pour cet élément et le suivant. Répétez jusqu'à ce que le début du tableau soit atteint.
user2428118
1
@Titus "Notez que si nous avons 3 éléments égaux consécutifs, nous devons en additionner les éléments les plus à droite. Ainsi, par exemple, [2, 2, 2] devrait devenir [2, 4], pas [4, 2]."
Martin Ender
1
La décision sur les tableaux vides est regrettable; il a invalidé quelques réponses, y compris la mienne.
Dennis

Réponses:

21

Gelée , 10 9 8 octets

Œg+2/€UF

TryItOnline ou exécuter tous les cas de test

Comment?

Œ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]
Jonathan Allan
la source
19

Haskell, 47 57 50 octets

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

Usages reduce(ou foldcomme on l'appelle en Haskell, ici un repli à droite foldr). Exemple d'utilisation: map abs.foldr(#)[] $ [2,2,2,4,4,8]-> [2,4,8,8].

Edit: +10 octets pour que cela fonctionne aussi pour les tableaux non triés. Les nombres fusionnés sont insérés en tant que valeurs négatives pour empêcher une deuxième fusion. Ils sont corrigés par une finale map abs.

nimi
la source
Le truc avec les négatifs est vraiment sympa!
xnor
14

Brain-Flak , 158 96

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

Essayez-le en ligne!

Explication:

1 Inverser la liste (tout déplacer vers l'autre pile, mais cela n'a pas d'importance)

{({}<>)<>}<>
{        }   #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 Effectuez les étapes 3 à 6 jusqu'à ce qu'il ne reste plus rien sur cette pile:

{                                                                                         }

3 Dupliquez les deux éléments supérieurs (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 Mettez un 1 en haut si les deux premiers sont égaux, un 0 sinon (du wiki)

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

5 Si les deux premiers étaient égaux (différent de zéro en haut), ajoutez les deux suivants et appuyez sur le résultat.

{{}(<({}{})>)}{}
{            }   #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 Déplacez l’élément supérieur vers l’autre pile

({}<>)<>

7 Basculez vers l’autre pile et imprimez implicitement

<>
Riley
la source
les pls ajoutent une virgule après le nom de la langue, sinon cela brise le classement ty: P
ASCII uniquement
9

PHP, 116 octets

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

ou

<?$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 octets si la sortie peut être un tableau print_rau lieu de 'json_encode`

176 octets pour résoudre ceci avec 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]));
Jörg Hülsermann
la source
1
Vous ne pouvez pas utiliser le tri car le résultat n'est pas toujours trié: [4, 4, 2, 8, 8, 2] -> [8, 2, 16, 2]
Crypto
@ Crypto Vous êtes juste après l'ajout des nouveaux cas de test. Avant l'utilisation de la sorte était ok
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));même idée mais plus courte
Crypto
@ Crypto Je ne suis pas sûr de la sortie en tant que représentation sous forme de chaîne ou d'un tableau. pour le test dont []j'ai besoin $r=[];Merci pour votre aide
Jörg Hülsermann
9

GNU sed, 41 38 37

Inclut +1 pour -r
-3 grâce à Digital Trauma
-1 grâce à seshoumara

:
s,(.*)(1+) \2\b,\1!\2\2!,
t
y,!, ,

L'entrée et la sortie sont des chaînes unaires séparées par des espaces ( basées sur ce consensus ).

Essayez-le en ligne!

Riley
la source
Utilisez y,!, ,pour enregistrer 1 octet.
Seshoumara
@seshoumara Duh ... Pourquoi n'ai-je pas pensé à cela? Merci!
Riley
8

Rétine , 32

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

rsur la ligne 3 active la correspondance de regex droite à gauche. Et cela signifie que la \1référence doit venir avant le (1+)groupe de capture auquel il fait référence.

Essayez-le en ligne.

Trauma numérique
la source
Nice .. Cette option de match de droite à gauche est assez pratique! Fait-il partie de .Net regex ou d’une fonctionnalité Retina?
Dada
J'étais sur le point de publier le mien à 26 ans, en utilisant le format de saisie séparation par saut de ligne: retina.tryitonline.net/ ... les principales économies proviennent de cela et de l'utilisation de la translittération pour supprimer le second remplacement.
Martin Ender
@ Dada C'est une fonctionnalité .NET (utilisée sous le capot pour permettre des recherches arbitraires). Retina n’a pas encore de fonction regex unique (bien qu’elle possède des fonctions de substitution uniques).
Martin Ender
1
@MartinEnder Ok merci! Les regex .NET sont vraiment super! Jalous Perl Coder repéré
Dada
@MartinEnder I votre solution est suffisamment différente pour justifier une autre réponse
Digital Trauma
8

Perl, 41 octets

Inclut +1 pour -p

Donnez la séquence d'entrée sur 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
Ton Hospel
la source
8

Python, 61 octets

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

Le booléen bvérifie si les deux derniers éléments doivent être réduits en vérifiant qu'ils sont égaux de manière sûre pour les listes de longueur 1 ou 0. Le dernier élément est ensuite ajouté avec un multiplicateur de 1égal ou non 2. Il est ajouté au résultat récursif sur la liste avec autant d'éléments coupés à la fin. Merci à Dennis pour 1 octet!

Xnor
la source
[l[-1]<<b]enregistre un octet.
Dennis
l[-2:-1]est[l[-2]]
mbomb007
2
J'en ai besoin pour les listes de taille 0 et 1.
xnor
7

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

Ton Hospel est arrivé avec 41 octets de réponse , allez voir!

-4 grâce à @Ton Hospel!

Edit : ajouté \b, sans cela, il échouait en entrée comme 24 4sur le résultat en sortie 28.

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

Courir avec le -pdrapeau:

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


Je ne vois pas d'autre moyen que d'utiliser reversedeux fois le pli à droite (comme le s/(\d+) \1/$1*2/geferait un pli gauche, c'est-à-dire 2 2 2qu'il deviendrait 4 2au lieu de 2 4). Donc 14 octets perdus grâce à reverse... Je pense quand même qu'il doit y avoir une autre (meilleure) façon (c'est du perl après tout!), Faites le moi savoir si vous le trouvez!

Dada
la source
reverse reversesemble un peu long. Je ne suis pas un expert en Perl, mais y a-t-il un moyen de créer un raccourci reverse(si rien d'autre, [ab] utilisant eval)?
Cyoce
Belle sexeeuse. Notez que vous pouvez simplement laisser ($_)
tomber
@TonHospel merci. En effet, la doc de reverselooks like reversene peut pas être appelée sans argument (les exemples le montrent, mais il n’existe qu’un seul prototype:) reverse LIST, j’ai donc oublié d’ $_être l’argument par défaut;)
Dada
A LISTpeut être vide ...
Ton Hospel
@TonHospel en effet, mais généralement lorsqu'un opérateur utilise $_comme argument par défaut, la doc spécifie un prototype sans paramètre (comme printou lenght...). Ou peut-être que c'est juste une mauvaise impression que j'ai.
Dada
7

JavaScript (ES6), 68 octets

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

sundar
la source
2
Pas mal, mais selon l'extrait exécuté: la [1024, 1024, 512, 512, 256, 256]résolution est-elle comme [2048, 512, 1024]et non [2048, 1024, 512]...?
WallyWest
7

Perl 5.10, 61 50 octets ( 49 + 1 pour drapeau)

Merci à Ton Hospel d' avoir sauvé 11 octets!

Solution sans regex, avec -adrapeau:

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

Essayez ici!

Paul picard
la source
Belle méthode alternative. Dommage que les tableaux perdent presque toujours face aux chaînes en perl. Néanmoins, vous pouvez vous rapprocher un peu en jouant votre code dans @a=($F[-1]-$b?$b:2*pop@F,@a)while$b=pop@F;say"@a"(50 octets)
Ton Hospel
@TonHospel En effet, j'ai tendance à éviter les solutions basées sur des chaînes de caractères (juste pour montrer que Perl peut faire plus que cela!). Je ne joue pas pour gagner quand même: D Merci pour les conseils de golf!
Paul Picard
7

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

Sauvegardé 1 octet grâce à @ l4m2

Corrigé pour les tableaux non triés maintenant qu'il a été précisé que de telles entrées sont à prévoir.

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

Arnauld
la source
1
J'étais sur le point de suggérer le montage que vous venez de faire :)
ETHproductions
a=>(a.reverse()+'').replace(/(.),\1/g,(c,i)=>i*2).split`,`.reverse()?
l4m2
@ l4m2 Cela fonctionne pour les entrées à un chiffre, mais échouera [1024, 1024, 512, 512, 256, 256](je pense que ce cas de test a peut-être été ajouté plus tard).
Arnauld
@Arnauld Eh bien, vous aussi, vous échouez ...
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 octets

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

Essayez-le en ligne!

Étapes généralisées

  1. Réduire par soustraction pour trouver où diffèrent des éléments consécutifs
  2. Réduire par soustraction sur les indices de ces lieux pour trouver la longueur d'éléments consécutifs
  3. Fractionner l'entrée en morceaux de ces longueurs
  4. Diviser des morceaux en paires
  5. Somme chaque paire
  6. Inverser chaque morceau sommé
  7. Aplatir à la liste à une dimension
Emigna
la source
5

Mathematica, 53 octets

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

Explication

Split@#

Fractionner les entrées en sous-listes composées de séquences d'éléments identiques c'est-à-dire {2, 2, 2, 4, 8, 8}devient {{2, 2, 2}, {4}, {8, 8}}.

#~Partition~UpTo@2

Partitionnez chaque sous-liste en partitions de la longueur maximale 2. c’est-à-dire {{2, 2, 2}, {4}, {8, 8}}devient {{{2, 2}, {2}}, {{4}}, {{8, 8}}}.

Plus@@@

Totaliser chaque partition. c'est-à-dire {{{2, 2}, {2}}, {{4}}, {{8, 8}}}devient {{4, 2}, {4}, {16}}.

Reverse

Inverser les résultats car la Partitioncommande de Mathematica va de gauche à droite, mais nous voulons que les partitions soient dans une autre direction. c'est-à-dire {{4, 2}, {4}, {16}}devient {{2, 4}, {4}, {16}}.

Join@@

Aplatir le résultat. c'est-à-dire {{2, 4}, {4}, {16}}devient {2, 4, 4, 16}.

JungHwan Min
la source
Salut JHM! Merci d'avoir répondu. Je ne comprends pas très bien Mathematica, alors pourriez-vous ajouter quelques explications sur ce qui se passe?
isaacg
Plus@@@est Tr/@et je pense que vous pouvez éviter les parenthèses et Join@@si vous utilisez ##&@@le résultat de Reverse(je ne l’ai pas testé cependant).
Martin Ender
5

Java 7, 133 octets

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'entrée est une ArrayList, et elle effectue une boucle en arrière, supprimant et doublant si nécessaire.

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;
}
Géobits
la source
Vous comparez les Longréférences sur la ligne 3 avec ==. Tenez compte a.get(i)-a.get(i-1)==0.
Jakob
4

Perl, 37 octets

Comprend +4 pour -0n

Exécuter avec l'entrée en tant que lignes séparées sur 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
Ton Hospel
la source
4

Haskell, 56 octets

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

PHP, 86 100 99 94 octets

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

nécessite PHP 7.0; prend des valeurs à partir des arguments de la ligne de commande.

Courez avec -nrou essayez-le en ligne .

Titus
la source
2
[2, 2, 2] renvoie [4,2] au lieu de [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);est 1 Byte plus court
Jörg Hülsermann
3

Julia 205 octets

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 fonction à appeler est H

par exemple H([1,2,2,4,8,2,])

Ce n'est en aucun cas le moyen le plus court de le faire à Julia. Mais c'est tellement cool que je voulais quand même le partager.

  • t(a) est un type de valeur, représentant la valeur (a).
  • s(a) est une instance de ce type de valeur
  • gest une fonction qui distribue les valeurs de différence (en utilisant les types de valeur) et le nombre de ses paramètres. Et c'est cool
  • Kjuste enroule gpour que

Partie super cool:

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

Ceci définit l' ^opérateur à appliquer aux fonctions. Donc , K^s(2)(X)c'est la même que K(K(X)) si Hon vient d' appeler Ksur Kun tas de fois - suffisamment de fois effondrement certainement tous les cas imbriqué

Cela peut être fait beaucoup plus court, mais cette façon est tellement amusante.

Lyndon White
la source
3

PowerShell v2 +, 81 octets

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

Prend l'entrée en tant que tableau explicite $n, l'inverse $n[$n.count..0], -joins les éléments avec une virgule, puis regex est -replaceune paire de chiffres correspondante avec le premier élément, a *2, et entourée de parenthèses. Les tubes qui résultent (qui @(2,2,4,4)ressemblera à l' entrée (4*2),(2*2)) à iex(abrégé Invoke-Expressionet similaire à eval), qui convertit la multiplication en nombres réels. Stocke le tableau résultant dans $b, encapsule celui-ci entre parenthèses pour le placer sur le pipeline, puis l'inverse $bavec [$b.count..0]. Laisse les éléments résultants sur le pipeline et la sortie est implicite.


Cas de test

NB-- Dans PowerShell, le concept de "retourner" un tableau vide n'a pas de sens - il est converti$nullen dès qu'il quitte la portée - et équivaut donc à ne rien renvoyer, ce qui est fait ici dans le premier exemple. (après quelques erreurs vachement verbeuses). De plus, la sortie ici est séparée par des espaces, car c'est le séparateur par défaut pour les tableaux stringifiés.

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
AdmBorkBork
la source
3

Javascript - 103 octets

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}
Alexis_A
la source
Enregistrement de 16 octets grâce aux conseils de @MayorMonty sur cette page
Alexis_A
Ça ne marche pas. Test avec des [2,2,4,4]rendements [2,2,4,4].
Conor O'Brien
1
Ouaip. Nœud v6.2.1
Conor O'Brien
My bad .. Je l'exécutais avec un autre code JS dans le même fichier et les variables globales se sont mélangées.
Alexis_A
3

Brain-Flak , 60 octets

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

Essayez-le en ligne!

Explication:

{({}<>)<>}<>   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
Jo King
la source
2

Python 2, 94 octets

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

Essayez-le en ligne

mbomb007
la source
2

Julia, 73 82 octets

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

Utilisez le pli à droite pour construire la liste de l’avant vers l’avant (vous pouvez également utiliser le pli à gauche et l’inverse de la liste au début et à la fin).

Si l'en-tête de la liste actuelle n'est pas égal à l'élément suivant à ajouter au début, ajoutez-le simplement au début.

Sinon, supprimez la tête de liste (sonne assez cruel) et ajoutez l'élément fois 2.

Exemple

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

Raquette 166 octets

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

Essai:

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

Sortie:

'()
'(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)
rnso
la source
1

Japt , 12 octets

ò¦ ®ò2n)mxÃc

Essayez-le en ligne!

Déballé et comment ça marche

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

J'ai eu une idée de la solution Jelly de Jonathan Allan .

Barboteur
la source
0

Mathematica, 51 octets

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

{Longest@a___,x_/;x>0,x_,b___}correspond à une liste contenant deux nombres positifs identiques consécutifs et transforme ces deux nombres en -2x. Longestoblige les matches à se dérouler le plus tard possible.

Le processus est illustré étape par étape:

   {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}
njpipeorgan
la source
0

Vim, 28 octets

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

Une macro qui regex recherche en arrière des numéros consécutifs correspondants et les ajoute.

Le tableau d'entrée doit être un nombre par ligne. Ce format me permet d’économiser des traits, ce qui est agréable, mais la vraie raison est de travailler autour des correspondances de regex qui se chevauchent. Étant donné la chaîne 222, si vous ne /22faites correspondre que la première paire, pas la seconde paire qui se chevauchent. Les règles de chevauchement sont différentes lorsque les deux paires commencent sur des lignes différentes. Dans ce défi [2, 2, 2]devient [2, 4], donc correspondant à la paire de chevauchement est critique.

REMARQUE: le défi demandé ne nécessite qu'un seul laissez-passer. Pour cette raison, vous devez avoir :set nowrapscan. Avec :set wrapscanmoi, je pourrais créer une version qui termine le travail en plusieurs passes, bien que cette solution ne l’ait pas toujours.

  • <C-@>: Normalement, en ligne de commande, taper un littéral <CR>sans exécuter la commande avec laquelle vous devez l'échapper <C-V>. Mais vous pouvez taper <C-@>sans échappée et il sera traité comme un <C-J>/ <NL>, ce qui ressemblera à <CR>lorsque vous exécutez la macro, mais pas lorsque vous tapez. Essayez de lire :help NL-used-for-Nul.
  • @=: Je ne peux pas utiliser facilement une macro enregistrée cette fois-ci, car il est possible que l’entrée ne comporte aucune paire correspondante. Si cela se produit lors de l'exécution d'une macro, la recherche infructueuse échouera. Mais si cela se produit lors de la passe (implicite en premier), les autres commandes du mode normal seront exécutées, ce qui endommagera le fichier. L'inconvénient de @=je perd un octet sur l'appel récursif; Parfois, vous pouvez utiliser @@un appel récursif, mais cela débute à @"partir de 4 octets plus tôt dans ce cas.
  • DJ@"<C-A>-: DJsupprime la ligne et met le numéro (pas de nouvelle ligne) dans un registre afin que je puisse l'exécuter en tant que macro pour un argument de nombre <C-A>. Je dois par la -suite pour ne pas avoir un deuxième match dans des cas comme [4, 2, 2].
udioica
la source
0

Perl6, 92 octets

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