Étirer un tableau

13

Plus tôt, j'ai défini le processus d'écrasement d'un tableau

Dans un écrasement, nous lisons le tableau de gauche à droite. Si, à un moment donné, nous rencontrons deux éléments identiques dans une rangée, nous supprimons le premier et doublons le second.

Par exemple, voici le processus d'écrasement du tableau suivant

[5,2,2,4]
 ^
[5,2,2,4]
   ^
[5,2,2,4]
     ^
[5,4,4]
   ^
[5,4,4]
     ^
[5,8]
   ^

Notez que le même élément peut être réduit plusieurs fois. Dans l'exemple, il 2,2,4s'est effondré en 8un seul passage.

Il est maintenant facile de broyer des tableaux, ce qui est difficile, c'est de les écraser. Votre tâche consiste à prendre un tableau d'entiers positifs en entrée et à sortir le plus grand tableau pouvant former l'entrée lorsqu'il est écrasé à plusieurs reprises. Par exemple, le réseau [4]est formé par écrasement [2,2]qui est à son tour formé par écrasement[1,1,1,1] . Puisque nous ne pouvons pas avoir de valeurs non entières, [1,1,1,1]nous ne pouvons plus les écraser et c'est donc notre réponse.

Vous ne recevrez jamais de 0 dans votre tableau d'entrée car ces tableaux peuvent être étendus indéfiniment. Vous ne recevrez également jamais un cas avec deux du même nombre impair côte à côte, de tels cas ne peuvent pas être le résultat d'un écrasement.

C'est du donc les réponses seront notées avec la taille de leur source mesurée en octets, moins d'octets étant meilleurs.

Avant de commencer à répondre, je veux juste dire que ce défi est beaucoup plus difficile qu'il n'y paraît. Vérifiez votre intuition au fur et à mesure et assurez-vous que votre réponse passe tous les cas de test.

Cas de test

[] -> []
[5] -> [5]
[6] -> [3,3]
[8] -> [1,1,1,1,1,1,1,1]
[4,8] -> [1,1,1,1,1,1,1,1,1,1,2]
[2,8] -> [1, 1, 1, 1, 2, 1, 1, 1, 1]
[4,4] -> [1,1,1,1,1,1,1,1]
Post Rock Garf Hunter
la source
1
Désolé mais je ne comprends toujours pas la règle. pourquoi [1,1,1,1,1,1,1,1,1,1,2]produire [4, 8]au lieu de [8, 4]? si cela est [1,>1,1,1,1,1,1,1,1,1,2], [2,1,>1,1,1,1,1,1,1,2], [2,>2,1,1,1,1,1,1,2], [4,1,>1,1,1,1,1,2], [4,2,1,>1,1,1,2], [4,2,>2,1,1,2], [4,>4,1,1,2], [8,1,>1,2], [8,2,>2], [8,4]?
tsh
2
@tsh Je pense que vous avez une idée fausse du fonctionnement du concassage. Voici le chemin qu'il prend d' abord passer: [1,>1,1,1,1,1,1,1,1,1,2], [2,>1,1,1,1,1,1,1,1,2], [2,1,>1,1,1,1,1,1,1,2], [2,2,>1,1,1,1,1,1,2], [2,2,1,>1,1,1,1,1,2], [2,2,2,>1,1,1,1,2], [2,2,2,1,>1,1,1,2], [2,2,2,2,>1,1,2], [2,2,2,2,1,>1,2], [2,2,2,2,2,>2], [2,2,2,2,4>], deuxième passage: [2,>2,2,2,4], [4,>2,2,4], [4,2,>2,4], [4,4,>4],[4,8>] . Espérons que cela clarifie les choses. Si vous souhaitez que du code pour regarder la question précédente a des réponses qui implémentent une fonction d'écrasement.
Post Rock Garf Hunter
Est-ce correct si je génère des numéros, chacun séparé par une nouvelle ligne?
scottinet
@scottinet C'est une façon raisonnable de sortir une liste. Aller de l'avant.
Post Rock Garf Hunter
Le cas de test [4, 4]doit être supprimé, car nous ne pouvons jamais obtenir ce tableau après une séquence stretch => crush, car cela se terminera par[8]
scottinet

Réponses:

2

JavaScript (Node.js) , 237 221 213 186 octets

