Il topo affamato


85

Sedici pile di formaggio vengono messe su un quadrato 4x4. Sono etichettati da a . La pila più piccola è e la più grande è .116116

Il topo affamato è così affamato che va sempre dritto alla pila più grande (cioè ) e lo mangia subito.16

Dopodiché, va nel più grande mucchio vicino e mangia rapidamente anche quello. (Sì ... è davvero affamato.) E così via fino a quando non ci sono più pile vicine.

Una pila può avere fino a 8 vicini (orizzontale, verticale e diagonale). Non c'è avvolgente.

Esempio

Iniziamo con le seguenti pile di formaggio:

37105681213159114141162

Il topo affamato mangia prima , quindi il suo più grande mucchio vicino, che è .1611

37105681213159🐭41412

Le sue prossime mosse sono , , , , , , , , e in questo preciso ordine.131210815149673

🐭5412

Non c'è più formaggio attorno all'Hungry Mouse, quindi si ferma qui.

La sfida

Data la configurazione iniziale del formaggio, il codice deve stampare o restituire la somma delle pile rimanenti una volta che il mouse affamato ha smesso di mangiarle.

Per l'esempio sopra, la risposta prevista è .12

Regole

  • Poiché la dimensione della matrice di input è fissa, è possibile utilizzarla come matrice 2D o matrice monodimensionale.
  • Ogni valore da a è garantito per apparire esattamente una volta.116
  • Questo è .

Casi test

[ [ 4,  3,  2,  1], [ 5,  6,  7,  8], [12, 11, 10,  9], [13, 14, 15, 16] ] --> 0
[ [ 8,  1,  9, 14], [11,  6,  5, 16], [13, 15,  2,  7], [10,  3, 12,  4] ] --> 0
[ [ 1,  2,  3,  4], [ 5,  6,  7,  8], [ 9, 10, 11, 12], [13, 14, 15, 16] ] --> 1
[ [10, 15, 14, 11], [ 9,  3,  1,  7], [13,  5, 12,  6], [ 2,  8,  4, 16] ] --> 3
[ [ 3,  7, 10,  5], [ 6,  8, 12, 13], [15,  9, 11,  4], [14,  1, 16,  2] ] --> 12
[ [ 8,  9,  3,  6], [13, 11,  7, 15], [12, 10, 16,  2], [ 4, 14,  1,  5] ] --> 34
[ [ 8, 11, 12,  9], [14,  5, 10, 16], [ 7,  3,  1,  6], [13,  4,  2, 15] ] --> 51
[ [13, 14,  1,  2], [16, 15,  3,  4], [ 5,  6,  7,  8], [ 9, 10, 11, 12] ] --> 78
[ [ 9, 10, 11, 12], [ 1,  2,  4, 13], [ 7,  8,  5, 14], [ 3, 16,  6, 15] ] --> 102
[ [ 9, 10, 11, 12], [ 1,  2,  7, 13], [ 6, 16,  4, 14], [ 3,  8,  5, 15] ] --> 103

32
+1 per quel personaggio del mouse
Luis Mendo,

2
... fai che 103:[[9, 10, 11, 12], [1, 2, 7, 13], [6, 16, 4, 14], [3, 8, 5, 15]]
Jonathan Allan il

9
Che sfida ben scritta! Lo terrò a mente per le nomination migliori.
xnor

9
Dopo aver letto male ero un po 'triste che questo non fosse un alce affamato.
akozi,

1
Questa sfida mi ricorda il mouse nel programma labirinto per il computer txo. Questo gioco è stato scritto negli anni '50 e il txo è stato il primo computer transistorizzato al mondo, secondo la leggenda. Sì, che ci crediate o no, qualcuno stava scrivendo videogiochi ai tempi di tuo nonno.
Walter Mitty,

Risposte:


11

Python 2 , 133 130 byte

a=input();m=16
for i in range(m):a[i*5:i*5]=0,
while m:i=a.index(m);a[i]=0;m=max(a[i+x]for x in[-6,-5,-4,-1,1,4,5,6])
print sum(a)

Provalo online!

Prende un elenco appiattito di 16 elementi.

Come funziona

a=input();m=16

# Add zero padding on each row, and enough zeroes at the end to avoid index error
for i in range(m):a[i*5:i*5]=0,

# m == maximum element found in last iteration
# i == index of last eaten element
# eaten elements of `a` are reset to 0
while m:i=a.index(m);a[i]=0;m=max(a[i+x]for x in[-6,-5,-4,-1,1,4,5,6])
print sum(a)

L'espressione della cella adiacente a[i+x]for x in[-6,-5,-4,-1,1,4,5,6]può essere abbreviata in a[i+j+j/3*2-6]for j in range(9)(la voce zero è innocua). Python 3 può sicuramente abbreviare codificando una lunghezza di 8 bytestring, ma Python 2 potrebbe comunque essere complessivamente migliore.
xnor

