Голодная мышь


85

Шестнадцать груд сыра кладут на квадрат 4х4. Они помечены от до . Наименьшая куча равна а самая большая - .116116

Голодная мышь настолько голодна, что всегда идет прямо к самой большой куче (то есть ) и ест ее сразу же.16

После этого он идет к самой большой соседней куче и быстро ее тоже съедает. (Да ... Это действительно голодно.) И так до тех пор, пока больше нет соседней кучи.

Куча может иметь до 8 соседей (по горизонтали, вертикали и диагонали). Там нет обернуть.

пример

Начнем со следующих грудок сыра:

37105681213159114141162

Голодная мышь сначала съедает , а затем свою самую большую соседнюю кучу, которая составляет .1611

37105681213159🐭41412

Его следующие ходы - , , , , , , , , и в этом точном порядке.131210815149673

🐭5412

Вокруг голодной мыши больше нет сыра, поэтому он останавливается там.

Соревнование

Учитывая исходную конфигурацию сыра, ваш код должен напечатать или вернуть сумму оставшихся куч, как только голодная мышь перестанет их есть.

Для приведенного выше примера ожидаемый ответ .12

правила

  • Поскольку размер входной матрицы фиксирован, вы можете принять его как двумерный массив или одномерный массив.
  • Каждое значение от до гарантированно появится ровно один раз.116
  • Это .

Контрольные примеры

[ [ 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 для этого персонажа мыши
Луис Мендо

2
... сделать это 103:[[9, 10, 11, 12], [1, 2, 7, 13], [6, 16, 4, 14], [3, 8, 5, 15]]
Джонатан Аллан

9
Какой красиво написанный вызов! Я буду помнить это для лучших номинаций.
Норн

9
После неправильного прочтения мне стало немного грустно, что это не голодный лось.
Акози

1
Этот вызов напоминает мне мышь в программе лабиринт для компьютера TXO. Эта игра была написана еще в 1950-х годах, и, согласно легенде, TXO был первым транзисторным компьютером в мире. Да, верьте или нет, кто-то писал видеоигры в дни вашего дедушки.
Уолтер Митти

Ответы:


11

Python 2 , 133 130 байт

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)

Попробуйте онлайн!

Принимает уплощенный список из 16 элементов.

Как это устроено

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)

Выражение соседней ячейки a[i+x]for x in[-6,-5,-4,-1,1,4,5,6]может быть сокращено до a[i+j+j/3*2-6]for j in range(9)(нулевая запись безвредна). Python 3, безусловно, может сделать короче, жестко закодировав строку длиной 8, но Python 2 может быть лучше в целом.
Норн

1
Хотя ваш нулевой цикл заполнения умна, она выглядит , как он короче взять 2D список: a=[0]*5 for r in input():a=r+[0]+a. Возможно, есть еще более короткое решение для нарезки строк, которое не требует итерации.
xnor

8

Python 2 , 111 байт

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)

Попробуйте онлайн!

Метод и контрольные примеры адаптированы из Bubbler . Принимает плоский список на STDIN.

Код проверяет, являются ли два плоских индекса iи jпредставляют собой соприкасающиеся ячейки, проверяя, что как строки, так и различия i/4-j/4столбцов i%4-j%4строго между -2 и 2. При первом проходе эта проверка автоматически завершается успешно, так что самая большая запись обнаруживается без учета смежности.


8

MATL , 50 49 47 байт

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

Ввод представляет собой матрицу, используя в ;качестве разделителя строк.

Попробуйте онлайн! Или проверьте все тестовые случаи .

объяснение

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, но можете ли вы немного сэкономить, если вы нажмете -136 вместо +136?
Тит

@ Titus Хм, я не понимаю, как
Луис Мендо

или наоборот: я думал, что вместо 1) нажмите 136 2) нажмите каждое съеденное значение 3) суммируйте съеденные значения 4) вычтите из 136 -> 1) нажмите 136 2) нажмите минус съеденного значения 3) сложите стек. Но поскольку это, очевидно, только один байт каждый; это, вероятно, не выгода.
Тит

@ Титус Ах, да, я думаю, что использует то же количество байтов. Кроме того, мне нужно каждое съеденное значение (не его отрицательное значение) для разницы набора; отрицание должно было бы быть сделано в конце
Луис Мендо

6

PHP, 177 174 171 байт

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;

Запустите с -nr, предоставьте матричные элементы в качестве аргументов или попробуйте онлайн .


5

JavaScript, 122 байта

Я сделал несколько неправильных поворотов на этом и теперь у меня не хватает времени для дальнейшего игры в гольф, но, по крайней мере, это работает. Вернусь завтра (или, зная меня, в поезд домой домой сегодня вечером!), Если я найду минуту.

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

Попробуйте онлайн


3
+1 за flatMap(): р
Арнаулд

: D Я думаю, что это первый раз, когда я использовал его для гольфа! Из интереса (и чтобы дать мне цель, когда я вернусь к этому), каков был ваш счет, когда вы попробовали это?
Лохматый

Не было ни минуты, чтобы вернуться к этому сегодня. Надеюсь, это означает, что завтра я смогу начать с совершенно новыми глазами.
Лохматый

