O rato faminto

85

Dezesseis pilhas de queijo são colocadas em um quadrado 4x4. Eles são rotulados de a . A menor pilha é e a maior é .116116

O Hungry Mouse está com tanta fome que sempre vai direto para a pilha maior (ou seja, ) e a come imediatamente.16

Depois disso, ele vai para a maior pilha vizinha e rapidamente come essa também. (Sim ... Está com muita fome.) E assim por diante até não haver mais pilha vizinha.

Uma pilha pode ter até 8 vizinhos (horizontal, vertical e diagonal). Não há volta.

Exemplo

Começamos com as seguintes pilhas de queijo:

37105681213159114141162

O rato faminto come primeiro e, em seguida, sua maior pilha vizinha, que é .1611

37105681213159🐭41412

Seus próximos movimentos são , , , , , , , , e nesta ordem exata.131210815149673

🐭5412

Não há mais queijo ao redor do Hungry Mouse, então ele pára por aí.

O desafio

Dada a configuração inicial do queijo, seu código deve imprimir ou retornar a soma das pilhas restantes depois que o Hungry Mouse parar de comê-las.

Para o exemplo acima, a resposta esperada é .12

Regras

  • Como o tamanho da matriz de entrada é fixo, você pode considerá-lo como uma matriz 2D ou uma matriz unidimensional.
  • É garantido que cada valor de a apareça exatamente uma vez.116
  • Isso é .

Casos de teste

[ [ 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
Arnauld
fonte
32
+1 para o personagem do mouse
Luis Mendo
2
... faça isso 103:[[9, 10, 11, 12], [1, 2, 7, 13], [6, 16, 4, 14], [3, 8, 5, 15]]
Jonathan Allan
9
Que desafio bem escrito! Vou ter isso em mente para as melhores indicações.
Xnor
9
Depois de interpretar mal, fiquei um pouco triste por não ser um alce faminto.
akozi
1
Esse desafio me lembra o mouse no programa de labirinto do computador txo. Este jogo foi escrito nos anos 50, e o txo ​​foi o primeiro computador transistorizado do mundo, segundo a lenda. Sim, acredite ou não, alguém estava escrevendo videogame nos dias de seu avô.
Walter Mitty

Respostas:

11

Python 2 , 133 130 bytes

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)

Experimente online!

Leva uma lista nivelada de 16 elementos.

Como funciona

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)
Bubbler
fonte
A expressão da célula adjacente a[i+x]for x in[-6,-5,-4,-1,1,4,5,6]pode ser reduzida para a[i+j+j/3*2-6]for j in range(9)(a entrada zero é inofensiva). O Python 3 certamente pode ser mais curto codificando uma cadeia de 8 bytes de comprimento 8, mas o Python 2 ainda pode ser melhor no geral.
Xnor
1
Embora seu loop estofamento zero é inteligente, parece que ele é mais curto para tomar uma lista 2D: a=[0]*5 for r in input():a=r+[0]+a. Talvez exista uma solução de corte de cadeia ainda mais curta que não exija iteração.
Xnor
8

Python 2 , 111 bytes

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)

Experimente online!

Método e casos de teste adaptados do Bubbler . Leva uma lista simples em STDIN.

O código verifica se dois índices simples ie jrepresenta células em contato, verificando se a diferença de linha i/4-j/4e a coluna i%4-j%4estão estritamente entre -2 e 2. A primeira passagem, em vez disso, faz com que essa verificação seja bem-sucedida automaticamente, para que a maior entrada seja encontrada, independentemente da adjacência.

xnor
fonte
8

MATL , 50 49 47 bytes

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

Entrada é uma matriz, usando ;como separador de linhas.

Experimente online! Ou verifique todos os casos de teste .

Explicação

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
Luis Mendo
fonte
Idk MatLab, mas você pode economizar um pouco se pressionar -136 em vez de +136?
Titus
@Titus Hm eu não vejo como #
Luis Mendo
ou o contrário: pensei em vez de 1) empurrar 136 2) empurrar cada valor comido 3) somar valores comidos 4) subtrair de 136 -> 1) empurrar 136 2) empurrar negativo do valor comido 3) somar pilha. Mas como obviamente é de apenas um byte cada; provavelmente não há ganho.
Titus
@ Titus Ah, sim, acho que usa o mesmo número de bytes. Além disso, preciso de cada valor comido (não negativo) para a diferença definida; negação teria que ser feito no final
Luis Mendo
6

