サイズ: 459
コメント:
|
サイズ: 3088
コメント:
|
削除された箇所はこのように表示されます。 | 追加された箇所はこのように表示されます。 |
行 3: | 行 3: |
{{{ int spx, spy; |
右下の1つを除いた他のピースをばらばらに入れ替えた後、 スライドするだけで元の位置に戻すのがこのパズル(15ゲーム)の問題です。 どんなにばらばらに配置しても元の位置にもどせるのかというと、そうではありません。 . '''元にもどせる配置と、元にもどせない配置があります。''' どんな配置だと元にもどせるかを解説した後、 元にもどせる配置だけを作成するメソッドを示します。 ---- === ちょっと数学的な説明 === 並び、置換、互換とその関係の説明をします。 ==== 並び ==== 並べるものの一つ一つを数で表すことにすると、 例えば5つのものの'''並び'''は . (1,2,3,4,5) や . (1,3,5,4,2) や . (4,3,2,5,1) のように書けます。 並び(4,3,2,5,1)は . 4という目印のものが1番目に . 3という目印のものが2番目に . 2という目印のものが3番目に . 5という目印のものが4番目に . 1という目印のものが5番目に 並んでいることを表しています。 ==== 置換 ==== . ものの並びの順番を入れ替える操作を(数学の用語では)'''置換'''と言います。 たとえば . 並び(1,2,3,4,5)を . 並び(1,3,5,4,2)に変える操作 も置換の1つです。 ==== 互換 ==== . 置換のうち2つの要素を互いに入れ替えるものを互換といいます。 たとえば . 並び(1,2,3,4,5)を . 並び(2,1,3,4,5)に変える操作 は互換の1つです。 交換される2つ以外の要素の位置は変わりません。 ==== 互換の積 ==== . 置換は互換の積で表すことができます。 どんな置換(入れ替え)も、互換(2つの入れ替え)を繰り返すことで行うことができるという意味です。 たとえば (1,2,3,4,5)に互換(2←→3)を行うと(1,3,2,4,5) (1,3,2,4,5)に互換(2←→5)を行うと(1,3,5,4,2) と、2回の互換で上の置換ができました。 他の方法もあります。 しかしどの方法をとっても、互換の回数は偶数回か奇数回のどちらかになります。 偶置換、奇置換といいます。 ---- 15ゲームでは 偶置換の問題は解けるが、奇置換の問題は解けません。 偶置換の問題だけを作るようにプログラムを作成します。 最初に正しい位置に配置した後 互換を偶数回行うことで問題を作成します。 ---- {{{#!java void shokika() { int x, y, x2, y2, w, cnt; ... ... for (cnt = 0; cnt < (tate*yoko*2); cnt++) { x = (int)(Math.random() * (yoko-1)); y = (int)(Math.random() * (tate-1)); if(Math.random() < 0.5) { x2 = x; y2 = y + 1; } else { x2 = x + 1; y2 = y; } w = ban[x][y]; ban[x][y] = ban[x2][y2]; ban[x2][y2] = w; } } |
行 6: | 行 109: |
{{{ g.setColor(Color.lightGray); g.fillRect(spx*haba, spy*haba, haba, haba); }}} {{{ spx = yoko-1; spy = tate-1; for (cnt = 0; cnt < (tate*yoko*2); ) // 偶数回置換 { x = (int)(Math.random() * yoko); y = (int)(Math.random() * tate); if(x != spx || y != spy) { ban[spx][spy] = ban[x][y]; spx = x; spy = y; cnt++; } } }}} |
ばらばらにする
右下の1つを除いた他のピースをばらばらに入れ替えた後、 スライドするだけで元の位置に戻すのがこのパズル(15ゲーム)の問題です。
どんなにばらばらに配置しても元の位置にもどせるのかというと、そうではありません。
元にもどせる配置と、元にもどせない配置があります。
どんな配置だと元にもどせるかを解説した後、 元にもどせる配置だけを作成するメソッドを示します。
ちょっと数学的な説明
- 並び、置換、互換とその関係の説明をします。
並び
並べるものの一つ一つを数で表すことにすると、 例えば5つのものの並びは
- (1,2,3,4,5) や
- (1,3,5,4,2) や
- (4,3,2,5,1)
のように書けます。
並び(4,3,2,5,1)は
- 4という目印のものが1番目に
- 3という目印のものが2番目に
- 2という目印のものが3番目に
- 5という目印のものが4番目に
- 1という目印のものが5番目に
並んでいることを表しています。
置換
ものの並びの順番を入れ替える操作を(数学の用語では)置換と言います。
たとえば
- 並び(1,2,3,4,5)を
- 並び(1,3,5,4,2)に変える操作
も置換の1つです。
互換
- 置換のうち2つの要素を互いに入れ替えるものを互換といいます。
たとえば
- 並び(1,2,3,4,5)を
- 並び(2,1,3,4,5)に変える操作
は互換の1つです。
交換される2つ以外の要素の位置は変わりません。
互換の積
- 置換は互換の積で表すことができます。
どんな置換(入れ替え)も、互換(2つの入れ替え)を繰り返すことで行うことができるという意味です。
たとえば
(1,2,3,4,5)に互換(2←→3)を行うと(1,3,2,4,5) (1,3,2,4,5)に互換(2←→5)を行うと(1,3,5,4,2) と、2回の互換で上の置換ができました。
他の方法もあります。
しかしどの方法をとっても、互換の回数は偶数回か奇数回のどちらかになります。
偶置換、奇置換といいます。
15ゲームでは 偶置換の問題は解けるが、奇置換の問題は解けません。
偶置換の問題だけを作るようにプログラムを作成します。
最初に正しい位置に配置した後 互換を偶数回行うことで問題を作成します。
1 void shokika()
2 {
3 int x, y, x2, y2, w, cnt;
4 ...
5 ...
6 for (cnt = 0; cnt < (tate*yoko*2); cnt++)
7 {
8 x = (int)(Math.random() * (yoko-1));
9 y = (int)(Math.random() * (tate-1));
10 if(Math.random() < 0.5)
11 {
12 x2 = x;
13 y2 = y + 1;
14 }
15 else
16 {
17 x2 = x + 1;
18 y2 = y;
19 }
20 w = ban[x][y];
21 ban[x][y] = ban[x2][y2];
22 ban[x2][y2] = w;
23 }
24 }