Dehnen Sie ein Array


13

Früher habe ich den Prozess des Zerquetschens eines Arrays definiert

In einem Schwarm lesen wir das Array von links nach rechts. Wenn wir an einem Punkt zwei gleiche Elemente in einer Reihe antreffen, entfernen wir das erste und verdoppeln das zweite.

Hier ist zum Beispiel der Prozess des Zerquetschens des folgenden Arrays

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

Beachten Sie, dass dasselbe Element mehrmals reduziert werden kann. In dem Beispiel 2,2,4wurde 8in einem einzigen Durchgang zusammengefasst.

Jetzt ist es ganz einfach, Arrays zu zerkleinern. Ihre Aufgabe ist es, ein Array positiver Ganzzahlen als Eingabe zu verwenden und das größte Array auszugeben, das die Eingabe bilden kann, wenn es wiederholt zerkleinert wird. Beispielsweise wird die Anordnung [4]durch Zerkleinern gebildet, [2,2]das wiederum durch Zerkleinern gebildet wird [1,1,1,1]. Da wir keine ganzzahligen Werte haben [1,1,1,1]können, können wir sie nicht weiter auflösen und sind somit unsere Antwort.

0In Ihrem Eingabearray wird niemals ein angezeigt, da solche Arrays auf unbestimmte Zeit erweitert werden können. Sie werden auch niemals einen Fall mit zwei gleichen ungeraden Zahlen nebeneinander erhalten. Solche Fälle können nicht das Ergebnis einer Quetschung sein.

Dies ist daher werden Antworten mit der Größe ihrer Quelle in Byte bewertet, wobei weniger Byte besser sind.

Bevor Sie mit der Beantwortung beginnen, möchte ich nur sagen, dass diese Herausforderung wesentlich schwieriger ist, als es scheint. Überprüfen Sie Ihre Intuition und stellen Sie sicher, dass Ihre Antwort alle Testfälle besteht.

Testfälle

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

1
Entschuldigung, aber ich kann die Regel immer noch nicht verstehen. Warum [1,1,1,1,1,1,1,1,1,1,2]produzieren [4, 8]statt [8, 4]? sollte dies sein [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]?
Dienstag,

2
@tsh Ich denke, Sie haben ein Missverständnis in der Art und Weise, wie das Zerkleinern funktioniert. Hier ist der Weg , es ersten Durchlauf dauert: [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>], zweiter Durchlauf: [2,>2,2,2,4], [4,>2,2,4], [4,2,>2,4], [4,4,>4], [4,8>]. Hoffentlich klärt das alles auf. Wenn Sie möchten, dass sich ein Code die vorherige Frage ansieht, gibt es Antworten, die eine Brechfunktion implementieren.
Post Rock Garf Hunter

Ist es in Ordnung, Zahlen auszugeben, die jeweils durch einen Zeilenumbruch getrennt sind?
Scottinet

@scottinet Das ist eine sinnvolle Möglichkeit, eine Liste auszugeben. Gehen Sie geradeaus.
Post Rock Garf Hunter

Der Testfall [4, 4]sollte entfernt werden, da wir dieses Array nach einer Stretch => Crush-Sequenz nie mehr bekommen können, da dies mit[8]
scottinet

Antworten:


2

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

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)},[])

Probieren Sie es online!

Dieser Algorithmus berechnet optimal gedehnte Arrays, indem er jede Zahl bis zum Maximum dehnt und dann, falls erforderlich, ein Zahlenpaar an der richtigen Stelle zurückdrückt, wodurch effektiv ein "Crush-Blocker" erzeugt wird, der die Crush-Sequenz der vorhergehenden Zahl unterbricht.

Zum Beispiel:

[1, 1, 1, 1, 1, 1]gibt [4,2]einmal zerkleinert, [1, 1, 1, 1, 2]ergibt aber[2, 4]

Die Herausforderung besteht darin, zu bestimmen, wo genau ein Crush-Blocker platziert werden soll, damit das Zerkleinern des resultierenden Arrays das richtige Ergebnis liefert:

  • Ein Crush-Blocker muss nur platziert werden, wenn die vorherige gestreckte Zahl der aktuellen entspricht und die aktuelle gestreckte Sequenz größer ist als die vorherige. Zum Beispiel [2, 4]erfordert einen Crush - Blocker (die gestreckte Zahl ist 1, wiederholt und [1, 1]ist kürzer als [1,1,1,1]), aber [4, 2]und [2, 6]erfordert nicht eine
  • Wenn wir ndie vorherige gestreckte Sequenz aufrufen und die obige Bedingung überprüft wird, ist die aktuelle Sequenz eine Wiederholung der nSequenz. Um die Crush-Sequenz der vorherigen Nummer zu unterbrechen, müssen wir den Crush-Blocker am Ende der zweiten nSequenz der aktuellen Nummer platzieren, um sie zu dehnen. Beispiel: [2, 8] => [(1, 1)=n, (1, 1) + (2) + (1, 1) + ...]oder[4, 8] => [(1, 1, 1, 1)=n, (1, 1, 1, 1) + (1, 1, 2) + ...]


1

Python 2 , 230 228 226 Bytes

Arbeitet durch Iteration aller möglichen Listen mit der gleichen Summe wie die Eingabe einer. Entfernen Sie diejenigen, die in einem zerkleinerten Zustand nicht mit dem Eingabearray übereinstimmen, und wählen Sie das längste aus.

Edit: -2 Bytes durch Entfernen der ifin der Hauptfunktion

Bearbeiten: -2 Bytes durch Entfernen von zwei unnötigen eckigen Klammern

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

Probieren Sie es online!

Erläuterung

Hauptfunktion, verantwortlich für die Suche nach allen möglichen Lösungen und die Auswahl der längsten

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

Crush-Funktion, die prüft, ob y gleich einem der Crushs ist.

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)

Generiere alle möglichen Permutationen mit der angegebenen Summe

b=lambda s:[z+[-~i]for i in range(s)for z in b(s+~i)]+[[]]

0

05AB1E , 41 37 Bytes

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

Probieren Sie es online!

Port meiner Javascript-Lösung.

Erklärungen:

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.