Я отправил свое решение.
Арно

5

R , 128 124 123 112 110 байт

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

Попробуйте онлайн!

Он создает матрицу 4x4 (которая помогла мне визуализировать вещи), дополняет ее нулями, затем начинает с 16 и ищет в ближайших «кучах» следующий по величине и т. Д.

В заключение выводится предупреждение, но оно не имеет значения и не меняет результат.

РЕДАКТИРОВАТЬ: -4 байта, сжимая инициализацию матрицы в 1 строку.

РЕДАКТИРОВАТЬ: -1 благодаря Роберту Хакену

РЕДАКТИРОВАТЬ: -13 байт, объединяющих предложения Джузеппе и Робина Райдера.


Вы можете сохранить один байт r==16для замены r>15.
Роберт Хакен,

1
117 байт - измените его на функцию, принимающую матрицу, и сделайте псевдоним с which.
Джузеппе

2
112 байтов улучшаются по советам @Giuseppe: вы можете хранить mкак логическое, а не целое число, и, следовательно, нужно вызывать whichтолько один раз вместо двух.
Робин Райдер

110 байт, используя гольф @RobinRyder и возиться с компрессией матрицы соседства.
Джузеппе

1
@ Sumner18 X%o%Yэто псевдоним для outer(X,Y,'*'). outerэто одна из самых удобных функций, так как она может функционировать как «широковещательная» функция Octave / MATLAB / MATL с aribtrary (векторизованными) операторами. Смотрите здесь ; также в редких случаях удобно то, kroneckerчто связано на этой странице.
Джузеппе

4

Древесный уголь , 47 байт

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

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

EA⭆ι§αλ

Преобразуйте введенные числа в буквенные символы (A = 0 .. Q = 16) и напечатайте их в виде сетки 4x4.

≔Qθ

Начните с еды Q, то есть 16.

W›θA«

Повторите, пока есть что поесть.

≔⌕KAθθ

Найдите, где находится куча. Это линейный вид в главном порядке строк.

J﹪θ⁴÷θ⁴

Преобразовать в координаты и перейти к этому месту.

≔⌈KMθ

Найдите самую большую соседнюю кучу.

Съешь текущую кучу.

≔ΣEKA⌕αιθ

Преобразуйте груды в целые числа и возьмите сумму.

⎚Iθ

Очистите холст и выведите результат.


3

Powershell, 143 141 136 130 122 121 байт

$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

Менее гольф тестовый скрипт:

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

Выход:

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

Объяснение:

Сначала добавьте верхнюю и нижнюю границы 0 и создайте одномерный массив:

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

     ↓

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

Powershell возвращается, $nullесли вы попытаетесь получить значение за концом массива.

Во-вторых , цикл biggest neighbor pileначался с 16 до ненулевого максимума. И аннулируйте это (Голодная Мышь ест это).

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

В-третьих , сумма оставшихся куч.


3

SAS, 236 219 байт

Ввод на перфокартах, одна строка на сетку (через пробел), вывод в журнал.

Эта проблема немного усложняется некоторыми ограничениями массивов в SAS:

  • Невозможно вернуть индексы строк и столбцов соответствующего элемента из многомерного массива шагов данных - вы должны обработать массив как 1-й, а затем обработать их для себя.
  • Если вы выходите за пределы, SAS выдает ошибку и останавливает обработку, а не возвращает ноль / ноль.

Обновления:

  • Удалено infile cards;утверждение (-13)
  • Используется подстановочный знак a:для определения массива, а не 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 за использование перфокарт в PPCG :)
GNiklasch

3

Haskell , 163 байта

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

Попробуйте онлайн!

fФункция принимает входные данные в виде списка из 4 списков 4 целых чисел.

Слегка разгульный

-- 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 байт

Принимает ввод как плоский массив.

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

Попробуйте онлайн!

комментарии

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

Да, я бы никогда не приблизился к этому!
Лохматый


3

Java 10, 272 248 байт

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

Клетки проверяются так же , как в моем ответе за все одиночные восьмерки вызова .
-24 байта благодаря @ OlivierGrégoire .

Попробуйте онлайн.

Объяснение:

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

не могли бы вы int r = c = X = Y = 0, R = 4, M = 1, x, y; ?
Serverfrog

@ Serverfrog Боюсь, что это невозможно при объявлении переменных в Java. Ваше предложение действительно дало мне идею сохранить байт, хотя, используя int r,c,R=4,M=1,x,y,X,Y;for(r=c=X=Y=0;, так что спасибо. :)
Кевин Круйссен

1

J, 82 байта

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

Попробуйте онлайн!

Я планирую гольф это более завтра, и , возможно , написать больше J-иш решение , подобное этому одному , но я решил попробовать сплющенный подход , так как я не сделал этого раньше.


Вам действительно нужно самое левое ]в g?
Гален Иванов

1
Спасибо, Гален, ты прав. Это меньше всего проблем с этим кодом :) У меня есть гораздо лучшее решение, которое я буду реализовывать, когда у меня будет время.
Иона

1

Красный , 277 байт

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]

Попробуйте онлайн!