1
Anche se il ciclo padding zero è intelligente, sembra che sia più breve per fare una lista 2D: a=[0]*5 for r in input():a=r+[0]+a. Forse esiste una soluzione di taglio delle stringhe ancora più breve che non richiede iterazioni.
xnor

8

Python 2 , 111 byte

i=x=a=input()
while x:x,i=max((y,j)for j,y in enumerate(a)if i>[]or 2>i/4-j/4>-2<i%4-j%4<2);a[i]=0
print sum(a)

Provalo online!

Metodo e casi di test adattati da Bubbler . Prende un elenco semplice su STDIN.

Il codice controlla se due indici piatti ie jrappresentano celle toccanti controllando che sia la differenza di riga sia la differenza di i/4-j/4colonna i%4-j%4siano strettamente comprese tra -2 e 2. Il primo passaggio ha invece questo controllo automaticamente eseguito in modo che la voce più grande venga trovata ignorando l'adiacenza.


8

MATL , 50 49 47 byte

16:HZ^!"2G@m1ZIm~]v16eXK68E16b"Ky0)Y)fyX-X>h]s-

L'input è una matrice, che utilizza ;come separatore di riga.

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

16:HZ^!  % Cartesian power of [1 2 ... 16] with exponent 2, transpose. Gives a 
         % 2-row matrix with 1st column [1; 1], 2nd [1; 2], ..., last [16; 16] 
"        % For each column, say [k; j]
  2      %   Push 2
  G@m    %   Push input matrix, then current column [k; j], then check membership.
         %   This gives a 4×4 matrix that contains 1 for entries of the input that
         %   contain k or j 
  1ZI    %   Connected components (based on 8-neighbourhood) of nonzero entries.
         %   This gives a 4×4 matrix with each connected component labeled with
         %   values 1, 2, ... respectively
  m~     %   True if 2 is not present in this matrix. That means there is only
         %   one connected component; that is, k and j are neighbours in the
         %   input matrix, or k=j
]        % End
v16e     % The stack now has 256 values. Concatenate them into a vector and
         % reshape as a 16×16 matrix. This matrix describes neighbourhood: entry 
         % (k,j) is 1 if values k and j are neighbours in the input or if k=j
XK       % Copy into clipboard K
68E      % Push 68 times 2, that is, 136, which is 1+2+...+16
16       % Push 16. This is the initial value eaten by the mouse. New values will
         % be appended to create a vector of eaten values
b        % Bubble up the 16×16 matrix to the top of the stack
"        % For each column. This just executes the loop 16 times
  K      %   Push neighbourhood matrix from clipboard K
  y      %   Copy from below: pushes a copy of the vector of eaten values
  0)     %   Get last value. This is the most recent eaten value
  Y)     %   Get that row of the neighbourhood matrix
  f      %   Indices of nonzeros. This gives a vector of neighbours of the last
         %   eaten value
  y      %   Copy from below: pushes a copy of the vector of eaten values
  X-     %   Set difference (may give an empty result)
  X>     %   Maximum value. This is the new eaten value (maximum neighbour not
         %   already eaten). May be empty, if all neighbours are already eaten
  h      %   Concatenate to vector of eaten values
]        % End
s        % Sum of vector of all eaten values
-        % Subtract from 136. Implicitly display

Idk MatLab, ma puoi risparmiare un po 'se premi -136 invece di +136?
Tito

@Titus Hm non vedo come
Luis Mendo il

o viceversa: ho pensato invece di 1) spingere 136 2) spingere ogni valore mangiato 3) sommare i valori mangiati 4) sottrarre da 136 -> 1) spingere 136 2) spingere negativo del valore mangiato 3) sommare la pila. Ma dato che ovviamente è solo un byte ciascuno; probabilmente non è un guadagno.
Tito

@Titus Ah, sì, penso che usi lo stesso numero di byte. Inoltre, ho bisogno di ogni valore consumato (non negativo) per la differenza impostata; la negazione dovrebbe essere fatta alla fine
Luis Mendo il

6

PHP, 177 174 171 byte

for($v=16;$v;$u+=$v=max($p%4-1?max($a[$p-5],$a[$p-1],$a[$p+3]):0,$a[$p-4],$a[$p+4],$p%4?max($a[$p-3],$a[$p+1],$a[$p+5]):0))$a[$p=array_search($v,$a=&$argv)]=0;echo 120-$u;

Esegui con -nr, fornisce elementi matrice come argomenti o provalo online .


5

JavaScript, 122 byte

Ho fatto più di un paio di svolte sbagliate su questo e ora ho finito il tempo per giocare a golf, ma almeno funziona. Torneremo domani (o, conoscendomi, sul treno per stasera!), Se riesco a trovare un minuto.

a=>(g=n=>n?g([-6,-5,-4,-1,1,4,5,6].map(x=>n=a[x+=i]>n?a[x]:n,a[i=a.indexOf(n)]=n=0)|n)-n:120)(16,a=a.flatMap(x=>[...x,0]))

Provalo online


3
+1 per flatMap(): p
Arnauld