PHP, 177 174 171 bytes

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;

Corra com -nr, forneça elementos da matriz como argumentos ou tente online .

Titus
fonte
5

JavaScript, 122 bytes

Eu levei mais de duas voltas erradas nesta e agora estou sem tempo para jogar golfe, mas pelo menos está funcionando. Vou revisitar amanhã (ou, me conhecendo, no trem para casa hoje à noite!), Se eu conseguir encontrar um 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]))

Experimente online

Shaggy
fonte
3
+1 para flatMap(): p
Arnauld
: DI acho que é a primeira vez que o uso no golfe! Fora de interesse (e para me dar uma meta quando eu voltar a isso), qual foi sua pontuação quando você tentou?
Shaggy
Não tive um minuto para voltar a isso hoje. Espero que isso signifique que eu possa começar de novo com olhos completamente frescos amanhã.
Shaggy
Eu postei minha solução.
Arnauld
5

R , 128 124 123 112 110 bytes

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)}

Experimente online!

Ele cria uma matriz 4x4 (que me ajudou a visualizar as coisas), preenchê-la com zeros, depois começa a partir dos 16 e pesquisa suas pilhas ao redor das próximas maiores e assim por diante.

Na conclusão, ele gera um aviso, mas não tem conseqüências e não altera o resultado.

EDIT: -4 bytes compactando a inicialização da matriz em 1 linha.

EDIT: -1 graças a Robert Hacken

EDIT: -13 bytes combinando as sugestões de Giuseppe e Robin Ryder.

Sumner18
fonte
Você pode salvar um byte mudando r==16para r>15.
quer
1
117 bytes - altere para uma função que obtém uma matriz e faça algum alias com o which.
Giuseppe
2
112 bytes melhorando as sugestões de @ Giuseppe: você pode armazenar mcomo um lógico em vez de um número inteiro e, portanto, precisa chamar apenas whichuma vez em vez de duas vezes.
Robin Ryder
110 bytes usando o golfe do @RobinRyder e mexendo na compactação da matriz de adjacência do bairro.
Giuseppe
1
@ Sumner18 X%o%Yé um apelido para outer(X,Y,'*'). outeré uma das funções mais úteis, pois pode funcionar como o recurso "broadcast" do Octave / MATLAB / MATL com operadores arbitrários (vetorizados). Veja aqui ; também útil em raras ocasiões é o kroneckerlink dessa página.
Giuseppe
4

Carvão , 47 bytes

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

Experimente online! Link é a versão detalhada do código. Explicação:

EA⭆ι§αλ

Converta os números de entrada em caracteres alfabéticos (A = 0 .. Q = 16) e imprima-os como uma grade 4x4.

≔Qθ

Comece comendo o Q, ou seja, 16.

W›θA«

Repita enquanto houver algo para comer.

≔⌕KAθθ

Encontre onde está a pilha. Esta é uma vista linear na ordem principal da linha.

J﹪θ⁴÷θ⁴

Converter em coordenadas e pular para esse local.

≔⌈KMθ

Encontre a maior pilha adjacente.

Coma a pilha atual.

≔ΣEKA⌕αιθ

Converta as pilhas novamente em números inteiros e pegue a soma.

⎚Iθ

Limpe a tela e produza o resultado.

Neil
fonte
3

Powershell, 143 141 136 130 130 122 121 bytes

$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 de teste com menos golfe:

$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"
}

Resultado:

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

Explicação:

Primeiro , adicione as bordas superior e inferior de 0 e faça uma matriz dimensional única:

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

     ↓

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

O PowerShell retornará $nullse você tentar obter o valor atrás do final da matriz.

Segundo , o loop biggest neighbor pileiniciou de 16 para um valor diferente de zero. E anulá-lo (o rato faminto come).

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

Terceiro , soma das pilhas restantes.

confuso
fonte
3

SAS, 236 219 bytes

Entrada em cartões perfurados, uma linha por grade (separada por espaço), saída impressa no log.

