Magnetic pull in a array


20

sfondo

Ho una fila di potenti magneti e un mucchio di oggetti metallici tra di loro. Dove li tireranno i magneti?

Ingresso

Il tuo input è un array di numeri interi non negativi, che conterrà almeno uno 1. Puoi usare qualsiasi formato ragionevole.

Le 0s della matrice rappresentano lo spazio vuoto e le 1s rappresentano i magneti fissi. Tutti gli altri numeri sono oggetti di metallo, che vengono tirati dai magneti. Ogni oggetto viene tirato verso il magnete più vicino (se c'è un pareggio, l'oggetto viene tirato a destra), e viaggia in quella direzione fino a quando non colpisce il magnete o un altro oggetto. Alla fine, tutti gli oggetti si sono raggruppati attorno ai magneti. L'ordine degli oggetti viene preservato.

Produzione

Il tuo output è l'array in cui ogni oggetto è stato tirato il più vicino possibile al magnete più vicino. Dovrebbe avere lo stesso formato dell'input.

Esempio

Considera l'array

[0,0,2,0,1,1,0,2,0,3,0,5,0,1,0]

L'estrema sinistra 2viene tirata verso la prima coppia di magneti, così come la seconda 2. Il 3ha un magnete quattro passi in entrambe le direzioni, in modo che viene tirato verso destra. Anche 5viene tirato a destra e va tra il 3e il magnete. L'output corretto è

[0,0,0,2,1,1,2,0,0,0,0,3,5,1,0]

Regole e punteggio

È possibile scrivere un programma completo o una funzione. Vince il conteggio di byte più basso e non sono consentite scappatoie standard.

Casi test

[0,1,0] -> [0,1,0]
[1,0,2,0,0,1,0] -> [1,2,0,0,0,1,0]
[7,0,5,0,0,1,0] -> [0,0,0,7,5,1,0]
[1,0,3,0,1,0,3,0,1] -> [1,0,0,3,1,0,0,3,1]
[1,0,0,0,0,0,0,7,3] -> [1,7,3,0,0,0,0,0,0]
[1,2,3,4,5,6,7,8,9,10,11,0,0,0,1] -> [1,2,3,4,5,6,7,0,0,0,8,9,10,11,1]
[12,3,0,0,1,0,1,3,0,0,6,12,0,0,0,1] -> [0,0,12,3,1,0,1,3,6,0,0,0,0,0,12,1]

Risposte:


7

Pyth, 28 20

o@.e?bhaDk_x1QkQ~hZQ

Grazie @ThomasKwa per il golf 6 byte!

Questo abusa dell'ordinamento stabile assegnando a tutti i valori 1 o maggiori nell'elenco l'indice del 1 più vicino (legami rotti sull'estrema destra) e quindi ordinando l'elenco in base a questi valori. Agli zeri viene assegnato il proprio indice come valore di ordinamento.

Test Suite

Suite di verifica

Spiegazione:

o@.e?bhaDk_x1QkQ~hZQ  ##  implicit: Q = eval(input())
o                  Q  ##  Sort Q using the values of the lambda below
 @              ~hZ   ##  select the value from the matching index of the enumerate
  .e           Q      ##  enumerate with b = value, k = index
    ?b                ##  ternary on b
      haDk_x1Q        ##  if true, this thing
              k       ##  otherwise use the index as the sort weight
          _x1Q        ##  the indices of 1 in Q, given in reverse order 
                      ##  (the reverse makes it sort to the right because of stable sorts)
       aDk            ##  sort those indices by |index - k|
      h               ##  take the first value

Esempio:

Prendi il caso di prova [1,0,3,0,1,0,3,0,1], per esempio. Quando applichiamo l'enumerazione, gli zeri avranno tutti il ​​proprio indice come valore di ordinamento, quindi li salterò e farò uno e tre.

Per il primo, otteniamo gli indici di quelli: [0, 4, 8]. Quindi invertilo e ordina in base al valore assoluto degli indici meno l'indice di quello, che risulta essere zero qui. Quindi [0, 4, 8]torniamo di nuovo. Il primo valore è 0quindi lo usiamo.

Per i tre, otteniamo gli indici invertiti e facciamo lo stesso ordinamento ma usandone due come indice dei tre, quindi sia 0e che 4danno lo stesso valore per la differenza assoluta, quindi otteniamo: [4, 0, 8]e prendiamo il 4.