: DI pensa che sia la prima volta che lo uso per il golf! Per interesse (e per darmi un obiettivo quando torno a questo), qual è stato il tuo punteggio quando l'hai provato?
Shaggy,

Non ho avuto un minuto per tornare a questo oggi. Spero che questo significhi che potrò ricominciare da capo con occhi completamente nuovi domani.
Shaggy,

Ho pubblicato la mia soluzione.
Arnauld,

5

R , 128 124 123 112 110 byte

function(r){r=rbind(0,cbind(0,r,0),0)
m=r>15
while(r[m]){r[m]=0
m=r==max(r[which(m)+c(7:5,1)%o%-1:1])}
sum(r)}

Provalo online!

Crea una matrice 4x4 (che mi ha aiutato a visualizzare le cose), lo riempie di 0, quindi inizia da 16 e cerca le "pile" circostanti per il prossimo più grande, e così via.

Al termine, genera un avviso, ma non ha conseguenze e non modifica il risultato.

EDIT: -4 byte comprimendo l'inizializzazione della matrice in 1 riga.

EDIT: -1 grazie a Robert Hacken

EDIT: -13 byte combinando i suggerimenti di Giuseppe e Robin Ryder.


È possibile salvare un byte che cambia r==16per r>15.
Robert Hacken,

1
117 byte - cambiarlo in una funzione che prende una matrice e fare un aliasing con il which.
Giuseppe,

2
112 byte migliorando su suggerimento di @Giuseppe: è possibile memorizzare mcome un numero logico anziché intero, quindi è necessario chiamare solo whichuna volta anziché due volte.
Robin Ryder,

110 byte usando il golf di @RobinRyder e pasticciare con la compressione della matrice di adiacenza del quartiere.
Giuseppe,

1
@ Sumner18 X%o%Yè un alias per outer(X,Y,'*'). outerè una delle funzioni più utili in circolazione in quanto può funzionare come funzione "broadcast" di Octave / MATLAB / MATL con operatori aribtrari (vettorializzati). Vedi qui ; utile anche in rare occasioni è kroneckerche è collegato in quella pagina.
Giuseppe

4

Carbone , 47 byte

EA⭆ι§αλ≔QθW›θA«≔⌕KAθθJ﹪θ⁴÷θ⁴≔⌈KMθA»≔ΣEKA⌕αιθ⎚Iθ

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

EA⭆ι§αλ

Converti i numeri di input in caratteri alfabetici (A = 0 .. Q = 16) e stampali come una griglia 4x4.

≔Qθ

Inizia mangiando la Q, ovvero 16.

W›θA«

Ripeti finché c'è qualcosa da mangiare.

≔⌕KAθθ

Trova dove si trova la pila. Questa è una vista lineare in ordine di riga maggiore.

J﹪θ⁴÷θ⁴

Converti in coordinate e salta in quella posizione.

≔⌈KMθ

Trova la pila adiacente più grande.

Mangia la pila corrente.

≔ΣEKA⌕αιθ

Converti le pile in numeri interi e prendi la somma.

⎚Iθ

Cancella la tela e stampa il risultato.


3

Powershell, 143 141 136 130 122 121 byte

$a=,0*5+($args|%{$_+0})
for($n=16;$i=$a.IndexOf($n)){$a[$i]=0
$n=(-1,1+-6..-4+4..6|%{$a[$i+$_]}|sort)[-1]}$a|%{$s+=$_}
$s

Script di test meno golfato:

$f = {

$a=,0*5+($args|%{$_+0})
for($n=16;$i=$a.IndexOf($n)){
    $a[$i]=0
    $n=(-1,1+-6..-4+4..6|%{$a[$i+$_]}|sort)[-1]
}
$a|%{$s+=$_}
$s

}

@(
    ,( 0  , ( 4,  3,  2,  1), ( 5,  6,  7,  8), (12, 11, 10,  9), (13, 14, 15, 16) )
    ,( 0  , ( 8,  1,  9, 14), (11,  6,  5, 16), (13, 15,  2,  7), (10,  3, 12,  4) )
    ,( 1  , ( 1,  2,  3,  4), ( 5,  6,  7,  8), ( 9, 10, 11, 12), (13, 14, 15, 16) )
    ,( 3  , (10, 15, 14, 11), ( 9,  3,  1,  7), (13,  5, 12,  6), ( 2,  8,  4, 16) )
    ,( 12 , ( 3,  7, 10,  5), ( 6,  8, 12, 13), (15,  9, 11,  4), (14,  1, 16,  2) )
    ,( 34 , ( 8,  9,  3,  6), (13, 11,  7, 15), (12, 10, 16,  2), ( 4, 14,  1,  5) )
    ,( 51 , ( 8, 11, 12,  9), (14,  5, 10, 16), ( 7,  3,  1,  6), (13,  4,  2, 15) )
    ,( 78 , (13, 14,  1,  2), (16, 15,  3,  4), ( 5,  6,  7,  8), ( 9, 10, 11, 12) )
    ,( 102, ( 9, 10, 11, 12), ( 1,  2,  4, 13), ( 7,  8,  5, 14), ( 3, 16,  6, 15) )
    ,( 103, ( 9, 10, 11, 12), ( 1,  2,  7, 13), ( 6, 16,  4, 14), ( 3,  8,  5, 15) )
) | % {
    $expected, $a = $_
    $result = &$f @a
    "$($result-eq$expected): $result"
}

