CodeIQの魔方陣ヌルヌル問題を解いてみた

方陣ヌルヌル問題を解いていたはずなのに、スパゲティグルグルになってました。(汚くて大変恐縮ですが)ワシのコードを見てくだされ~!!

問題

【問題】
正方形の方陣に、縦・横・斜めすべての列の値の合計が 0 になるように、すべて異なる整数を配置してください。
方陣は、3×3・4×4・5×5の3種類のサイズで作ってください。

解答

この内容で提出し正解でした。

n = 3 
-2 8 -6 
-4 0 4 
6 -8 2 

n = 4 
-15 13 11 -9 
7 -5 -3 1 
-1 3 5 -7 
9 -11 -13 15 

n = 5 
-4 10 24 -22 -8 
-6 -2 12 16 -20 
-18 -14 0 14 18 
20 -16 -12 2 6 
8 22 -24 -10 4 

求め方

全探索しようとしたのですが全く終わる気配がなく・・

Ozyさんの問題だったので、JavaScriptでショートコーディングしてみることにしました。(とは言いつつあまり短くなっていませんが・・・)

方陣に使用する数字は、和が0になるように同じ数字のプラスとマイナスを使用しました。

奇数x奇数のコード(n=3 or 5)

n=5;p=n*n;a=[];x=p+~(n/2);for(i=p;i--;){a[x]=i*2-p+1;x=a[t=(x-1+(x%n?n:2*n))%p]!=null?(x-n+p)%p:t}for(i=n;i--;)print(a.slice(i*n,i*n+n).join(" "))

実行結果

ヒンズーの連続方式」で解きました。

4x4のコード

a=[];for(i=16;i--;)a[38505>>i&1?i:15-i]=i*2-15;for(i=4;i--;)print(a.slice(i*4,i*4+4).join(" "))

実行結果

解き方の参考:4の倍数×4の倍数の魔方陣の作り方

38505=1001 0110 0110 1001(2進数)で、
1001
0110
0110
1001
1の場所→インデックス順(左上から)
0の場所→インデックス逆順(右下から)
値を埋めていくよう作りました。

感想

自力では3x3(手計算)しか求めることができませんでしたが、勉強するいいきっかけとなりました。

フィードバックコメントを出題者のOzyさんよりいただきました。

まさかのショートコーディング!
笑わせていただきました、ありがとうございます!

(2014/06/13追記)
解説記事来てました。
タテ・ヨコ・ナナメ、すべての合計が0(null)になる「魔方陣ヌルヌル」解説記事|CodeIQ MAGAZINE
「ショートコード書いちゃった賞」頂いちゃいました。ありがとうございます。