|
> 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
|
|