魔方陣(奇数)

 投稿者:しばっち  投稿日:2011年11月13日(日)20時06分51秒
  魔方陣(奇数 魔方陣のみ)
N * N 方陣において1~N^2までの数字を全て使用し、各縦、横、斜めの列の和が全て同じ

DIM A(19, 19)
FOR N=3 TO 19 STEP 2
   LET  X = INT(N / 2) + 1
   LET  A(X, 1) = 1
   LET  I = 2
   LET  Y = N + 1
   DO
      IF X = N THEN LET  X = 1 ELSE LET  X = X + 1
      IF Y = 1 THEN LET  Y = N ELSE LET  Y = Y - 1
      IF A(X, Y) <> 0 THEN
         LET  Y = Y + 2
         LET  X = X - 1
      END IF
      DO
         LET  A(X, Y) = I
         IF X = N AND Y = 1 THEN
            LET  Y = Y + 1
            LET  I = I + 1
         ELSE
            EXIT DO
         END IF
      LOOP
      IF I = N * N THEN EXIT DO
      LET  I = I + 1
   LOOP
   PRINT N; " * "; N; " 魔方陣"
   FOR Y = 1 TO N
      FOR X = 1 TO N
         PRINT USING "#####": A(X, Y);
      NEXT X
      PRINT
   NEXT Y
   MAT A=ZER
NEXT N
END
 

Re: 魔方陣(奇数)

 投稿者:山中和義  投稿日:2012年12月 9日(日)10時04分59秒
  > No.1710[元記事へ]

> 魔方陣(奇数 魔方陣のみ)
> N * N 方陣において1~N^2までの数字を全て使用し、各縦、横、斜めの列の和が全て同じ

行列の演算で求めてみました。


!奇数の魔方陣

!行列Mのつくり方
!n×nの場合
!右斜めの対角線に、数字(n-1)/2を入れる。
!これを基準に右斜めに数字が揃うように、0から(n-1)までの数字を順に埋めていく。
!3 4 … n-1 0 1 2
!4 … n-1 0 1 2 3
! :
!0 1 2 3 4 … n-1
!1 2 3 4 … n-1 0
!2 3 4 … n-1 0 1
! :

LET N=9

DIM X(N,N) !行や列の並びを反転させる
MAT X=ZER
FOR i=1 TO N
   LET X(N-i+1,i)=1
NEXT i
PRINT "行列X(この行列は、「行列の演算」で実現するために用いる)"
MAT PRINT X; !debug
PRINT "として、"
PRINT

DIM M(N,N)
FOR i=1 TO N
   FOR J=1 TO N
      LET M(i,J)=MOD((i+INT((N-1)/2))+(J-1),N)
   NEXT J
NEXT i
PRINT "行列M"
MAT PRINT M; !debug

DIM B(N,N)
MAT B=M*X
MAT B=TRN(B)
PRINT "と、行列M*Xの転置行列(M*X)^t、すなわち、Mを反時計まわりに90度回転したもの"
MAT PRINT B; !debug
MAT B=(N)*B
PRINT "を、";N;"倍したもの(n*(M*X)^t)"
MAT PRINT B; !debug
MAT M=M+B
PRINT "を足す。(M+n*(M*X)^t)"
PRINT
MAT PRINT M;


!------------------------------

DIM F(0 TO N*N-1) !数字の使用回数
MAT F=ZER
FOR i=1 TO N
   FOR J=1 TO N
      LET T=M(i,J)
      IF F(T)=1 THEN !相異なるものかどうか
         PRINT T;"が重複します。"
         STOP
      END IF
      LET F(T)=1 !「使用」とする
   NEXT J
NEXT i

DIM W(N,1) !行の和
MAT W=CON !(1,1,1,…,1)^t
MAT W=M*W !内積をとる
MAT PRINT W;

DIM Y(1,N) !列の和
MAT Y=CON
MAT Y=Y*M
MAT PRINT Y;


PRINT tr(M)!左斜め対角線の和 tr(M)

LET T=0 !左斜め対角線の和
FOR i=1 TO N
   LET T=T+M(N-i+1,i)
NEXT i
PRINT T

END

EXTERNAL FUNCTION tr(A(,)) !行列Aのトレース ※左斜め対角線の和
LET T=0
FOR i=0 TO MIN(SIZE(A,1),SIZE(A,2))-1
   LET T=T+A(i+LBOUND(A,1),i+LBOUND(A,2))
NEXT i
LET tr=T
END FUNCTION


実行結果

行列X(この行列は、「行列の演算」で実現するために用いる)
0  0  0  0  0  0  0  0  1
0  0  0  0  0  0  0  1  0
0  0  0  0  0  0  1  0  0
0  0  0  0  0  1  0  0  0
0  0  0  0  1  0  0  0  0
0  0  0  1  0  0  0  0  0
0  0  1  0  0  0  0  0  0
0  1  0  0  0  0  0  0  0
1  0  0  0  0  0  0  0  0

として、

行列M
5  6  7  8  0  1  2  3  4
6  7  8  0  1  2  3  4  5
7  8  0  1  2  3  4  5  6
8  0  1  2  3  4  5  6  7
0  1  2  3  4  5  6  7  8
1  2  3  4  5  6  7  8  0
2  3  4  5  6  7  8  0  1
3  4  5  6  7  8  0  1  2
4  5  6  7  8  0  1  2  3

と、行列M*Xの転置行列(M*X)^t、すなわち、Mを反時計まわりに90度回転したもの
4  5  6  7  8  0  1  2  3
3  4  5  6  7  8  0  1  2
2  3  4  5  6  7  8  0  1
1  2  3  4  5  6  7  8  0
0  1  2  3  4  5  6  7  8
8  0  1  2  3  4  5  6  7
7  8  0  1  2  3  4  5  6
6  7  8  0  1  2  3  4  5
5  6  7  8  0  1  2  3  4

を、 9 倍したもの(n*(M*X)^t)
36  45  54  63  72  0  9  18  27
27  36  45  54  63  72  0  9  18
18  27  36  45  54  63  72  0  9
9  18  27  36  45  54  63  72  0
0  9  18  27  36  45  54  63  72
72  0  9  18  27  36  45  54  63
63  72  0  9  18  27  36  45  54
54  63  72  0  9  18  27  36  45
45  54  63  72  0  9  18  27  36

を足す。(M+n*(M*X)^t)

41  51  61  71  72  1  11  21  31
33  43  53  54  64  74  3  13  23
25  35  36  46  56  66  76  5  15
17  18  28  38  48  58  68  78  7
0  10  20  30  40  50  60  70  80
73  2  12  22  32  42  52  62  63
65  75  4  14  24  34  44  45  55
57  67  77  6  16  26  27  37  47
49  59  69  79  8  9  19  29  39

360
360
360
360
360
360
360
360
360

360  360  360  360  360  360  360  360  360

360
360

 

戻る