Это действительно длинное решение, и я не доволен им, но я потратил так много времени на то, чтобы установить его на работу в TIO (очевидно, между Win и Linux стабильными версиями Red много различий), поэтому я все равно выкладываю его ...

Более читабельно:

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

Желе ,  31 30  29 байт

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

Так как метод слишком медленный, чтобы запускаться в течение 60-х годов с включенной мышью, 16это 9приводит к тому, что она начинает работать и ограничивает свои возможности, так что она может есть только 9меньше или меньше. Попробуйте онлайн! (при этом здесь она ест 9, 2, 7, 4, 8, 6, 3уходя 97).

Как?

³œ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

Ах да, мощности недостаточно!
Джонатан Аллан

2
@Arnauld - наконец-то есть немного времени для игры в гольф: D Это должно сработать, но будет (слишком) слишком медленно для работы в TIO с тестовым набором, который вы использовали ранее.
Джонатан Аллан

Может ли голосующий дать отзыв? Это работает, имеет полное и четкое объяснение, а также является самой короткой записью в настоящее время.
Джонатан Аллан

Я проголосовал, но, учитывая O ((n ^ 2)!) Этого ответа, я бы хотел, чтобы испытание требовало полиномиального времени.
lirtosiast

1

Не моя лучшая работа. Есть некоторые определенные улучшения, которые, вероятно, будут фундаментальными для используемого алгоритма - я уверен, что его можно улучшить, используя только an int[], но я не мог понять, как эффективно перечислить соседей таким образом. Мне бы очень хотелось увидеть решение PowerShell, которое использует только одномерный массив!

PowerShell Core , 348 байт

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}

Попробуйте онлайн!


Более читаемая версия:

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
}


О да, странная вещь, которую я заметил, это то, что попытка сделать это (array|sort)[-1]вместо того, чтобы Measure -maxработать в PSv5, но получала неверные результаты в ядре. Понятия не имею почему.
Веска

Да, это странно. Я тестировал его, (0..10|sort)[-1]но он возвращает 10 на PSv5 и 9 на PS Core. Это потому, что он рассматривает это в лексикографическом порядке вместо числового. Позор, это.
Джефф Фриман

Классическая Microsoft меняет важные вещи.
Веска

Я согласен в этом случае. Я не уверен, почему PS Core Sort выбрасывает массив int32 в массив строк. Но это заблудило, так что я отступлю. Спасибо за реструктуризацию!
Джефф Фриман

1

C (gcc), 250 байт

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

Попробуйте онлайн!

Примечание. Это представление изменяет входной массив.

s()это функция, вызываемая с аргументом изменяемой переменной int[16](которая является той же самой в памяти, что и переменная int[4][4], которая g()интерпретирует ее как).

s()находит местоположение 16в массиве, затем передает эту информацию g, которая является рекурсивной функцией, которая принимает местоположение, устанавливает число в этом месте равным 0, а затем:

  • Если рядом с ним есть положительное число, выполните рекурсию с расположением наибольшего соседнего числа

  • Иначе, верните сумму чисел в массиве.


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

если g возвращает сумму съеденного, вам не нужно вычислять сумму в нем. Просто верните 16 * 17/2-g () в конце s
RiaD

Вы можете использовать побитовый или вместо логического или?
RiaD



1

Добавить ++ , 281 байт

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

Попробуйте онлайн!

Ох, это сложный.

Проверьте все контрольные примеры

Как это устроено

Для этого объяснения мы будем использовать вход

M=[37105681213159114141162]

x1x16M4x4

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

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

    Это реализует две вспомогательные функции:

    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
  • h(x,y)160
  • tm

Наконец, выведите t , то есть оставшиеся, не собранные значения.


1

C # (.NET Core) , 258 байт

Без LINQ. Использование System.Collections.Generic предназначено для форматирования после - функция не требует этого.

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

Попробуйте онлайн!


1

Perl 6 , 151 136 126 125 119 байт

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

Супер потертый раствор. Принимает ввод как плоский массив.

Попробуйте онлайн!



1

K (нгн / к) , 49 байтов

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

Попробуйте онлайн!

input ( x) является массивом 1d

(+!4 4)!x словарь, который отображает пары координат в значения x

h:: присваивать глобальной переменной h

*> ключ, соответствующий максимальному значению

{ }\ повторять до схождения, собирая промежуточные значения в списке

h[,x]:0 обнулять текущую позицию

+x+0,'1-!3 3 соседние позиции

( )#hотфильтровать их из hсловаря меньшего размера

*>какой сосед имеет максимальное значение? становится текущей позицией для новой итерации

+/hнаконец, вернуть сумму hоставшихся значений


1

Wolfram Language (Mathematica) , 124 115 байтов

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

Попробуйте онлайн!

Это берет 2D-массив, дополняет его с каждой стороны, а затем немедленно выравнивает, чтобы нам не пришлось тратить байты на индексацию. Единственная цена для этого, Join@@чтобы сгладить. После этого это продолжается, как показано ниже.

124-байтовая версия для 2D-массива: попробуйте онлайн!

Главным образом моя собственная работа, немного полученная из 149-байтового ответа 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.
)&
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.