Tikus Lapar

85

Enam belas tumpukan keju diletakkan di atas kotak 4x4. Mereka dilabeli dari hingga . Tumpukan terkecil adalah dan yang terbesar adalah .116116

Tikus Lapar sangat lapar sehingga selalu langsung menuju tumpukan terbesar (yaitu ) dan langsung memakannya.16

Setelah itu, ia pergi ke tumpukan tetangga terbesar dan dengan cepat memakan yang satu juga. (Ya ... Ini benar - benar lapar.) Dan seterusnya sampai tidak ada tumpukan tetangga lagi.

Tumpukan mungkin memiliki hingga 8 tetangga (horizontal, vertikal dan diagonal). Tidak ada bungkus.

Contoh

Kita mulai dengan tumpukan keju berikut:

37105681213159114141162

Tikus Lapar pertama kali makan , dan kemudian tumpukan tetangganya yang terbesar, yaitu .1611

37105681213159🐭41412

Langkah selanjutnya adalah , , , , , , , , dan dalam urutan yang tepat ini.131210815149673

🐭5412

Tidak ada keju lagi di sekitar Tikus Lapar, jadi berhenti di sana.

Tantangan

Dengan konfigurasi keju awal, kode Anda harus mencetak atau mengembalikan jumlah tumpukan yang tersisa setelah Tikus Lapar berhenti memakannya.

Untuk contoh di atas, jawaban yang diharapkan adalah .12

Aturan

  • Karena ukuran matriks input ditetapkan, Anda dapat menganggapnya sebagai array 2D atau array satu dimensi.
  • Setiap nilai dari hingga dijamin akan muncul tepat sekali.116
  • Ini adalah .

Uji kasus

[ [ 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
sumber
32
+1 untuk karakter mouse itu
Luis Mendo
2
... buatlah 103:[[9, 10, 11, 12], [1, 2, 7, 13], [6, 16, 4, 14], [3, 8, 5, 15]]
Jonathan Allan
9
Sungguh tantangan yang ditulis dengan baik! Saya akan mengingatnya untuk nominasi best-of.
xnor
9
Setelah salah membaca, saya sedikit sedih karena ini bukan rusa besar yang lapar.
akozi
1
Tantangan ini mengingatkan saya pada mouse di program maze untuk komputer txo. Permainan ini ditulis pada tahun 1950-an, dan txo adalah komputer dengan transistor yang pertama di dunia, menurut legenda. Ya, percaya atau tidak, seseorang sedang menulis video game di zaman kakekmu.
Walter Mitty

Jawaban:

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)

Cobalah online!

Mengambil daftar rata dari 16 elemen.

Bagaimana itu bekerja

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
sumber
Ekspresi sel yang berdekatan a[i+x]for x in[-6,-5,-4,-1,1,4,5,6]dapat disingkat menjadi a[i+j+j/3*2-6]for j in range(9)(entri nol tidak berbahaya). Python 3 pasti bisa melakukan lebih pendek dengan melakukan hardcoding bytestring panjang-8, tetapi Python 2 mungkin masih lebih baik secara keseluruhan.
xnor
1
Meskipun Anda bantalan lingkaran nol pintar, sepertinya itu lebih pendek untuk mengambil daftar 2D: a=[0]*5 for r in input():a=r+[0]+a. Mungkin ada solusi mengiris string yang lebih pendek namun tidak memerlukan iterasi.
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)

Cobalah online!

Metode dan uji kasus diadaptasi dari Bubbler . Mengambil daftar datar di STDIN.

Kode memeriksa apakah dua indeks rata idan jmewakili sel sentuh dengan memeriksa bahwa kedua baris berbeda i/4-j/4dan perbedaan kolom i%4-j%4benar-benar antara -2 dan 2. Lewat pertama justru pemeriksaan ini berhasil secara otomatis sehingga entri terbesar ditemukan mengabaikan kedekatan.

Tidak
sumber
8

MATL , 50 49 47 byte

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

Input adalah sebuah matriks, menggunakan ;pemisah baris.

Cobalah online! Atau verifikasi semua kasus uji .