Produzione:

True: 0
True: 0
True: 1
True: 3
True: 12
True: 34
True: 51
True: 78
True: 102
True: 103

Spiegazione:

Innanzitutto , aggiungi i bordi superiore e inferiore di 0 e crea un array monodimensionale:

0 0 0 0 0
# # # # 0
# # # # 0
# # # # 0
# # # # 0

     ↓

0 0 0 0 0 # # # # 0 # # # # 0 # # # # 0 # # # # 0

Powershell restituisce $nullse si tenta di ottenere il valore dietro la fine dell'array.

In secondo luogo , il loop è biggest neighbor pileiniziato da 16 a un massimo di zero. E annullalo (The Hungry Mouse lo mangia).

for($n=16;$i=$a.IndexOf($n)){
    $a[$i]=0
    $n=(-1,1+-6..-4+4..6|%{$a[$i+$_]}|sort)[-1]
}

Terzo , somma delle pile rimanenti.


3

SAS, 236 219 byte

Input su schede perforate, una riga per griglia (spazio separato), output stampato sul registro.

Questa sfida è leggermente complicata da alcune limitazioni degli array in SAS:

  • Non è possibile restituire gli indici di riga e colonna di un elemento corrispondente dall'array di passaggi di dati multidimensionale: è necessario trattare l'array come 1-d e quindi elaborarli autonomamente.
  • Se si supera il limite, SAS genera un errore e interrompe l'elaborazione anziché restituire null / zero.

aggiornamenti:

  • infile cards;Dichiarazione rimossa (-13)
  • Carattere jolly utilizzato a:per la definizione dell'array anziché a1-a16(-4)

golfed:

data;input a1-a16;array a[4,4]a:;p=16;t=136;do while(p);m=whichn(p,of a:);t=t-p;j=mod(m-1,4)+1;i=ceil(m/4);a[i,j]=0;p=0;do k=max(1,i-1)to min(i+1,4);do l=max(1,j-1)to min(j+1,4);p=max(p,a[k,l]);end;end;end;put t;cards;
    <insert punch cards here>
    ; 

Ungolfed:

data;                /*Produce a dataset using automatic naming*/
input a1-a16;        /*Read 16 variables*/
array a[4,4] a:;     /*Assign to a 4x4 array*/
p=16;                /*Initial pile to look for*/
t=136;               /*Total cheese to decrement*/
do while(p);         /*Stop if there are no piles available with size > 0*/
  m=whichn(p,of a:); /*Find array element containing current pile size*/
  t=t-p;             /*Decrement total cheese*/
  j=mod(m-1,4)+1;    /*Get column number*/
  i=ceil(m/4);       /*Get row number*/
  a[i,j]=0;          /*Eat the current pile*/
                     /*Find the size of the largest adjacent pile*/
  p=0;
  do k=max(1,i-1)to min(i+1,4);
    do l=max(1,j-1)to min(j+1,4);
      p=max(p,a[k,l]);
    end;
  end;
end;
put t;              /*Print total remaining cheese to log*/
                    /*Start of punch card input*/
cards; 
  4  3  2  1  5  6  7  8 12 11 10  9 13 14 15 16 
  8  1  9 14 11  6  5 16 13 15  2  7 10  3 12  4 
  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 
 10 15 14 11  9  3  1  7 13  5 12  6  2  8  4 16 
  3  7 10  5  6  8 12 13 15  9 11  4 14  1 16  2 
  8  9  3  6 13 11  7 15 12 10 16  2  4 14  1  5 
  8 11 12  9 14  5 10 16  7  3  1  6 13  4  2 15 
 13 14  1  2 16 15  3  4  5  6  7  8  9 10 11 12 
  9 10 11 12  1  2  4 13  7  8  5 14  3 16  6 15 
  9 10 11 12  1  2  7 13  6 16  4 14  3  8  5 15 
;                    /*End of punch card input*/
                     /*Implicit run;*/

1
+1 per l'uso di schede perforate in PPCG :)
GNiklasch,

3

Haskell , 163 byte

