Allunga un array


13

In precedenza ho definito il processo di frantumazione di un array

In una cotta leggiamo l'array da sinistra a destra. Se ad un certo punto incontriamo due dello stesso elemento di fila rimuoviamo il primo e raddoppiamo il secondo.

Ad esempio, ecco il processo di compressione del seguente array

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

Si noti che lo stesso elemento può essere compresso più volte. Nell'esempio è 2,2,4stato compresso in 8un unico passaggio.

Ora schiacciare le matrici è facile, ciò che è difficile le sta schiacciando. Il tuo compito è prendere una matrice di numeri interi positivi come input e produrre la matrice più grande che può formare l'input quando viene schiacciata ripetutamente. Ad esempio l'array [4]è formato dalla frantumazione [2,2]che a sua volta è formata dalla frantumazione[1,1,1,1] . Dal momento che non possiamo avere valori non interi non [1,1,1,1]possono essere ulteriormente decompressi e quindi è la nostra risposta.

Non riceverai mai un 0 nel tuo array di input perché tali array possono essere espansi indefinitamente. Inoltre non riceverai mai un caso con due dello stesso numero dispari uno accanto all'altro, tali casi non possono essere il risultato di uno schiacciamento.

Questo è quindi le risposte verranno valutate con la dimensione della loro sorgente misurata in byte con meno byte migliori.

Prima di iniziare a rispondere, voglio solo dire che questa sfida è significativamente più difficile di quanto sembri. Controlla l'intuizione mentre procedi e assicurati che la tua risposta superi tutti i casi di test.

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

1
Scusa ma non riesco ancora a capire la regola. perché [1,1,1,1,1,1,1,1,1,1,2]produrre [4, 8]invece di [8, 4]? questo dovrebbe essere [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 Penso che tu abbia un'idea sbagliata del modo in cui funziona lo schiacciamento. Ecco il percorso prende primo passaggio: [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>], secondo passaggio: [2,>2,2,2,4], [4,>2,2,4], [4,2,>2,4], [4,4,>4], [4,8>]. Spero che questo chiarisca. Se desideri che un codice per esaminare la domanda precedente abbia delle risposte che implementano una funzione di compressione.
Post Rock Garf Hunter,

Va bene se produco numeri, ognuno separato da una nuova riga?
scottinet,

@scottinet Questo è un modo ragionevole per generare un elenco. Vai avanti.
Post Rock Garf Hunter,

Il caso di test [4, 4]dovrebbe essere rimosso, poiché non potremo mai ottenere quell'array dopo una sequenza di stiramento =>, poiché questo finirà con[8]
scottinet,

Risposte:


2

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

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

Provalo online!

Questo algoritmo calcola le matrici allungate ottimali, allungando ogni numero al massimo, quindi, se necessario, ridimensiona una coppia di numeri nel posto giusto, creando in modo efficace un "blocco di schiacciamento", interrompendo la sequenza di schiacciamento del numero precedente.

Per esempio:

[1, 1, 1, 1, 1, 1][4,2]una volta schiacciato, ma [1, 1, 1, 1, 2]risulta in[2, 4]

La sfida consiste nel determinare esattamente dove posizionare un dispositivo di blocco per schiacciamento in modo tale che lo schiacciamento dell'array risultante dia il risultato giusto:

  • Un bloccatore di schiacciamento deve essere posizionato solo se il numero allungato precedente è uguale a quello corrente e se la sequenza allungata corrente è maggiore di quella precedente. Per esempio,[2, 4] richiede un bloccante cotta (il numero è allungato 1, ripetuto, e [1, 1]è più corta [1,1,1,1]), ma [4, 2]e [2, 6]non richiedono una
  • se chiamiamo nla sequenza allungata precedente e se la condizione sopra è verificata, la sequenza corrente è una ripetizione della nsequenza. Per interrompere la sequenza di compressione del numero precedente, è necessario posizionare il blocco della compressione alla fine della seconda nsequenza del numero corrente per allungare. Esempio: [2, 8] => [(1, 1)=n, (1, 1) + (2) + (1, 1) + ...]o[4, 8] => [(1, 1, 1, 1)=n, (1, 1, 1, 1) + (1, 1, 2) + ...]


1

Python 2 , 230 228 226 byte

Funziona ripetendo tutti gli elenchi possibili con la stessa somma di quello di input. Rimozione di quelli che non corrispondono all'array di input in uno stato ridotto, selezionando quello più lungo.

Modifica: -2 byte rimuovendo la iffunzione principale

Modifica: -2 byte rimuovendo due parentesi quadre non necessarie

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

Provalo online!

Spiegazione

Funzione principale, responsabile della ricerca di tutte le possibili soluzioni e della selezione della più lunga

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

Funzione di schiacciamento, che controlla se y è uguale a uno degli schiacciamenti.

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)

Genera tutte le possibili permutazioni con la somma indicata

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

0

05AB1E , 41 37 byte

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

Provalo online!

Porta della mia soluzione Javascript.

spiegazioni:

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