Quindi sarà l'array "valori di ordinamento" finale [0, 1, 4, 3, 4, 5, 8, 7, 8]. Grazie all'ordinamento stabile, i legami sono interrotti dall'ordine in cui i valori sono apparsi originariamente, quindi otteniamo l'array finale che vogliamo.


L'ordinamento per indice del più vicino 1è una bella idea!
Zgarb,

4

Retina , 97 72 byte

+`(?<=\b1(,1*)*?)(\B,(11+)|,(11+))\b(?!(?<-1>,1*)*,1\b)|(11+),\B
$3,$4$5

Si prevede che l'input sia un elenco separato da virgole di numeri interi unari (i delimitatori iniziali e finali come il [...]lavoro vanno bene).

Esegui tutti i casi di test qui. (Per comodità, questo si occupa automaticamente della conversione da e in decimale.)

Ecco un'idea completamente diversa che evita i costosi gruppi di bilanciamento utilizzando più fasi. Attualmente è più lungo di 6 byte, ma potrebbe essere più golfabile:

,1\b
>1
\b1,
1<
(T`,`<`<1*,
)T`,`>`,1*>
+`(1+>)>
>$1
+`<(<1+\b)(?!>)
$1<
<|>
,

Non appena ho visto questa sfida ho pensato che Retina sarebbe stata una buona scelta (+1)
Michael Klein,

@MichaelKlein Grazie, ma non credo proprio. Sono sorpreso che stia persino battendo JavaScript, ma sono abbastanza sicuro che non avrà alcuna possibilità contro nessuna delle lingue del golf.
Martin Ender,

In forma come in ho subito iniziato a pensare a come risolvere in Retina
Michael Klein il

3

JavaScript (ES6), 108 byte

a=>a.map(_=>a.map((x,i)=>x>1?a[j=(n=a.indexOf(1,i))<0|n-i>i-p?i-1:i+1]?0:a[a[i]=0,j]=x:x<1?0:p=i,p=-1/0))&&a

Spiegazione

Passa da una cella all'altra e, se contiene metallo, controlla se la cella successiva nella direzione del magnete più vicino è vuota e, se lo è, la sposta lì. Questo processo viene ripetuto molte volte fino a quando tutto il metallo si è spostato il più lontano possibile.

var solution =

a=>
  a.map(_=>                  // loop a.length times to ensure completeness
    a.map((x,i)=>            // for each cell item x at index i
      x>1?                   // if the cell contains metal
        a[j=                 // j = index of cell to move to
          (n=a.indexOf(1,i)) // n = index of next magnet
          <0|n-i>i-p?i-1:i+1 // set j to previous or next cell based on closest magnet
        ]?0:                 // if cell j is empty
          a[a[i]=0,j]=x      // set it to x and set cell i to 0
      :x<1?0:                // else if the cell contains a magnet
        p=i,                 // set p to the index of this magnet
      p=-1/0                 // p = index of previous magnet, initialise to -Infinity
    )
  )
  &&a                        // return a
<input type="text" id="input" value="1,2,3,4,5,6,7,8,9,10,11,0,0,0,1" />
<button onclick="result.textContent=solution(input.value.split(',').map(n=>+n))">Go</button>
<pre id="result"></pre>


2

PHP, 337 caratteri

<?$i=explode(",",$argv[1]);$m=$n=[];foreach($i as$k=>$v)if($v>0)eval("array_push(\$".($v<2?"m":"n").",$k);");for($p=0;$p<count($i);$p++)foreach($i as$k=>$v)if($v>1){$i[$k]=0;$r=-1;foreach($m as$_)if($r<0||abs($k-$r)>abs($_-$k))$r=$_;while($i[$r]>0)$r+=($r<$k?1:-1);$i[$r]=$v;}$s="";foreach($i as$v)$s.=$v.",";echo substr($s,0,-1)."\n";?>

Sì, questo è molto lungo, perché PHP non è davvero un linguaggio per giocare a golf, ma funziona e mi sono divertito a farlo, quindi per me va bene. Naturalmente sono aperto a possibili carenze.

Inoltre c'è una piccola funzionalità di bug che pensa, quindi ad esempio qui:

root@raspberrypi:~/stack# php magnet.php 12,3,0,0,1,0,1,3,0,0,6,12,0,0,0,1
0,0,3,12,1,0,1,3,6,0,0,0,0,0,12,1

sembra che i 12 siano magicamente messi di fronte ai 3, ma non è vero!

Il 3 rispetta il numero più grande e lo lascia avvicinarsi alla magia!

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.