Penjelasan

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
sumber
Idk MatLab, tetapi bisakah Anda menghemat sedikit jika Anda menekan -136 alih-alih +136?
Titus
@Itus Hm Saya tidak mengerti bagaimana caranya
Luis Mendo
atau sebaliknya: saya pikir bukannya 1) tekan 136 2) tekan setiap nilai yang dimakan 3) jumlahkan nilai yang dimakan 4) kurangi dari 136 -> 1) tekan 136 2) tekan negatif dari nilai yang dimakan 3) jumlah tumpukan. Tetapi karena jelas hanya satu byte setiap; mungkin tidak ada untungnya.
Titus
@Itus Ah, ya, saya pikir itu menggunakan jumlah byte yang sama. Juga, saya perlu setiap nilai yang dimakan (bukan yang negatif) untuk perbedaan yang ditetapkan; meniadakan harus dilakukan pada akhirnya
Luis Mendo
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;

Jalankan dengan -nr, berikan elemen matriks sebagai argumen atau coba online .

Titus
sumber
5

JavaScript, 122 byte

Saya melakukan lebih dari beberapa kesalahan dalam hal ini dan sekarang saya kehabisan waktu untuk bermain golf lagi, tetapi setidaknya itu berhasil. Akan mengunjungi kembali besok (atau, mengenal saya, di rumah kereta malam ini!), Jika saya dapat menemukan satu menit.

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

Cobalah online

Shaggy
sumber
3
+1 untuk flatMap(): p
Arnauld
: Saya rasa ini adalah pertama kalinya saya menggunakannya untuk golf! Karena ketertarikan (dan untuk memberi saya target ketika saya kembali ke sini), berapa skor Anda ketika Anda mencobanya?
Shaggy
Tidak mendapatkan satu menit untuk kembali ke hari ini. Semoga itu berarti saya akan dapat memulai kembali dengan mata yang benar-benar segar besok.
Shaggy
Saya telah memposting solusi saya.
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)}

Cobalah online!

Ini menciptakan matriks 4x4 (yang membantu saya untuk memvisualisasikan hal-hal), membalutnya dengan 0, kemudian mulai dari 16 dan mencari di sekitarnya "tumpukan" untuk terbesar berikutnya, dan sebagainya.

Setelah menyimpulkan, itu memang mengeluarkan peringatan, tetapi tidak ada konsekuensi dan tidak mengubah hasilnya.

EDIT: -4 byte dengan mengompresi inisialisasi matriks menjadi 1 baris.

EDIT: -1 terima kasih kepada Robert Hacken

EDIT: -13 byte menggabungkan saran Giuseppe dan Robin Ryder.

Sumner18
sumber
Anda dapat menyimpan perubahan satu byte r==16untuk r>15.
Robert Hacken
1
117 bytes - ubah ke fungsi yang mengambil matriks dan lakukan aliasing dengan which.
Giuseppe
2
112 byte meningkat berdasarkan saran @Giuseppe: Anda dapat menyimpan msebagai logika alih-alih bilangan bulat, dan karenanya hanya perlu memanggil whichsatu kali, bukan dua kali.
Robin Ryder
110 byte menggunakan golf @RobinRyder dan bermain-main dengan mengompresi matriks adjacency lingkungan.
Giuseppe
1
@ Sumner18 X%o%Yadalah alias untuk outer(X,Y,'*'). outeradalah salah satu fungsi yang paling mudah digunakan karena dapat berfungsi sebagai fitur "broadcast" Octave / MATLAB / MATL dengan operator aribtrary (vectorized). Lihat di sini ; juga berguna pada kesempatan langka kroneckeryang terhubung di halaman itu.
Giuseppe
4

Arang , 47 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

EA⭆ι§αλ

Ubah angka input menjadi karakter alfabet (A = 0 .. Q = 16) dan cetaklah sebagai kisi 4x4.

≔Qθ

Mulailah dengan makan Q, yaitu 16.

W›θA«

Ulangi sementara ada sesuatu untuk dimakan.

≔⌕KAθθ

Temukan di mana tumpukan itu. Ini adalah tampilan linear dalam urutan baris-utama.

J﹪θ⁴÷θ⁴

Konversikan ke koordinat dan lompat ke lokasi itu.

≔⌈KMθ

Temukan tumpukan terdekat yang terbesar.

Makan tumpukan saat ini.

≔ΣEKA⌕αιθ

Ubah tumpukan menjadi bilangan bulat dan ambil jumlahnya.

⎚Iθ

Bersihkan kanvas dan hasilkan hasilnya.

Neil
sumber
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

Skrip uji yang kurang golf:

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

Keluaran:

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

Penjelasan:

Pertama , tambahkan batas atas dan bawah 0 dan buat array dimensi tunggal:

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

     ↓

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

Powershell kembali $nulljika Anda mencoba untuk mendapatkan nilai di belakang akhir array.

Kedua , loop biggest neighbor piledimulai dari 16 hingga non-nol-maksimum. Dan membatalkannya (Mouse Lapar memakannya).

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