o f=foldl1 f.concat
r=[0..3]
q n=take(min(n+2)3).drop(n-1)
0#m=m
v#m=[o max$q y$q x<$>n|y<-r,x<-r,m!!y!!x==v]!!0#n where n=map(z<$>)m;z w|w==v=0|0<1=w
f=o(+).(16#)

Provalo online!

La ffunzione accetta l'input come un elenco di 4 elenchi di 4 numeri interi.

Leggermente ungolfed

-- helper to fold over the matrix
o f = foldl1 f . concat

-- range of indices
r = [0 .. 3]

-- slice a list (take the neighborhood of a given coordinate)
-- first we drop everything before the neighborhood and then take the neighborhood itself
q n = take (min (n + 2) 3) . drop (n - 1)

-- a step function
0 # m = m -- if the max value of the previous step is zero, return the map
v # m = 
    -- abuse list comprehension to find the current value in the map
    -- convert the found value to its neighborhood,
    -- then calculate the max cell value in it
    -- and finally take the head of the resulting list
    [ o max (q y (q x<$>n)) | y <- r, x <- r, m!!y!!x == v] !! 0 
       # n -- recurse with our new current value and new map
    where 
        -- a new map with the zero put in place of the value the mouse currently sits on 
        n = map (zero <$>) m
        -- this function returns zero if its argument is equal to v
        -- and original argument value otherwise
        zero w 
            | w == v = 0
            | otherwise = w

-- THE function. first apply the step function to incoming map,
-- then compute sum of its cells
f = o (+) . (16 #)

3

JavaScript (ES7), 97 byte

Accetta l'input come un array appiattito.

f=(a,s=p=136,m,d)=>a.map((v,n)=>v<m|(n%4-p%4)**2+(n-p)**2/9>d||(q=n,m=v))|m?f(a,s-m,a[p=q]=0,4):s

Provalo online!

Commentate

f = (                    // f= recursive function taking:
  a,                     // - a[] = flattened input array
  s =                    // - s = sum of cheese piles, initialized to 1 + 2 + .. + 16 = 136
      p = 136,           // - p = position of the mouse, initially outside the board
  m,                     // - m = maximum pile, initially undefined
  d                      // - d = distance threshold, initially undefined
) =>                     // 
  a.map((v, n) =>        // for each pile v at position n in a[]:
    v < m |              //   unless this pile is not better than the current maximum
    (n % 4 - p % 4) ** 2 //   or (n % 4 - p % 4)²
    + (n - p) ** 2 / 9   //      + (n - p)² / 9
    > d ||               //   is greater than the distance threshold:
    (q = n, m = v)       //     update m to v and q to n
  )                      // end of map()
  | m ?                  // if we've found a new pile to eat:
    f(                   //   do a recursive call:
      a,                 //     pass a[] unchanged
      s - m,             //     update s by subtracting the pile we've just eaten
      a[p = q] = 0,      //     clear a[q], update p to q and set m = 0
      4                  //     use d = 4 for all next iterations
    )                    //   end of recursive call
  :                      // else:
    s                    //   stop recursion and return s

Sì, non mi sarei mai avvicinato a questo!
Shaggy,


3

Java 10, 272 248 byte

m->{int r=0,c=0,R=4,C,M=1,x,y,X=0,Y=0;for(;R-->0;)for(C=4;C-->0;)if(m[R][C]>15)m[r=R][c=C]=0;for(;M!=0;m[r=X][c=Y]=0)for(M=-1,C=9;C-->0;)try{if((R=m[x=r+C/3-1][y=c+C%3-1])>M){M=R;X=x;Y=y;}}catch(Exception e){}for(var Z:m)for(int z:Z)M+=z;return M;}

Le celle sono controllate come nella mia risposta per la sfida All the single eights .
-24 byte grazie a @ OlivierGrégoire .

Provalo online.

Spiegazione:

m->{                       // Method with integer-matrix parameter and integer return-type
  int r=0,                 //  Row-coordinate for the largest number, starting at 0
      c=0,                 //  Column-coordinate for the largest number, starting at 0
      R=4,C,               //  Row and column indices (later reused as temp integers)
      M=1,                 //  Largest number the mouse just ate, starting at 1
      x,y,X=0,Y=0;         //  Temp integers
  for(;R-->0;)             //  Loop `R` in the range (4, 0]:
    for(C=4;C-->0;)        //   Inner loop `C` in the range (4, 0]:
      if(m[R][C]>15)       //    If the current cell is 16:
        m[r=R][c=C]        //     Set `r,c` to this coordinate
          =0;              //     And empty this cell
  for(;M!=0;               //  Loop as long as the largest number isn't 0:
      ;                    //    After every iteration:
       m[r=X][c=Y]         //     Change the `r,c` coordinates,
         =0)               //     And empty this cell
    for(M=-1,              //   Reset `M` to -1
        C=9;C-->0;)        //   Inner loop `C` in the range (9, 0]:
          try{if((R=       //    Set `R` to:
            m[x=r+C/3-1]   //     If `C` is 0, 1, or 2: Look at the previous row
                           //     Else-if `C` is 6, 7, or 8: Look at the next row
                           //     Else (`C` is 3, 4, or 5): Look at the current row
             [y=c+C%3-1])  //     If `C` is 0, 3, or 6: Look at the previous column
                           //     Else-if `C` is 2, 5, or 8: Look at the next column
                           //     Else (`C` is 1, 4, or 7): Look at the current column
               >M){        //    And if the number in this cell is larger than `M`
                 M=R;      //     Change `M` to this number
                 X=x;Y=y;} //     And change the `X,Y` coordinate to this cell
          }catch(Exception e){}
                           //    Catch and ignore ArrayIndexOutOfBoundsExceptions
                           //    (try-catch saves bytes in comparison to if-checks)
  for(var Z:m)             //  Then loop over all rows of the matrix:
    for(int z:Z)           //   Inner loop over all columns of the matrix:
      M+=z;                //    And sum them all together in `M` (which was 0)
  return M;}               //  Then return this sum as result

potresti non int r = c = X = Y = 0, R = 4, M = 1, x, y; ?
Serverfrog,

@Serverfrog Temo che non sia possibile quando si dichiarano le variabili in Java. Il tuo suggerimento mi ha dato l'idea di salvare un byte usando int r,c,R=4,M=1,x,y,X,Y;for(r=c=X=Y=0;, quindi, grazie. :)
Kevin Cruijssen il

1

J, 82 byte

g=.](]*{:@[~:])]_1}~[:>./]{~((,-)1 5 6 7)+]i.{:
[:+/[:(g^:_)16,~[:,0,~0,0,0,.~0,.]

Provalo online!

Ho intenzione di golf questo più domani, e forse scrivo una soluzione più J-ish simile a questo uno , ma ho pensato che mi piacerebbe provare l'approccio appiattito poiché non avevo fatto prima.


Hai davvero bisogno dell'estrema sinistra ]in g?
Galen Ivanov,

1
Grazie Galeno, hai ragione. È l'ultimo dei problemi con questo codice :) Ho una soluzione molto migliore che implementerò quando avrò tempo.
Giona il

1

Rosso , 277 byte

func[a][k: 16 until[t:(index? find load form a k)- 1
p: do rejoin[t / 4 + 1"x"t % 4 + 1]a/(p/1)/(p/2): 0
m: 0 foreach d[-1 0x-1 1x-1 -1x0 1x0 -1x1 0x1 1][j: p + d
if all[j/1 > 0 j/1 < 5 j/2 > 0 j/2 < 5 m < t: a/(j/1)/(j/2)][m: t]]0 = k: m]s: 0
foreach n load form a[s: s + n]s]

Provalo online!

È una soluzione davvero lunga e non ne sono contento, ma ho passato così tanto tempo a sistemarlo per funzionare in TIO (apparentemente ci sono molte differenze tra le versioni Win e Linux della versione stabile di Red), quindi lo pubblico comunque ...

Più leggibile:

f: func [ a ] [
    k: 16
    until [
        t: (index? find load form a n) - 1
        p: do rejoin [ t / 4 + 1 "x" t % 4 + 1 ]
        a/(p/1)/(p/2): 0
        m: 0
        foreach d [ -1 0x-1 1x-1 -1x0 1x0 -1x1 0x1 1 ] [
            j: p + d
            if all[ j/1 > 0
                    j/1 < 5
                    j/2 > 0
                    j/2 < 5 
                    m < t: a/(j/1)/(j/2)
            ] [ m: t ]
        ]
        0 = k: m
    ]
    s: 0
    foreach n load form a [ s: s + n ]
    s
]

1

Gelatina ,  31 30  29 byte

³œiⱮZIỊȦ
⁴ṖŒPŒ!€Ẏ⁴;ⱮṢÇƇṪ
FḟÇS

Dal momento che il metodo è troppo lento per essere eseguito entro gli anni '60 con il mouse a partire da 16questo, la avvia alle 9e limita la sua capacità in modo che sia in grado di mangiare solo 9se meno Provalo online! (quindi qui mangia 9, 2, 7, 4, 8, 6, 3se ne va 97).

Come?

³œiⱮZIỊȦ - Link 1, isSatisfactory?: list of integers, possiblePileChoice
³        - (using a left argument of) program's 3rd command line argument (M)
   Ɱ     - map across (possiblePileChoice) with:
 œi      -   first multi-dimensional index of (the item) in (M)
    Z    - transpose the resulting list of [row, column] values
     I   - get the incremental differences
      Ị  - insignificant? (vectorises an abs(v) <= 1 test)
       Ȧ - any and all? (0 if any 0s are present in the flattened result [or if it's empty])

⁴ṖŒPŒ!€Ẏ⁴;ⱮṢÇƇṪ - Link 2, getChosenPileList: list of lists of integers, M
⁴               - literal 16
 Ṗ              - pop -> [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
  ŒP            - power-set -> [[],[1],[2],...,[1,2],[1,3],...,[2,3,7],...,[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]]
      €         - for each:
    Œ!          -   all permutations
       Ẏ        - tighten (to a single list of all these individual permutations)
        ⁴       - (using a left argument of) literal 16
          Ɱ     - map across it with:
         ;      -   concatenate (put a 16 at the beginning of each one)
           Ṣ    - sort the resulting list of lists
             Ƈ  - filter keep those for which this is truthy:
            Ç   -   call last Link as a monad (i.e. isSatisfactory(possiblePileChoice)
              Ṫ - tail (get the right-most, i.e. the maximal satisfactory one)

FḟÇS - Main Link: list of lists of integers, M
F    - flatten M
  Ç  - call last Link (2) as a monad (i.e. get getChosenPileList(M))
 ḟ   - filter discard (the resulting values) from (the flattened M)
   S - sum

Ah sì, il power-set non è abbastanza!
Jonathan Allan,

2
@Arnauld - finalmente ho avuto un po 'di tempo per giocare a golf: D Questo dovrebbe funzionare, ma sarà (molto) troppo lento per correre al TIO con il test case che hai usato prima.
Jonathan Allan

Il voto negativo potrebbe fornire un feedback? Funziona, ha una spiegazione completa e chiara ed è anche la voce più breve al momento.
Jonathan Allan

Ho votato, ma data la O ((n ^ 2)!) Di questa risposta, vorrei che la sfida avesse richiesto tempo polinomiale.
Lirtosiast

1

Non è il mio miglior lavoro. Ci sono alcuni miglioramenti da fare, alcuni probabilmente fondamentali per l'algoritmo utilizzato: sono sicuro che può essere migliorato usando solo un int[], ma non sono riuscito a capire come elencare in modo efficiente i vicini in quel modo. Mi piacerebbe vedere una soluzione PowerShell che utilizza solo un array monodimensionale!

PowerShell Core , 348 byte

Function F($o){$t=120;$a=@{-1=,0*4;4=,0*4};0..3|%{$a[$_]=[int[]](-join$o[(3+18*$_)..(3+18*$_+13)]-split',')+,0};$m=16;while($m-gt0){0..3|%{$i=$_;0..3|%{if($a[$i][$_]-eq$m){$r=$i;$c=$_}}};$m=($a[$r-1][$c-1],$a[$r-1][$c],$a[$r-1][$c+1],$a[$r][$c+1],$a[$r][$c-1],$a[$r+1][$c-1],$a[$r+1][$c],$a[$r+1][$c+1]|Measure -Max).Maximum;$t-=$m;$a[$r][$c]=0}$t}

Provalo online!


Versione più leggibile:

Function F($o){
    $t=120;
    $a=@{-1=,0*4;4=,0*4};
    0..3|%{$a[$_]=[int[]](-join$o[(3+18*$_)..(3+18*$_+13)]-split',')+,0};
    $m=16;
    while($m-gt0){
        0..3|%{$i=$_;0..3|%{if($a[$i][$_]-eq$m){$r=$i;$c=$_}}};
        $m=($a[$r-1][$c-1],$a[$r-1][$c],$a[$r-1][$c+1],$a[$r][$c+1],$a[$r][$c-1],$a[$r+1][$c-1],$a[$r+1][$c],$a[$r+1][$c+1]|Measure -Max).Maximum;
        $t-=$m;
        $a[$r][$c]=0
    }
    $t
}


Oh sì, la cosa strana che ho notato è che provare a fare il (array|sort)[-1]invece di Measure -maxlavorare su PSv5, ma stava ottenendo risultati errati nel core. Non ho idea del perché.
Veskah

Sì, è strano. L'ho provato (0..10|sort)[-1]ma restituisce 10 su PSv5 ma 9 su PS Core. Questo perché lo tratta in ordine lessicografico anziché numerico. Peccato, quello.
Jeff Freeman,

Microsoft classica cambia le cose importanti.
Veskah

Sono d'accordo in questo caso. Non sono sicuro del motivo per cui PS Core Sort genera un array di int32 in un array di stringhe. Ma questo sta andando in rovina, quindi divagherò. Grazie per la ristrutturazione!
Jeff Freeman, il

1

C (gcc), 250 byte

x;y;i;b;R;C;
g(int a[][4],int X,int Y){b=a[Y][X]=0;for(x=-1;x<2;++x)for(y=-1;y<2;++y)if(!(x+X&~3||y+Y&~3||a[y+Y][x+X]<b))b=a[C=Y+y][R=X+x];for(i=x=0;i<16;++i)x+=a[0][i];return b?g(a,R,C):x;}
s(int*a){for(i=0;i<16;++i)if(a[i]==16)return g(a,i%4,i/4);}

Provalo online!

Nota: questa presentazione modifica l'array di input.

s()è la funzione da chiamare con un argomento di un mutabile int[16](che è lo stesso in memoria di un int[4][4], che è ciò che lo g()interpreta).

s()trova la posizione 16dell'array, quindi passa queste informazioni a g, che è una funzione ricorsiva che accetta una posizione, imposta il numero in quella posizione su 0, quindi:

  • Se c'è un numero positivo adiacente ad esso, ricorrere con la posizione del numero adiacente più grande

  • Altrimenti, restituisce la somma dei numeri nella matrice.


s(int*a){for(i=0;a[i]<16;++i);return g(a,i%4,i/4);}
RiaD,

se g restituisce la somma del mangiato non è necessario calcolare la somma in esso. Restituisci solo 16 * 17/2-g () alla fine di s
RiaD

puoi usare bit a bit o invece se logico o?
RiaD



1

Aggiungi ++ , 281 byte

D,f,@@,VBFB]G€=dbLRz€¦*bMd1_4/i1+$4%B]4 4b[$z€¦o
D,g,@@,c2112011022200200BD1€Ω_2$TAVb]8*z€kþbNG€lbM
D,k,@~,z€¦+d4€>¦+$d1€<¦+$@+!*
D,l,@@#,bUV1_$:G1_$:
D,h,@@,{l}A$bUV1_$:$VbU","jG$t0€obU0j","$t€iA$bUpVdbLRG€=€!z€¦*$b]4*$z€¦o
y:?
m:16
t:120
Wm,`x,$f>y>m,`m,$g>x>y,`y,$h>x>y,`t,-m
Ot

Provalo online!

Oof, questo è complicato.

Verifica tutti i casi di test

Come funziona

Per questa spiegazione, useremo l'input

M=[37105681213159114141162]

X1X16M4X4

  • f(X,M)4X4XMX=16Mf(X,M)=(4,3)

  • g(M,y)f(X,M)g(M,f(X,M))=11

    Questo implementa le due funzioni di supporto:

    K(X)

    l(M,y)

  • h(y,M)0

016120(1+2++14+15) .

0

0

  • f(y,m)16MX: =(4,3)
  • g(X,y)0 , se non ci sono nuovi vicini (che termina il ciclo while).
  • h(X,y)160 , affinché il passaggio precedente funzioni
  • t-m , rimuovendo quel valore dall'importo del valore totale.

Infine, output t , ovvero i valori rimanenti, non raccolti.


1

C # (.NET Core) , 258 byte

Senza LINQ. L'utilizzo di System.Collections.Generic è per la formattazione successiva - la funzione non lo richiede.

e=>{int a=0,b=0,x=0,y=0,j=0,k;foreach(int p in e){if(p>15){a=x=j/4;b=y=j%4;}j++;}e[x,y]=0;while(1>0){for(j=-1;j<2;j++)for(k=-1;k<2;k++){try{if(e[a+k,b+j]>e[x,y]){x=a+k;y=b+j;}}catch{}}if(e[x,y]<1)break;e[x,y]=0;a=x;b=y;}a=0;foreach(int p in e)a+=p;return a;}

Provalo online!


1

Perl 6 , 151 136 126 125 119 byte

{my@k=$_;my $a=.grep(16,:k)[0];while @k[$a] {@k[$a]=0;$a=^@k .grep({2>$a+>2-$_+>2&$a%4-$_%4>-2}).max({@k[$_]})};[+] @k}

Soluzione super squallida. Accetta input come array appiattito.

Provalo online!


1

Perl 5 -MList::Util=sum -p , 137 byte

splice@F,$_,0,0for 12,8,4;map{$k{++$,}=$_;$n=$,if$_&16}@F;map{map{$n=$_+$"if$k{$"+$_}>$k{$n}&&!/2|3/}-6..6;$k{$"=$n}=0}@F;$_=sum values%k

Provalo online!


1

K (ngn / k) , 49 byte

{{h[,x]:0;*>(+x+0,'1-!3 3)#h}\*>h::(+!4 4)!x;+/h}

Provalo online!

input ( x) è un array 1d

(+!4 4)!x un dizionario che associa coppie di corde ai valori di x

h:: assegnare a una variabile globale h

*> la chiave corrispondente al valore massimo

{ }\ ripetere fino alla convergenza, raccogliendo valori intermedi in un elenco

h[,x]:0 azzerare la posizione corrente

+x+0,'1-!3 3 posizioni vicine

( )#hfiltrali da hun dizionario più piccolo

*>quale vicino ha il valore massimo? diventa la posizione corrente per la nuova iterazione

+/hinfine, restituisce la somma dei hvalori rimanenti


1

Wolfram Language (Mathematica) , 124 115 byte

(p=#&@@Position[m=Join@@ArrayPad[#,1],16];Do[m[[p]]=0;p=MaximalBy[#&@@p+{0,-1,1,-5,5,-6,6,-7,7},m[[#]]&],16];Tr@m)&

Provalo online!

Questo prende un array 2D, lo riempie su ciascun lato, quindi lo appiattisce immediatamente in modo da non dover passare l'indicizzazione dei byte. L'unico costo è Join@@appiattire. Successivamente procede come di seguito.

Versione a 124 byte per un array 2D: provalo online!

Principalmente il mio lavoro, con un po 'derivato dalla risposta a 149 byte di J42161217 .

Ungolfed:

(p = #& @@ Position[m = #~ArrayPad~1,16];     m = input padded with a layer of 0s
                                              p = location of 16
Do[
    m = MapAt[0&,m,p];                        Put a 0 at location p
    p = #& @@ MaximalBy[                      Set p to the member of
        p+#& /@ Tuples[{0,-1,1},2],             {all possible next locations}
        m~Extract~#&],                        that maximizes that element of m,
                                              ties broken by staying at p+{0,0}=p.
16];                                        Do this 16 times.
Tr[Tr/@m]                                   Finally, output the sum of m.
)&
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.