f=a=>a.map(b=>{for(i=1;~b%2;b/=2)i*=2;return Array(i).fill(b)}).reduce((t,c,i,s)=>{b=c.slice();if(i)r=2*s[--i].length,b.length>=r&&b[0]==s[i][0]?b[r-2]+=b.pop():b;return t.concat(b)},[])

Essayez-le en ligne!

Cet algorithme calcule des tableaux étirés optimaux, en étirant chaque nombre au maximum, puis, si nécessaire, il écrase une paire de nombres au bon endroit, créant effectivement un "bloqueur d'écrasement", interrompant la séquence d'écrasement du nombre précédent.

Par exemple:

[1, 1, 1, 1, 1, 1]donne [4,2]une fois écrasé, mais se [1, 1, 1, 1, 2]traduit par[2, 4]

Le défi est de déterminer où exactement un bloqueur d'écrasement doit être placé afin que l'écrasement du tableau résultant donne le bon résultat:

  • Un bloqueur d'écrasement ne doit être placé que si le nombre étiré précédent est égal à celui actuel et si la séquence étirée actuelle est supérieure à la précédente. Par exemple,[2, 4] il faut un bloqueur d'écrasement (le nombre est étiré 1, répété, et [1, 1]est plus courte que [1,1,1,1]), mais [4, 2]et [2, 6]ne nécessitent pas un
  • si nous appelons nla séquence étirée précédente, et si la condition ci-dessus est vérifiée, alors la séquence actuelle est une répétition de la nséquence. Pour interrompre la séquence d'écrasement du numéro précédent, nous devons placer le bloqueur d'écrasement à la fin de la deuxième nséquence du numéro actuel à étirer. Exemple:, [2, 8] => [(1, 1)=n, (1, 1) + (2) + (1, 1) + ...]ou[4, 8] => [(1, 1, 1, 1)=n, (1, 1, 1, 1) + (1, 1, 2) + ...]
scottinet
la source
1

Gelée , 42 octets

ṪḤ,⁼?⁹⁸;µ/Ḋ$¹L’$?ÐĿċ³
ṗЀ⁸ẎS⁼¥Ðfµ€ŒpẎ€ÇÐfṪ

Essayez-le en ligne!

Programme complet. Extrêmement inefficace, mais fonctionne.

Erik le Outgolfer
la source
1

Python 2 , 230 228 226 octets

Fonctionne en itérant toutes les listes possibles avec la même somme que celle en entrée. Suppression de ceux qui ne sont pas égaux au tableau d'entrée dans un état écrasé, en sélectionnant le plus long.

Modifier: -2 octets en supprimant leif dans la fonction principale

Modifier: -2 octets en supprimant deux crochets inutiles

lambda x:max((c(z[:],x),len(z),z)for z in b(sum(x)))[2]
def c(x,y):
 i=e=1
 while x[i:]:
	if x[~-i]==x[i]:del x[i];i-=1;x[i]*=2;e=2
	i+=1
 return x==y or~-e and c(x,y)
b=lambda s:[z+[-~i]for i in range(s)for z in b(s+~i)]+[[]]

Essayez-le en ligne!

Explication

Fonction principale, chargée de trouver toutes les solutions possibles et de sélectionner la plus longue

lambda x:max((c(z[:],x),len(z),z)for z in b(sum(x)))[2]

Fonction d'écrasement, qui vérifie si y est égal à l'un des écrasements.

def c(x,y):
 i=e=1
 while x[i:]:
	if x[~-i]==x[i]:del x[i];i-=1;x[i]*=2;e=2
	i+=1
 return x==y or~-e and c(x,y)

Générer toutes les permutations possibles avec la somme donnée

b=lambda s:[z+[-~i]for i in range(s)for z in b(s+~i)]+[[]]
Halvard Hummel
la source
0

05AB1E , 41 37 octets

vy[DÉ#2÷]DYQX©NoDU‹&sDV¸X∍sić·®·Íǝ}»,

Essayez-le en ligne!

Port de ma solution Javascript.

Explications:

vy                   for each member of the list
[DÉ#2÷]              divide by 2 until odd: stack = stretched value, N = iterations
DYQ                  stetched value equal to the previous one?
X©NoDU‹              previous size < current one? (+store the new size in X)
&                    AND on the 2 previous tests
sDV¸X∍s              build a list of the new stretched value repeated X times
                      (+store the new stetched value in Y)
ić·®·Íǝ}             if the previous tests are true:
                       reduce the result list size by 1
                       multiply by 2 the number at the crush block position
»,                   join by newline + print the list
scottinet
la source