魔方陣の変形

 投稿者:GAI  投稿日:2012年 2月16日(木)20時01分20秒
  紹介して頂いたHPはとっても参考になりました。
自分でも相当探していたんですが、まさに調べたいことがここにあったんだと膝を打つ気持ちでした。
またまた

3×3の魔方陣として
4 3 8

9 5 1

2 7 6

は有名で、これはなんとかプログラムを組んで発見することは可能であると感じます。

これを

A^2  B^2  C^2

D^2  E^2  F^2

G^2  H^2  I^2

の計算で魔方陣となる配列がとれるか探せるものでしょうか?

 

Re: 魔方陣の変形

 投稿者:山中和義  投稿日:2012年 2月17日(金)13時32分17秒
  > No.1769[元記事へ]

GAIさんへのお返事です。

> A^2  B^2  C^2
> D^2  E^2  F^2
> G^2  H^2  I^2
> の計算で魔方陣となる配列がとれるか探せるものでしょうか?

汎用的には、バックトラック法で解決します。

魔方陣を
123
456
789
の順に、数値を埋めていけばよいです。

和をSとして、0≦A,B,C≦Sがおおざっぱな候補ですが、
1行目は、A^2+B^2+C^2=Sですから、
Aは、A^2≦S
Bは、A^2+B^2≦S
Cは、A^2+B^2+C^2=S
を満たさないといけません。

このようなチェックを途中にコーディングすれば完成です。


!3×3魔方陣

LET t0=TIME

PUBLIC NUMERIC C !解の数
PUBLIC NUMERIC M(9) !魔方陣
PUBLIC NUMERIC S !和
FOR S=0 TO 1500
   PRINT "S=";S
   LET C=0
   CALL try(1)
NEXT S

PRINT "実行時間=";TIME-t0

END

EXTERNAL SUB try(p) !バックトラック法で探索する
FOR i=0 TO S !候補
   LET t=i*i !埋め込む数値

   !M(p) 123
   !   456
   !   789
   LET OK=1
   IF p=1 THEN
      IF t>S THEN EXIT SUB !不適切
   ELSEIF p=2 THEN
      IF M(1)+t>S THEN EXIT SUB !不適切
   ELSEIF p=3 THEN
      IF M(1)+M(2)+t< S THEN LET OK=0 !不適切

      IF M(1)+M(2)+t>S THEN EXIT SUB !不適切
   ELSEIF p=4 THEN
      IF M(1)+t>S THEN EXIT SUB !不適切
   ELSEIF p=5 THEN
      IF M(1)+t>S THEN EXIT SUB !不適切
      IF M(2)+t>S THEN EXIT SUB !不適切
      IF M(3)+t>S THEN EXIT SUB !不適切
      IF M(4)+t>S THEN EXIT SUB !不適切
   ELSEIF p=6 THEN
      IF M(4)+M(5)+t< S THEN LET OK=0 !不適切

      IF M(3)+t>S THEN EXIT SUB !不適切
      IF M(4)+M(5)+t>S THEN EXIT SUB !不適切
   ELSEIF p=7 THEN
      IF M(1)+M(4)+t< S THEN LET OK=0 !不適切
      IF M(3)+M(5)+t< S THEN LET OK=0 !不適切

      IF M(1)+M(4)+t>S THEN EXIT SUB !不適切
      IF M(3)+M(5)+t>S THEN EXIT SUB !不適切
   ELSEIF p=8 THEN
      IF M(2)+M(5)+t< S THEN LET OK=0 !不適切

      IF M(7)+t>S THEN EXIT SUB !不適切
      IF M(2)+M(5)+t>S THEN EXIT SUB !不適切
   ELSEIF p=9 THEN
      IF M(1)+M(5)+t< S THEN LET OK=0 !不適切
      IF M(3)+M(6)+t< S THEN LET OK=0 !不適切
      IF M(7)+M(8)+t< S THEN LET OK=0 !不適切

      IF M(1)+M(5)+t>S THEN EXIT SUB !不適切
      IF M(3)+M(6)+t>S THEN EXIT SUB !不適切
      IF M(7)+M(8)+t>S THEN EXIT SUB !不適切
   ELSE
      PRINT "論理エラー"; p
      STOP
   END IF
   IF OK=1 THEN !条件を満たすなら
      LET M(p)=t !上書き

      IF p=9 THEN !すべて揃ったなら

         IF M(1)<=M(9) AND M(1)<=M(2) AND M(2)<=M(4) THEN !対称性

            LET C=C+1 !結果を表示する
            PRINT "No.";C

            FOR j=1 TO 9 !3x3
               PRINT M(j);
               IF MOD(j,3)=0 THEN PRINT
            NEXT j
            PRINT

         END IF

      ELSE
         CALL try(p+1) !次へ

      END IF

   END IF
NEXT i
END SUB

 

戻る