破解保险柜!


10

/puzzling/24334/to-catch-a-thief的启发

将为您提供一个n由s和s(或您选择的任何其他字符)填充的by nn本身是可选输入)网格。您的目标是使每个单元格相同(或)。您可以按照以下定义进行一系列移动(注意与“ Puzzling SE”链接有所不同):0101

  • 选择一个单元格。
  • 同一行和同一列中的每个单元格(单元格本身除外)都变为相反。0110

输出完成任务所需的最少移动次数。如果无法解决,则输出除非负整数以外的任何内容。最短的代码获胜。

样本数据

1 0 0
0 0 0
0 0 0

-1

1 1 1
1 1 1
1 1 1

0

1 0 1
0 1 0
1 0 1

1

1 1 1 1
0 0 0 0
0 0 0 0
1 1 1 1

2

0 1 0 1
1 0 1 0
1 0 1 0
0 1 0 1

2


3
万一难题无法解决,该怎么办?例如1000(重新排列为正方形,无所谓)。
orlp 2015年


@orlp任何不是数字的输出都可以。
ghosts_in_the_code 2015年

我们需要解析输入还是它可以是任何已经填充的数组数据类型?
coredump

1
第一个测试用例的解决方案是什么?我没有解决办法。
cardboard_box

Answers:


4

Matlab 171字节

输入应该是2D矩阵,因此您可以这样称呼它 c([1,1,1,1;0,0,0,0;0,0,0,0;1,1,1,1])(分号开始新的一行)。此功能只是蛮力地进行所有可能的移动,因此我们得到的运行时O(2^(n^2))

怎么做

这是通过选择所有可能的方法来填充相同大小的另一个矩阵而用1和0来完成的,这基本上是用二进制计数的,其中矩阵的每个项代表一定的2的幂。

然后,我们对那些为1的像元执行移动,这是通过二维卷积的和(mod 2)以及大小为1xn和nx1的矢量进行的。

最后,我们通过计算所有条目的标准偏差来确定这些移动是否真正产生了预期的结果。如果所有条目都相同,则标准偏差仅为零。并且,每当我们实际找到所需结果时,便将其与先前解决方案的移动次数进行比较。inf如果给定的问题无法解决,该函数将返回。

数学?

实际上,值得注意的是,所有这些动作共同产生了一个阿贝尔群!如果有人真的设法对这些群体进行分类,请告诉我。

高尔夫球版:

function M=c(a);n=numel(a);p=a;M=inf;o=ones(1,n);for k=0:2^n-1;p(:)=dec2bin(k,n)-'0';b=mod(conv2(p,o,'s')+conv2(p,o','s'),2);m=sum(p(:));if ~std(b(:)-a(:))&m<M;M=m;end;end

完整版(带有实际动作的输出。)

function M = c(a)
n=numel(a);
p=a;
M=inf;                                               %current minimum of number of moves
o=ones(1,n);
for k=0:2^n-1;
    p(:) = dec2bin(k,n)-'0';                         %logical array with 1 where we perform moves
    b=mod(conv2(p,o,'same')+conv2(p,o','same'),2);   %perform the actual moves
    m=sum(p(:));                                     %number of moves;
    if ~std(b(:)-a(:))&m<M                           %check if the result of the moves is valid, and better
        M=m;
        disp('found new minimum:')
        disp(M)                                      %display number of moves of the new best solution (not in the golfed version)
        disp(p)                                      %display the moves of the new best solution                               (not in the golfed version)
    end
end

1

Perl 5,498字节

这接受“ n”和所需的结果,并输出计数,如果没有则输出“ X”。

例如:

perl ./crack.golf.pl 3 000111111

2。它仅在n ^ 2 <= 64时有效n <= 8。尽管即使n值低至5还是很慢的。它会构建一个^ 3位数组,并事先对2 ^(n ^ 2)数组进行排序,因为为什么不呢?

为了提高可读性,我在这里浪费了一些换行符:

$n=shift;$y=shift;$p=$n*$n;@m=(0..$n-1);@q=(0..$p-1);@v=(0..2**$p-1);@d=map{0}(@q);@b=map{$r=$_;map{$c=$_;$d[$r*$n+$_]^=1 for(@m);$d[$_*$n+$c]^=1 for(@m);$j=0;$k=1;
map{$j|=$k*$d[$_];$k<<=1;}@q;@d=map{0}(@q);$j;}@m}@m;for$k(sort{$a->[0]<=>$b->[0]}map{$z=0;map{$z+=$_}split(//,sprintf"%b",$_);[$z,$_]}@v){$l=sprintf"%0${p}b",$k->[1];
@m=map{$_}split(//,$l);$s=0;for(@q){$s^=$b[$_]if$m[$_];}$z=0;map{$z+=$_}split(//,sprintf"%b",$_);if($y eq sprintf"%0${p}b",$s){print"$k->[0]\n";exit 0;}}print"X\n";
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.