饥饿的老鼠


85

将16堆奶酪放在4x4正方形上。它们被标记为到。最小的桩是,最大的桩是。116116

饥饿的老鼠是如此饥饿,以至于它总是直接跳到最大的一堆(即)并立即吃掉它。16

之后,它进入最大的相邻堆,并很快也吃掉那堆。(是的…… 真的很饿。)依此类推,直到不再有相邻的堆了。

一堆最多可以有8个邻居(水平,垂直和对角线)。没有环绕。

我们从以下几堆奶酪开始:

37105681213159114141162

饥饿的老鼠先吃掉,然后再吃掉最大的邻居堆,即。1611

37105681213159🐭41412

其下一个动作是,,,,,,,,和在此确切顺序。131210815149673

🐭5412

饥饿的老鼠周围不再有奶酪,所以它停在那里。

挑战

给定初始的奶酪配置,一旦饥饿的老鼠停止吃掉它们,您的代码必须打印或返回剩余的总和。

对于以上示例,预期答案为。12

规则

  • 由于输入矩阵的大小是固定的,因此可以将其作为2D数组或一维数组。
  • 从到每个值都保证只出现一次。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
Luis Mendo

2
...使那103:[[9, 10, 11, 12], [1, 2, 7, 13], [6, 16, 4, 14], [3, 8, 5, 15]]
乔纳森·艾伦,

9
多么好的书面挑战!对于最佳提名,我会牢记在心。
xnor18年

9
误读后,我为这不是饥饿的驼鹿感到难过。
akozi

1
这个挑战让我想起了txo计算机迷宫程序中的鼠标。传说,这款游戏的创作可追溯到1950年代,而txo是世界上第一台晶体管计算机。是的,信不信由你,有人在你祖父时代写电子游戏。
Walter Mitty

Answers:


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)(零项无害)。通过硬编码长度为8的字节串,Python 3肯定可以做得更短,但是Python 2总体上可能仍然更好。
xnor

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上列出清单。

该代码通过检查行差和列差是否都严格在-2和2之间来检查是否有两个平坦的索引ij表示触摸单元。相反,第一遍使该检查自动成功进行,以便找到最大的条目,而无需考虑邻接关系。i/4-j/4i%4-j%4


8

MATL50 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 Hm我不知道如何
Luis

或反过来:我认为不是1)推136 2)推每个吃的值3)累加吃的值4)从136减去-> 1)推136 2)推吃值的负3)累加堆栈。但是很明显每个字节只有一个字节。可能没有收获。
泰特斯

@Titus啊,是的,我认为使用相同数量的字节。另外,我需要每个吃过的值(而不是它的负数)作为设定差异。否定性必须在最后完成
Luis Mendo

6

PHP,177174171字节

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():p
Arnauld

:DI认为这是我第一次将它用于高尔夫!出于兴趣(当我回到目标位置时给我一个目标),尝试时您的得分是多少?
粗野的

今天没有时间再来讨论这个问题。希望那意味着我明天可以重新开始。
粗野的

我已经发布了解决方案。
Arnauld

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矩阵(帮助我可视化了东西),将其填充为0,然后从16开始,并在其周围的“桩”中搜索下一个最大的桩,依此类推。

得出结论后,它确实会发出警告,但没有影响,也不会改变结果。

编辑: -4字节通过将矩阵的初始化压缩为1行。

编辑: -1感谢罗伯特·哈肯

编辑: -13字节结合朱塞佩和罗宾·赖德的建议。


您可以将一个字节更改r==16为保存r>15
罗伯特·哈肯

1
117字节 -将其更改为带有矩阵的函数,并使用进行一些别名which
朱塞佩

2
@Giuseppe的建议改进了112个字节:您可以存储m为逻辑而不是整数,因此只需要调用which一次即可,而不必调用两次。
罗宾·赖德

使用@RobinRyder的高尔夫110字节,并压缩邻居邻接矩阵。
朱塞佩

1
@ Sumner18 X%o%Y是的别名outer(X,Y,'*')outer是最方便的功能之一,因为它可以通过带aribtrary(矢量化)运算符的Octave / MATLAB / MATL来充当“广播”功能。见这里 ; 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

$null如果您尝试获取数组末尾的值,Powershell将返回。

其次,循环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-d,然后自己计算出来。
  • 如果您超出范围,则SAS会引发错误并暂停处理,而不是返回null /零。

更新:

  • 已删除的infile cards;声明(-13)
  • 使用通配符a:定义数组,而不是a1-a16(-4)

打高尔夫球:

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

取消高尔夫:

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

爪哇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

你能不能诠释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;,非常感谢。:)
Kevin Cruijssen

1

J,82字节

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

在线尝试!

我打算高尔夫这更明天,也许写一个类似的更J-ISH解决一个,但我想我会尝试扁平的方法,因为我还没有做到这一点之前。


您真的需要最左边]g吗?
Galen Ivanov

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并限制了她的能力,以致只能吃9s或更少的食物。在线尝试!(因此,她在这里吃饭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

不是我最好的工作。有一定的改进要做,可能是所使用算法的基础-我敢肯定,仅使用可以将其改进int[],但是我无法弄清楚如何以这种方式有效枚举邻居。我很乐意看到仅使用一维数组的PowerShell解决方案!

PowerShell核心,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 中工作,但是在核心中得到了不正确的结果。不知道为什么。
Veskah

是的,那很奇怪。我对其进行了测试,(0..10|sort)[-1]但在PSv5上返回10,而在PS Core上返回9。这是因为它按字典顺序而不是数字顺序对待。真可惜
杰夫·弗里曼

经典的Microsoft改变了重要的事情。
Veskah

我同意这种情况。我不确定为什么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](与in相同的内存,将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返回所吃的总和,则无需计算其中的总和。只需在s末尾返回16 * 17 / 2-g()
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

Perl -MList::Util=sum -p 5,137个字节

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

在线尝试!


1

K(ngn / k),49个字节

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

在线尝试!

输入(x)是一维数组

(+!4 4)!x 字典将一对坐标映射到的值 x

h:: 分配给全局变量 h

*> 最大值对应的密钥

{ }\ 重复直到收敛,然后在列表中收集中间值

h[,x]:0 将当前位置清零

+x+0,'1-!3 3 邻居位置

( )#hh较小的字典中过滤掉它们

*>哪个邻居的价值最大?它成为新迭代的当前位置

+/h最后,返回h的剩余值之和


1

Wolfram语言(Mathematica)124115字节

(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@@将其扁平化。之后,其进行如下。

2D阵列的124字节版本在线尝试!

大多数情况下是我自己的工作,部分内容来自J42161217的149字节答案

取消高尔夫:

(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.
)&
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.