Ketiga , jumlah tumpukan yang tersisa.

mazzy
sumber
3

SAS, 236 219 byte

Input pada kartu punch, satu baris per kisi (dipisahkan spasi), output dicetak ke log.

Tantangan ini sedikit rumit oleh beberapa batasan array di SAS:

  • Tidak ada cara untuk mengembalikan indeks baris dan kolom dari elemen yang cocok dari array data-langkah multidimensi - Anda harus memperlakukan array sebagai 1-d dan kemudian mengerjakannya sendiri.
  • Jika Anda keluar dari batas, SAS melempar kesalahan dan menghentikan pemrosesan daripada mengembalikan nol / nol.

Pembaruan:

  • infile cards;Pernyataan dihapus (-13)
  • Wildcard digunakan a:untuk definisi array daripada a1-a16(-4)

Golf:

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

Tidak Disatukan:

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;*/
pengguna3490
sumber
1
+1 untuk penggunaan kartu punch di 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#)

Cobalah online!

The ffungsi mengambil masukan sebagai daftar 4 daftar 4 bilangan bulat.

Sedikit tidak berbulu

-- 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
sumber
3

JavaScript (ES7), 97 byte

Mengambil input sebagai array yang diratakan.

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

Cobalah online!

Berkomentar

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
sumber
Yap, saya tidak akan pernah mendekati itu!
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;}

Sel-sel diperiksa sama seperti dalam jawaban saya untuk tantangan All the single eights .
-24 byte terima kasih kepada @ OlivierGrégoire .

Cobalah online.

Penjelasan:

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
sumber
bisakah Anda tidak int r = c = X = Y = 0, R = 4, M = 1, x, y; ?
Serverfrog
@Serverfrog Saya khawatir itu tidak mungkin ketika mendeklarasikan variabel di Java. Saran Anda memang memberi saya ide untuk menyimpan byte, dengan menggunakan int r,c,R=4,M=1,x,y,X,Y;for(r=c=X=Y=0;, jadi terima kasih. :)
Kevin Cruijssen
1

J, 82 byte

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

Cobalah online!

Saya berencana untuk golf ini lebih besok, dan mungkin menulis lebih J-ish solusi yang mirip dengan ini satu , tapi kupikir aku akan mencoba pendekatan diratakan karena saya tidak melakukan itu sebelumnya.

Jonah
sumber
Apakah Anda benar-benar membutuhkan paling kiri ]di g?
Galen Ivanov
1
Terima kasih Galen, kamu benar. Ini yang paling sedikit masalah dengan kode ini :) Saya punya solusi yang jauh lebih baik yang akan saya terapkan ketika saya punya waktu.
Jonah
1

Merah , 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]

Cobalah online!

Ini solusi yang sangat panjang dan saya tidak senang dengan itu, tapi saya menghabiskan begitu banyak waktu untuk memperbaikinya untuk bekerja di TIO (ternyata ada banyak perbedaan antara versi stabil Win dan Linux Red), jadi saya tetap mempostingnya ...

Lebih mudah dibaca:

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
sumber
1

Jelly ,  31 30  29 byte

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

Karena metode ini terlalu lambat untuk dijalankan dalam 60-an dengan mouse mulai pada 16ini memulai 9dan membatasi kemampuannya sehingga ia hanya bisa makan 9atau kurang. Cobalah online! (Jadi di sini dia makan 9, 2, 7, 4, 8, 6, 3pergi 97).

Bagaimana?

³œ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
sumber
Ah ya, set daya tidak cukup!
Jonathan Allan
2
@Arnauld - akhirnya punya sedikit waktu untuk bermain golf: D Ini seharusnya bekerja, tetapi akan (terlalu lambat) untuk berlari di TIO dengan test case yang Anda gunakan sebelumnya.
Jonathan Allan
Bisakah pemilih bawah memberikan umpan balik? Ini berfungsi, memiliki penjelasan lengkap dan jelas, dan juga entri terpendek saat ini.
Jonathan Allan
Saya membenarkan, tetapi diberi O ((^ 2)!) Dari jawaban ini saya berharap tantangan itu membutuhkan waktu polinomial.
lirtosiast
1

Bukan pekerjaan terbaik saya. Ada beberapa perbaikan pasti yang harus dilakukan, beberapa mungkin mendasar untuk algoritma yang digunakan - Saya yakin itu dapat ditingkatkan dengan hanya menggunakan int[], tapi saya tidak tahu bagaimana cara menghitung tetangga secara efisien dengan cara itu. Saya ingin melihat solusi PowerShell yang hanya menggunakan array satu dimensi!

