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であるセルに対して。これは、サイズ1xnとnx1のベクトルとの2つの2次元畳み込みの合計(mod 2)によって行われます。
最後に、すべてのエントリの標準偏差を計算することにより、それらの動きが実際に望ましい結果を生み出したかどうかを判断します。すべてのエントリが同じ場合、標準偏差はゼロのみです。そして、実際に望ましい結果を見つけたときはいつでも、それを以前のソリューションの移動回数と比較します。関数は戻ります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
1000
(正方形として再配置され、どのようにしてもかまいません)。