3×3のマス目に1から9までの数字をいれました。この図では縦の列も横の列も対角線の列もその和がいずれも15になっています。このようにすべて異なる数字を入れて縦・横・対角線の和が一定になる正方形の数の表は「魔方陣」と呼ばれます。また、3×3マス目を持つ魔方陣のことを3次の魔方陣と呼びます。
魔方陣を作るのに何か良い方法があるでしょうか?実は奇数次の魔方陣を一つ作るための手順は1963年に数学者シモン・ドゥ・ラ・ルベールによって考案されています。その手順は次のようなものです。5次の魔方陣を例に実際に入れてみましょう。
5×5のマス目を準備します
最上部の中央のマス目に1を置きます
斜め右上に進み、正方形の外に次の数字2を置きます。この2は正方形の外にあるので同じ縦列の一番下にもってきます。
次の数3を2の斜め右上に置きます。
次の数4を3の斜め右上に置きます。この4は正方形の外にあるので同じ横列の一番左端に持っていきます。
4の斜め右上に5を入れる
5の斜め右上のマス目はすでに1でふさがっているので、5の下に6を入れる。
6の斜め右上に7、7の斜め右上に8を入れる。8の右上に9を入れ、この9は正方形の外にあるので同じ縦列の一番下にもってきます。
9の斜め右上に10を入れ、この10は正方形の外にあるので同じ横列の一番左端に持っていきます。10の斜め右上に11を入れたいのですがすでに6でふさがっているので、10の下に11を入れます。
11の斜め右上に12,順に斜め右上に移動しながら13,14,15と入れていきます。15の斜め右上には縦横に回り込む列がありませんから、15の下に16を入れます。
16の斜め右上に17を入れ、この17は正方形の外にあるので同じ横列の一番左端に持っていきます。17の斜め右上に18を入れ、この18は正方形の外にあるので同じ縦列の一番下にもってきます。
18の斜め右上に19、19の斜め右上に20を入れます。20の斜め右上に21を入れたいのですがすでに16でふさがっているので、20の下に21を入れます。
21の斜め右上に22、22の斜め右上に23をいれます。23は枠外なので左端に持っていきます。23の斜め右上に24を入れます。24の斜め右上に25を入れ、25は枠外なので下端にいれます。
25まですべて入ったので完成です。縦横対角線の和がいずれも65になっていることがわかります。
はじめの3×3の魔方陣も上の手順を使って作られています。また、上の手順をまとめると次のようなアルゴリズムにすることができます。
1.最上部の中央のマス目に1を置く
2.2からN2まで順に繰り返す
(ア)斜め右上に進む。このとき、
①正方形の上に出た場合には反対側下端のマス目に進む
②正方形の右に出た場合には反対側左端のマス目に進む
③移動先にすでに数字があるときは下に移動する
(イ)数字を順に置く
上記の手順をjavaのプログラムにしてみました。Java言語がコンパイルできるPCで下のプログラムをmahoujin.javaというファイルで保存します。
> javac mahoujin.java
> java Mahoujin
と5×5の魔方陣が表示されると思います。3行目の変数nの値は魔方陣の1辺の大きさになります。ここを変更すれば99×99のような大きな魔方陣も求めることができます。
このような手順を「アルゴリズム」と言います。つまり、「アルゴリズム」とはコンピュータで計算を行うときの「計算方法」ということになりますね。試行錯誤を繰り返して魔方陣を求めるよりも、簡単に求められる「やり方」だと言っていいでしょう。問題の答えを求める一般的なやり方を見つけることが、コンピュータで答えを見つけることにつながるということになります。
奇数次の魔方陣を求めるアルゴリズムの他にも偶数次の魔方陣を求めるアルゴリズムもあります。皆さんでチャレンジしてみてください。
public class Mahoujin {
public static void main(String[] args) {
int n=5; //魔方陣の1辺の大きさ 魔方陣は n×n になる。
int x,y; // 魔方陣の座標
int[][] m=new int[n+1][n+1]; // 1からnでアクセスするのでn+1個必要
for (int i=1; i<=n; i++){ // n×nの魔方陣を0で初期化
for (int j=1; j<=n; j++){
m[i][j]=0; }
}
x = (1+n)/2; //スタートは1行目の中央から
y = 1; //1行目
m[y][x] =1; // 1行目の中央に1を置く
for (int i=2; i<= n*n; i++){ //残り2..n*nまで
int nextX, nextY;
nextX = x + 1;
nextY = y - 1;
if(nextX > n) { // 範囲外を参照した場合、回り込む
nextX = 1;
}
if(nextY < 1) {
nextY = n;
}
if(m[nextY][nextX] != 0) { // 次座標が埋まっている場合、下の座標へ
nextX = x;
nextY = y + 1;
}
m[nextY][nextX] = i;
x = nextX;
y = nextY;
}
for (int i=1; i<=n; i++) { // 魔方陣の出力
for (int j=1; j<=n; j++){
System.out.print((m[i][j]) + "\t");
}
System.out.println();
}
}
}
魔方陣を求めるプログラム(mahoujin.javaという名前で保存してください)
掲載大学 学部 |
静岡大学 情報学部 | 静岡大学 情報学部のページへ>> |
私たちが考える未来/地球を救う科学技術の定義 | 現在、環境問題や枯渇資源問題など、さまざまな問題に直面しています。 これまでもわたしたちの生活を身近に支えてきた”工学” が、これから直面する問題を解決するために重要な役割を担っていると考えます。 |