Core PowerShell , 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}

Cobalah online!


Versi yang lebih mudah dibaca:

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
sumber
Oh ya, hal aneh yang saya perhatikan adalah mencoba melakukan (array|sort)[-1]alih - alih Measure -maxbekerja di PSv5 tetapi mendapatkan hasil yang salah pada intinya. Tidak tahu kenapa.
Veskah
Ya, itu aneh. Saya mengujinya (0..10|sort)[-1]tetapi mengembalikan 10 pada PSv5 tetapi 9 pada PS Core. Ini karena ia memperlakukannya dalam urutan leksikografis, bukan numerik. Malu, itu.
Jeff Freeman
Microsoft klasik mengubah hal-hal penting.
Veskah
Saya setuju dalam hal ini. Saya tidak yakin mengapa PS Core Sort melempar array int32 ke array string. Tapi, ini menyimpang menjadi kata-kata kasar, jadi saya akan ngelantur. Terima kasih untuk restrukturisasi!
Jeff Freeman
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);}

Cobalah online!

Catatan: Kiriman ini mengubah array input.

s()adalah fungsi untuk memanggil dengan argumen yang bisa berubah int[16](yang sama di-memori sebagai int[4][4], yang g()menafsirkannya sebagai).

s()menemukan lokasi 16array, kemudian meneruskan informasi ini ke g, yang merupakan fungsi rekursif yang mengambil lokasi, menetapkan angka di lokasi itu menjadi 0, dan kemudian:

  • Jika ada angka positif yang berdekatan dengannya, ulangi dengan lokasi nomor berdekatan terbesar

  • Lain, kembalikan jumlah angka dalam array.

pizzapants184
sumber
s(int*a){for(i=0;a[i]<16;++i);return g(a,i%4,i/4);}
RiaD
jika g mengembalikan jumlah yang dimakan, Anda tidak perlu menghitung jumlah di dalamnya. Cukup kembalikan 16 * 17/2-g () di akhir s
RiaD
dapatkah Anda menggunakan bitwise atau sebaliknya jika logis atau?
RiaD
211 byte
ceilingcat
1

Tambahkan ++ , 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

Cobalah online!

Oof, ini yang rumit.

Verifikasi semua kasus uji

Bagaimana itu bekerja

Untuk penjelasan ini, kami akan menggunakan input

M.=[37105681213159114141162]

x1x16M.4x4

  • f(x,M.)4x4xM.x=16M.f(x,M.)=(4,3)

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

    Ini mengimplementasikan dua fungsi pembantu:

    k(x)

    l(M.,y)

  • h(y,M.)0

016120(1+2++14+15)

0

0

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

Akhirnya, output t , yaitu nilai yang tersisa, yang tidak dikumpulkan.

caird coinheringaahing
sumber
1

C # (.NET Core) , 258 byte

Tanpa LINQ. Menggunakan System.Collections.Generic adalah untuk memformat setelah - fungsi tidak memerlukannya.

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

Cobalah online!

Destroigo
sumber
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}

Solusi super lusuh. Mengambil input sebagai array rata.

Cobalah online!

bb94
sumber
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

Cobalah online!

Xcali
sumber
1

K (ngn / k) , 49 byte

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

Cobalah online!

input ( x) adalah array 1d

(+!4 4)!x kamus yang memetakan pasangan coords dengan nilai x

h:: tetapkan ke variabel global h

*> tombol yang sesuai dengan nilai maks

{ }\ ulangi sampai konvergensi, kumpulkan nilai-nilai perantara dalam daftar

h[,x]:0 nolkan posisi saat ini

+x+0,'1-!3 3 posisi tetangga

( )#hsaring dari hsebagai kamus yang lebih kecil

*>tetangga mana yang memiliki nilai maks? itu menjadi posisi saat ini untuk iterasi baru

+/hakhirnya, kembalikan jumlah hnilai yang tersisa

ngn
sumber
1

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

Cobalah online!

Ini membutuhkan array 2D, menempatkannya di setiap sisi, lalu segera meratakannya sehingga kita tidak perlu menghabiskan byte pengindeksan. Satu-satunya biaya untuk ini adalah Join@@meratakan. Setelah itu hasilnya seperti di bawah ini.

Versi 124-byte untuk array 2D: Cobalah online!

Sebagian besar karya saya sendiri, dengan sedikit berasal dari jawaban 149-byte J42161217 .

Tidak Disatukan:

(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
sumber