Esse desafio é um pouco complicado por algumas limitações de matrizes no SAS:

  • Não há como retornar os índices de linha e coluna de um elemento correspondente a partir de uma matriz multidimensional de etapas de dados - você deve tratar a matriz como 1d e depois elaborá-los por conta própria.
  • Se você sair dos limites, o SAS emitirá um erro e interromperá o processamento em vez de retornar nulo / zero.

Atualizações:

  • infile cards;Declaração removida (-13)
  • Curinga usado a:para definição de matriz em vez de a1-a16(-4)

Golfe:

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;*/
user3490
fonte
1
+1 para o uso de cartões perfurados em PPCG :)
GNiklasch
3

Haskell , 163 bytes

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#)

Experimente online!

A ffunção recebe a entrada como uma lista de 4 listas de 4 números inteiros.

Ligeiramente não-destruído

-- 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 #)
Max Yekhlakov
fonte
3

JavaScript (ES7), 97 bytes

Recebe a entrada como uma matriz nivelada.

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

Experimente online!

Comentado

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
Arnauld
fonte
Sim, eu nunca teria chegado nem perto disso!
Shaggy
3

Java 10, 272 248 bytes

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;}

As células são verificadas da mesma forma que na minha resposta para o desafio Todos os oitavos .
-24 bytes graças a @ OlivierGrégoire .

Experimente online.

Explicação:

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
Kevin Cruijssen
fonte
você não poderia int r = c = X = Y = 0, R = 4, M = 1, x, y; ?
Serverfrog
@Serverfrog Acho que isso não é possível ao declarar as variáveis ​​em Java. Sua sugestão me deu uma idéia de salvar um byte, usando int r,c,R=4,M=1,x,y,X,Y;for(r=c=X=Y=0;, então obrigado. :)
Kevin Cruijssen
1

J, 82 bytes

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

Experimente online!

Eu pretendo golfe este mais amanhã, e talvez escrever uma solução mais J-ish semelhante a este um , mas eu percebi que eu tente a abordagem achatada desde que eu não tinha feito isso antes.

Jonah
fonte
Você realmente precisa de mais à esquerda ]em g?
Galen Ivanov #
1
Obrigado Galen, você está certo. É o menor dos problemas com esse código :) Eu tenho uma solução muito melhor que implementarei quando tiver tempo.
Jonah
1

Vermelho , 277 bytes

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]

Experimente online!

É uma solução realmente longa e eu não estou feliz com isso, mas gastei muito tempo corrigindo-o para trabalhar no TIO (aparentemente existem muitas diferenças entre as versões estáveis ​​do Red do Win e Linux), então eu a publico assim mesmo ...

Mais legível:

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
]
Galen Ivanov
fonte
1

Geléia ,  31 30  29 bytes

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

Como o método é muito lento para ser executado nos anos 60, com o mouse iniciado, 16ele a inicia 9e limita sua capacidade, de modo que ela é capaz de comer apenas 9s ou menos. Experimente on-line! (assim aqui ela come 9, 2, 7, 4, 8, 6, 3indo embora 97).

Quão?

³œ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
Jonathan Allan
fonte
Ah sim, power-set não é suficiente!
Jonathan Allan
2
@ Arnauld - finalmente consegui um pouco de tempo para jogar golfe: D Isso deve funcionar, mas será (muito) lento demais para rodar no TIO com o caso de teste que você usou antes.
Jonathan Allan
Poderia o eleitor rebaixado dar algum feedback? Isso funciona, tem uma explicação completa e clara e também é a entrada mais curta atualmente.
Jonathan Allan
Voto a favor, mas considerando o O ((n ^ 2)!) Dessa resposta, gostaria que o desafio exigisse tempo polinomial.
lirtosiast 6/06
1

Não é o meu melhor trabalho. Há algumas melhorias definitivas a serem feitas, algumas provavelmente fundamentais para o algoritmo usado - tenho certeza de que pode ser aprimorado usando apenas um int[], mas não consegui descobrir como enumerar vizinhos dessa maneira com eficiência. Eu adoraria ver uma solução do PowerShell que usa apenas uma matriz unidimensional!

