附件,51字节
{[3,3]&Rotate[Sample[{Sum@_=_2}&_\BinBelow@8]'_,4]}
在线尝试!
说明
与Galen的J / APL答案类似,基本技术是生成具有正确数量的地雷的1和0的数组,通过将输入附加到末尾来插入输入,旋转数组以使输入位于中心,然后重塑为3x3矩阵。
第1部分:生成二进制数组
有很多方法可以做到这一点,但是我主要遇到两种类型:蛮力和选择。
主要的暴力破解方法如下所示:
NestWhile[{Random[8&2]},0,{Sum@_/=_2}&_]
这将生成8个二进制数字(Random[8&2]
)的随机数组,而它们的总和不等于输入{Sum@_/=_2}&_
。这有点冗长,因为下面的代码强调部分“只是为了使它起作用”:
NestWhile[{Random[8&2]},0,{Sum@_/=_2}&_]
^ ^^^^^ ^^^^
我放弃了这个主意。
选择更加有趣。主要概念是使用BaseBelow[b, n]
内置b
函数,该函数生成n
从0
to到所有宽度(以数字数组形式)的基整数的列表b^n-1
。例如,BaseBelow[3, 2]
生成所有宽度为2的三进制整数:
A> BaseBelow[3, 2]
0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
2 2
我们专门将BaseBelow[2, 8]
宽度8的所有二进制整数使用。它们表示所有长度的所有可能的雷区。这是第一步。
第二步是选择只有N
1的所有此类数组,其中N
输入为。我的第一个想法是将英语声明直接翻译为Attache:
Chunk[SortBy[Sum,BaseBelow[2,8]],Sum]@N@1
但是,这不仅比上述方法长了1个字节,而且还具有很高的重复性-甚至还没有随机化!当然,我可以通过重新组织BaseBelow
调用方式来节省1个字节,但是使用这种方法根本不值得。
因此,我决定用一块石头杀死两只鸟,并采用一种Shuffle
基本方法。以下内容N
以随机顺序给出了所有有效长度的雷区:
{Sum@_=_2}&N\Shuffle[BaseBelow&8!2]
然后,所有需要做的就是选择第一个。但是我可以做得更好-当然,仅Sample
过滤数组会更好吗?这种方法出来是这样的:
Sample[{Sum@_=_2}&_\BaseBelow[2,8]]
BaseBelow&8!2
由于\
s的优先级太高,我不得不恢复高尔夫球。否则感到满意,我开始砍掉一个字节:
Sample[{Sum@_=_2}&_\2&BaseBelow@8]
(我在这里发现了另一种简洁地调用二进位函数的方法:x&f@y
是一个高等价表达式,其结果为f[x, y]
。)
但是,尽管如此,我仍然记得一个别名2&BaseBelow
:BinBelow
。所以我用了:
Sample[{Sum@_=_2}&_\BinBelow@8]
这将产生所需的雷区。我相信这几乎是最佳的。
第2部分:形成数组
如前所述,我使用的成形技术与J / APL答案类似,因此我不会赘述过多。假设MINEFIELD
是最后一节的结果。该函数将变为:
{[3,3]&Rotate[MINEFIELD'_,4]}
MINEFIELD'_
将雷区与原始输入连接起来_
,给我们这样的东西:
[1, 0, 0, 0, 1, 0, 0, 1, 3]
然后,Rotate[MINEFIELD'_,4]
将此列表4
向左旋转一次,并放置在中心:
[1, 0, 0, 1, 3, 1, 0, 0, 0]
最后一步是[3,3]&
将列表重塑为3x3矩阵:
1 0 0
1 3 1
0 0 0
1
和“0
?