Núcleo do PowerShell , 348 bytes

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}

Experimente online!


Versão mais legível:

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
}
Jeff Freeman
fonte
Ah, sim, a coisa estranha que notei é que tentar fazer o (array|sort)[-1]invés de Measure -maxtrabalhar no PSv5, mas estava obtendo resultados incorretos no núcleo. Não faço ideia do porquê.
Veskah 17/01
Sim, isso é estranho. Eu testei, (0..10|sort)[-1]mas ele retorna 10 no PSv5, mas 9 no PS Core. Isso ocorre porque ele é tratado em ordem lexicográfica em vez de numérica. Que vergonha.
Jeff Freeman
Microsoft clássico que muda as coisas importantes.
Veskah 17/01
Eu concordo neste caso. Não sei por que o PS Core Sort lança uma matriz de int32 para uma matriz de seqüências de caracteres. Mas, isso está se tornando um discurso retórico, então eu vou discordar. Obrigado pela reestruturação!
Jeff Freeman
1

C (gcc), 250 bytes

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);}

Experimente online!

Nota: Este envio modifica a matriz de entrada.

s()é a função para chamar com um argumento de um mutável int[16](que é o mesmo na memória que um int[4][4], que é o que o g()interpreta).

s()localiza a localização do 16na matriz e passa essas informações para g, que é uma função recursiva que obtém uma localização, define o número nesse local como 0 e, em seguida:

  • Se houver um número positivo adjacente, recorra à localização do maior número adjacente

  • Senão, retorne a soma dos números na matriz.

pizzapants184
fonte
s(int*a){for(i=0;a[i]<16;++i);return g(a,i%4,i/4);}
Riad
se g retornar soma de comido, não será necessário calcular a soma. Basta retornar 16 * 17/2-g () no final de s
RiaD 24/11
você pode usar bit a bit ou, se for lógico ou?
Riad
211 bytes
ceilingcat 31/12/19
1

Adicionar ++ , 281 bytes

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

Experimente online!

Oof, isso é complicado.

Verifique todos os casos de teste

Como funciona

Para esta explicação, usaremos a entrada

M=[37105681213159114141162]

x1x16M4x4

  • f(x,M)4x4xMx=16Mf(x,M)=(4,3)

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

    Isso implementa as duas funções auxiliares:

    k(x)

    eu(M,y)

  • h(y,M)0 0

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

0 0

0 0

  • f(y,m)16Mx: =(4,3)
  • g(x,y)0 0
  • h(x,y)160 0
  • t-m

Finalmente, produza t , ou seja, os valores restantes não coletados.

caird coinheringaahing
fonte
1

C # (.NET Core) , 258 bytes

Sem LINQ. O uso System.Collections.Generic é para a formatação posterior - a função não exige isso.

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;}

Experimente online!

Destroigo
fonte
1

Perl 6 , 151 136 126 125 119 bytes

{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}

Super solução surrada. Recebe a entrada como uma matriz achatada.

Experimente online!

bb94
fonte
1

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

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

Experimente online!

Xcali
fonte
1

K (ngn / k) , 49 bytes

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

Experimente online!

a entrada ( x) é uma matriz 1d

(+!4 4)!x um dicionário que mapeia pares de cordas para os valores de x

h:: atribuir a uma variável global h

*> a chave correspondente ao valor máximo

{ }\ repita até a convergência, coletando valores intermediários em uma lista

h[,x]:0 zere a posição atual

+x+0,'1-!3 3 posições vizinhas

( )#hfiltrá-los hcomo um dicionário menor

*>qual vizinho tem o valor máximo? torna-se a posição atual para a nova iteração

+/hfinalmente, retorne a soma dos hvalores restantes

ngn
fonte
1

Wolfram Language (Mathematica) , 124 115 bytes

(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)&

Experimente online!

Isso pega uma matriz 2D, junta-a de cada lado e a aplana imediatamente para que não tenhamos que gastar a indexação de bytes. O único custo para isso é Join@@achatar. Depois, procede como abaixo.

Versão de 124 bytes para uma matriz 2D: Experimente online!

Principalmente meu próprio trabalho, com um pouco derivado da resposta de 149 bytes de 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.
)&
lirtosiast
fonte