今回は、「となりオセロ」の解法プログラムを取り上げます。「となりオセロ」のルールは、1人で遊べるようにオセロを元に私が考えてみました。 パズルとしても多少は面白いところがあると思いますので、解法プログラムを理解するためにも遊んでみてください。 「となりオセロ」のルールは、次のようなものです。
|
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||
スタート図 | 完成図 | 失敗図の一例 |
「となりオセロ」パズルは、左上に黒石が1つ置かれた盤面でスタートします。 スタート図では、左上の黒石の周囲の3ヶ所のみ石を置くことができます。 石の少ない間は石を置く毎に、石を置ける場所は増えていきます。すべての石を置き終わったときに、 すべて黒石であれば完成ということになります。(なお、パズルを改良 (?) して白石も混じった完成図も採用していますが、ここではすべてが黒石になる完成図のみを扱います。)
「となりオセロ」のルールはちょっとした思いつきですが、 何はともあれ正解がないことにはパズルが成立しないことになります。 また、正解がある場合にも、どの程度の正解率があるのか知りたいところです。 そこで、まずは最初に、総当たりの全手順探索のプログラムを作って調べてみました。
1: use strict; 2: my (%round, %board, $all, $black); my $start = "11"; my $n = 3; 3: 4: foreach my $i (1 .. $n) { # %round の作成 5: foreach my $j (1 .. $n) { 6: my @round = (); 7: foreach my $k (($i > 1 && $i < $n) ? ($i - 1, $i, $i + 1) : $i == 1 ? ($i, $i + 1) : ($i - 1, $i)) { 8: foreach my $l (($j > 1 && $j < $n) ? ($j - 1, $j, $j + 1) : $j == 1 ? ($j, $j + 1) : ($j - 1, $j)) { 9: next if $k == $i and $l == $j; # 自分自身のマス目を除外 10: push @round, $k . $l; 11: } 12: } 13: $round{"$i$j"} = [@round]; 14: } 15: } 16: 17: foreach my $i (1 .. $n) { # 石のない状態で %board を作成 18: foreach my $j (1 .. $n) { 19: my $key = $i . $j; 20: $board{$key} = [0]; 21: my $k = ($i > 1 && $i < $n) ? 2 : 1; 22: my $l = ($j > 1 && $j < $n) ? 2 : 1; 23: push @{$board{$key}}, $k + $l; 24: push @{$board{$key}}, scalar(@{$round{$key}}); 25: } 26: } 27: 28: $board{$start}->[0] = 1; # 11 に石を置く 29: foreach my $pos (@{$round{$start}}) { 30: --$board{$pos}->[2]; 31: if ("$pos$start" =~ /(.).\1/) { 32: --$board{$pos}->[1]; 33: } 34: } 35: 36: search(); 37: 38: sub search { 39: my @next_pos = grep { !$board{$_}->[0] and $board{$_}->[2] < @{$round{$_}} } keys %board; 40: foreach my $pos (@next_pos) { 41: $board{$pos}->[0] = 1; # 石を置く 42: foreach my $round (@{$round{$pos}}) { 43: --$board{$round}->[2]; 44: if ("$pos$round" =~ /(.).\1/) { 45: --$board{$round}->[1]; 46: $board{$round}->[0] = 3 - $board{$round}->[0] if $board{$round}->[0]; 47: } 48: } 49: 50: if (@next_pos == 1) { # 盤面が埋まった 51: ++$all; 52: ++$black unless grep { $board{$_}->[0] == 2 } keys %board; 53: } else { # 次の石を置くための再帰呼び出し 54: search(); 55: } 56: 57: $board{$pos}->[0] = 0; # 石を取り除く 58: foreach my $round (@{$round{$pos}}) { 59: ++$board{$round}->[2]; 60: if ("$pos$round" =~ /(.).\1/) { 61: ++$board{$round}->[1]; 62: $board{$round}->[0] = 3 - $board{$round}->[0] if $board{$round}->[0]; 63: } 64: } 65: } 66: } 67: 68: print "all: $all, black: $black\n";
プログラムの最初の方で、「となりオセロ」の盤面を作成します。盤面には2桁の番号を付け、 左上がマス目が 11 になります (下図、4 x 4 盤面)。盤面データは、ハッシュ %board で管理します。%board のキーがマス目の番号を表し、値には無名配列の中に3つのデータが格納されます。 3つのデータはそれぞれ、マス目の石の状態、隣接するタテとヨコの空きマス目の数、 隣接する周囲の空きマス目の数、となります。冒頭での盤面の作成は石のない状態で作成するので、%board の初期データは下図の右側のようになります。
|
%board = (11 => [0, 2, 3], 12 => [0, 3, 5], 13 => [0, 3, 5], 14 => [0, 2, 3], 21 => [0, 3, 5], 22 => [0, 4, 8], 23 => [0, 4, 8], 24 => [0, 3, 5], 31 => [0, 3, 5], 32 => [0, 4, 8], 33 => [0, 4, 8], 34 => [0, 3, 5], 41 => [0, 2, 3], 42 => [0, 3, 5], 43 => [0, 3, 5], 44 => [0, 2, 3]); |
無名配列の最初の「マス目の石の状態」は、0 が石が置かれていないことを意味し、 1が黒石であることを意味し、2 が白石であることを意味しています。石が置かれていない 0 の状態では、タテまたはヨコに石が置かれても変化しません。石は黒石として置かれるので、 そこで始めて1になります。その後は、タテまたはヨコに石が置かれると1と 2 の間で値がトグル (1の場合は 2 に、2 の場合は1になること) します。
2番目の「隣接するタテとヨコのの空きマス目の数」は、 隣接するタテまたはヨコに石が置かれたときに減らされます。逆の言い方をすると、 マス目に石を置いたときは、隣接するタテとヨコのデータを更新することになります。 3番目の「隣接する周囲の空きマス目の数」は2番目のデータとほぼ同様で、 タテとヨコに石を置いたときだけでなく斜めに隣接するマス目に置かれたときもデータを更新される点が異なります。
「となりオセロ」パズルは、11 のマス目に石を置いた状態からスタートします。11 に石を置くと %board は、初期値から太字で示したデータが変更されます。
|
%board = (11 => [1, 2, 3], 12 => [0, 2, 4], 13 => [0, 3, 5], 14 => [0, 2, 3], 21 => [0, 2, 4], 22 => [0, 4, 7], 23 => [0, 4, 8], 24 => [0, 3, 5], 31 => [0, 3, 5], 32 => [0, 4, 8], 33 => [0, 4, 8], 34 => [0, 3, 5], 41 => [0, 2, 3], 42 => [0, 3, 5], 43 => [0, 3, 5], 44 => [0, 2, 3]); |
2つ目からの石は、search() サブルーチンを呼び出して置いて行きます。 2つ目の石は、石が置いてなくかつ周囲に石の置いてある 12, 21, 23 の内の1つに置くことになります。仮に 12 に石を置いたとすると %board のデータは、次のように変更されます。
|
%board = (11 => [2, 1, 2], 12 => [1, 2, 4], 13 => [0, 2, 4], 14 => [0, 2, 3], 21 => [0, 2, 3], 22 => [0, 3, 6], 23 => [0, 4, 7], 24 => [0, 3, 5], 31 => [0, 3, 5], 32 => [0, 4, 8], 33 => [0, 4, 8], 34 => [0, 3, 5], 41 => [0, 2, 3], 42 => [0, 3, 5], 43 => [0, 3, 5], 44 => [0, 2, 3]); |
再帰呼び出し型の search() サブルーチンで次々に石を置いていくと、 総当たりの全手順探索ができます。盤面にすべて石が置かれたときに、 全手順数と盤面がすべて黒石になる正解手順数を数えていきます。ちなみに、盤面がすべて黒石になったときの %board のデータは、1番目がすべて1に、2番目と3番目がすべて 0 になります (下図)。なお、白石がある場合は、1番目のデータが 2 になるので簡単に判別できます。
|
%board = (11 => [1, 0, 0], 12 => [1, 0, 0], 13 => [1, 0, 0], 14 => [1, 0, 0], 21 => [1, 0, 0], 22 => [1, 0, 0], 23 => [1, 0, 0], 24 => [1, 0, 0], 31 => [1, 0, 0], 32 => [1, 0, 0], 33 => [1, 0, 0], 34 => [1, 0, 0], 41 => [1, 0, 0], 42 => [1, 0, 0], 43 => [1, 0, 0], 44 => [1, 0, 0]); |
全手順探索プログラムを私のパソコン (PentiumM 1.8GHz, 2GB RAM) で実行した結果は、次のようになりました。3 x 3 盤面は短時間で実行できることは分かっていましたが、4 x 4 盤面はどのくらい時間がかかるのか分かりませんでした。そこで、あらかじめ盤面に 4, 5 個の石を置いておいて、どのくらい時間がかかるか見て全体の時間を推測しました。 結果的に、約1カ月かかって実行を終了しました。
盤面 時間 全手順 正解手順 正解率 3 x 3 1s 9,240 304 3.29% 4 x 4 2,593,202s 19,157,271,840 5,813,496 0.03% (30d0h20m2s)
正解率は、3 x 3 盤面では 3.29%、4 x 4 盤面では 0.03% となりました。 この正解率では、ランダムにただ石を置いて行くだけでは正解できないことを示しています。 多少なりとも考える要素があるということで、パズルとして楽しめるものと思います。
正解手順探索のプログラムは、前節の全手順探索プログラムが出発点になります。 全手順探索プログラムから、不正解の手順を除外します。また、正解手順にも対称解や手順前後解もたくさんあります。 そのような解も、除外していきます。
1 use strict; 2 my (%round, %board, %hist, $black); my $start = "11"; my $n = 4; 3 4 foreach my $i (1 .. $n) { 5 foreach my $j (1 .. $n) { 6 my @round = (); 7 foreach my $k (($i > 1 && $i < $n) ? ($i - 1, $i, $i + 1) : $i == 1 ? ($i, $i + 1) : ($i - 1, $i)) { 8 foreach my $l (($j > 1 && $j < $n) ? ($j - 1, $j, $j + 1) : $j == 1 ? ($j, $j + 1) : ($j - 1, $j)) { 9 next if $k == $i and $l == $j; 10 push @round, $k . $l; 11 } 12 } 13 $round{"$i$j"} = [@round]; 14 } 15 } 16 17 foreach my $i (1 .. $n) { 18 foreach my $j (1 .. $n) { 19 my $key = $i . $j; 20 $board{$key} = [0]; 21 my $k = ($i > 1 && $i < $n) ? 2 : 1; 22 my $l = ($j > 1 && $j < $n) ? 2 : 1; 23 push @{$board{$key}}, $k + $l; 24 push @{$board{$key}}, scalar(@{$round{$key}}); 25 } 26 } 27 28 $board{$start}->[0] = 1; 29 foreach my $pos (@{$round{$start}}) { 30 --$board{$pos}->[2]; 31 if ("$pos$start" =~ /(.).\1/) { 32 --$board{$pos}->[1]; 33 } 34 } 35 36 search([11, join('', map { $board{$_}->[0] } sort keys %board)]); 37 38 sub search { 39 my $ref = shift; 40 my @next_pos = grep { !$board{$_}->[0] and $board{$_}->[2] < @{$round{$_}} 41 and $board{$_}->[1] % 2 == 0 and $board{$_}->[1] } keys %board; 42 my @stone = grep { $board{$_}->[0] } keys %board; 43 44 my $diag = 1; # 対角線対称マス目の除外 45 foreach my $pos (@stone) { 46 my $d_pos = reverse $pos; 47 next if $pos == $d_pos; 48 if ($board{$pos}->[0] != $board{$d_pos}->[0]) { $diag = 0; last; } 49 } 50 if ($diag) { 51 @next_pos = grep { substr($_, 0, 1) <= substr($_, 1, 1) } @next_pos; 52 } 53 54 if (@stone >= $n) { # 逆対角線対称マス目のの除外 55 my $gaid = 1; 56 foreach my $pos (@stone) { 57 my $g_pos = ($n + 1 - substr($pos, 1, 1)) . ($n + 1 - substr($pos, 0, 1)); 58 next if $pos == $g_pos; 59 if ($board{$pos}->[0] != $board{$g_pos}->[0]) { $gaid = 0; last; } 60 } 61 if ($gaid) { 62 @next_pos = grep { substr($_, 0, 1) + substr($_, 1, 1) <= $n + 1 } @next_pos; 63 } 64 } 65 66 foreach my $pos (@next_pos) { 67 $board{$pos}->[0] = 1; 68 foreach my $round (@{$round{$pos}}) { 69 --$board{$round}->[2]; 70 if ("$pos$round" =~ /(.).\1/) { 71 --$board{$round}->[1]; 72 $board{$round}->[0] = 3 - $board{$round}->[0] if $board{$round}->[0]; 73 } 74 } 75 76 my $patt = join '', map { $board{$_}->[0] } sort keys %board; 77 my $stone = @stone + 1; 78 unless (grep /$patt/, @{$hist{$stone}}) { 79 push @{$hist{$stone}}, $patt; 80 if (grep { !$board{$_}->[0] and $board{$_}->[1] } keys %board) { 81 search([$pos, $patt, $ref]); 82 } else { 83 display([$pos, $patt, $ref]); 84 ++$black; 85 } 86 } 87 88 $board{$pos}->[0] = 0; 89 foreach my $round (@{$round{$pos}}) { 90 ++$board{$round}->[2]; 91 if ("$pos$round" =~ /(.).\1/) { 92 ++$board{$round}->[1]; 93 $board{$round}->[0] = 3 - $board{$round}->[0] if $board{$round}->[0]; 94 } 95 } 96 } 97 } 98 99 sub display { # 正解手順の表示 100 my $tmp_ref = shift; 101 my @work; 102 while ($tmp_ref) { 103 my ($pos, $board); 104 ($pos, $board, $tmp_ref) = @$tmp_ref; 105 unshift @work, [sprintf("%-${n}s", $pos), $board =~ /.{$n}/g]; 106 } 107 108 my @line; 109 foreach my $i (0 .. $n) { 110 push @line, join(" ", map { $_->[$i] } @work); 111 } 112 print "$_\n" foreach @line; 113 print "\n"; 114 } 115 116 print "black: $black\n";
全手順探索プログラムで解説した部分は省略して、正解手順探索プログラムで追加した部分を主に解説します。
スタート図: ['11', '1000000000000000'] 2つ目の置き石時: ['12', '2100000000000000', 上の配列のリファレンス] 3つ目の置き石時: ['13', '2210000000000000', 上の配列のリファレンス] .....
上のデータ構造は、正解手順を表示するために使います。正解手順が得られたときに、 リファレンスをスタート図まで辿ると正解手順を表示するためのデータを取得できます。
Line 44 〜 52: 対角線対称マス目を除外 (本文で詳述)
Line 54 〜 64: 逆対角線対称マス目を除外 (本文で詳述)
正解手順探索のプログラムは、前節の全手順探索のプログラムに1つ1つコードを 追加しながら作っています。プログラムの説明は、4 x 4 盤面を使って行っていきます。4 x 4 盤面の次のデータが出発点となり、その遷移を見ていくことにします。
奇数マス目除外 時間: 730s(12m10s) 正解手順数: 5,813,496
下の図は 11, 22, 33, 44 と石を置いたところで、14 と 41 以外のマス目に石を置くことができます。
石を置くことができるマス目に書かれた数字は、タテとヨコに隣接する空きマス目の数です。
隣接する空きマス目の数が偶数の場合は最終的に黒石に、奇数の場合は最終的に白石になります。
奇数のマス目を除外すると、不正解手順を除外することができます。
|
my @next_pos = grep { !$board{$_}->[0] and $board{$_}->[2] < @{$round{$_}} and $board{$_}->[1] % 2 == 0 } keys %board; |
配列 @next_pos は、次に石を置くことのできる空きマス目のリストです。全手順探索では 12, 13, 21, 23, 24, 31, 32, 34, 42, 43 の 10 個ですが、太字のコードを追加すると奇数のマス目は除外されて 23 と 32 の2ヶ所だけ残ることになります。
奇数マス目を石を置く対象から外すと、大幅に時間が短縮されました。4 x 4 盤面で正解率が 0.03% ですので、期待したのですがその通りとなりました。これで不正解手順は生成されなくなりましたので、 以降は正解手順数のみ表示することにします。全手順探索は繰り返し実行することは簡単にはできませんが、 これで何度も実行できるくらいの時間になりました。
対角線対称除外 時間: 228s(3m48s) 正解手順数: 1,246,202
盤面の石の配置が 11, 22, 33, 44 の対角線に対して対称になっている場合は、11, 22, 33, 44
の対角線を含む上半分 (下図の水色のマス目) だけに石を置くようにします。11
のみに石が置いてあるスタート図も対角線対称で、石を置くことができる12, 22, 21 の内 21
は石を置く対象からは外されます。
下図の石の配置になるには、12 → 21 の順序のみに限定され、21 → 12 の順序は排除されます。
また、3つの石が置かれている下の図も対角線対称で、水色のマス目が石を置ける対象になります。
実際には周囲に石のある 13, 22, 23 のみに石を置けて、31, 32 は石を置けないことになります。
|
my $diag = 1; foreach my $pos (@stone) { my $d_pos = reverse $pos; next if $pos == $d_pos; if ($board{$pos}->[0] != $board{$d_pos}->[0]) { $diag = 0; last; } } if ($diag) { @next_pos = grep { substr($_, 0, 1) <= substr($_, 1, 1) } @next_pos; } |
逆対角線対称除外 時間: 213s(3m33s) 正解手順数: 952,572
逆対角線対象とは、14, 23, 32, 41 の対角線に対して対称になっているものをいいます。
逆対角線対称になっているのは、対角線対称よりもはるかに少なくなります。
逆対角線対称になる最小の置き石は、スタート図から 22, 33, 44 と石を置いた場合 (対角線対称でもある)
です。逆対角線対称も、対角線対称と同じように逆対角線を含む上半分のマス目が石を置ける対象になります。
閉所マス目の除外 時間: 0.5s 正解手順数: 1,007
盤面に石を置いていく過程で、隣接するタテとヨコにすべて石が置かれたマス目が出現します。
最小で4個のマス目を置いたときに、閉所マス目が出現することがあります (下図)。
この閉所マス目は、石を置かなくても最終的な結果に影響がなく石を置くことを省略できます。
閉所マス目に石を置かずに完成図とすると、4 〜 6 箇所のマス目に石を置かなくても済みます。
閉所マス目を省略した完成図は、ランダムの順序で空きマス目に石を置くことができ、
すべて石を置くと盤面が黒石のみの図となります。
|
my @next_pos = grep { !$board{$_}->[0] and $board{$_}->[2] < @{$round{$_}} and $board{$_}->[1] % 2 == 0 and $board{$_}->[1] } keys %board; ... if (grep { !$board{$_}->[0] and $board{$_}->[1] } keys %board) { search(...); |
閉所マス目を除外するコードは、少し離れている2ヶ所を修正します。配列 @next_pos から閉所マス目を除外するコードを追加し、それにともない閉所マス目のみになったときには search() 呼び出しを停止するコードの追加です。盤面の空きマス目が閉所マス目のみになった場合は、 その時点で完成したことにします。次の図は、閉所マス目に石を置かない完成図の1例です。
|
上の図では、末尾の5手を省略することができます。対角線対称、逆対角線対称がなければ、 最大で 5! が正解手順数から除外されることになります。また、1つ上の図の4個の置き石の例では、 5個目以降に常に置き石の対象になるのを除外しています。閉所マス目を除外するコードを追加すると、 正解手順数は劇的に減少し、時間も1秒未満になりました。
手順前後除外 時間: 0.1s 正解手順数: 10
最後に追加したのは、手順前後を除外するコードです。下の図では、対角線対称の 32, 43 を除いた 23, 34, 44
が次に石を置けるマス目です。次に連続して 23 と 34 に石を置く場合に 23 → 34 と 34 → 23
の2つの順序は、手順前後による同一図になります。また、23 → 44 と 44 → 23 も同じです。
|
my $patt = join '', map { $board{$_}->[0] } sort keys %board; my $stone = @stone + 1; unless (grep /$patt/, @{$hist{$stone}}) { push @{$hist{$stone}}, $patt; ... } |
手順前後を除外すると、正解手順数は 10 になり、時間はほぼ瞬時に終わるようになりました。 何をもって正解手順数とするのかは難しいのですが、全手順探索の正解手順数 5,813,496 から対角線対象、逆対角線対象、閉所マス目、手順前後を除外した 10 を 4 x 4 盤面の正解手順数とすることにしました。なお、3 x 3 盤面では正解手順数が 2 に、5 x 5 盤面では時間が 416 秒かかり正解手順数が 203 になりました。
以上説明してきたほかに正解手順探索では、正解手順を表示するコードを追加しています。 正解手順が得られたら、その都度 display サブルーチンを呼び出しています。 最初の行に置いた石のマス目番号を表示し、次の行からは盤面の石の配置を表示しています。3 x 3 盤面では、次の2つの正解手順が表示されます。
11 12 21 22 23 32 100 210 110 120 120 120 000 000 100 210 221 211 000 000 000 000 000 010 11 22 13 31 33 100 100 101 101 101 000 010 010 010 010 000 000 000 100 101
3 x 3 盤面の手順は、最初に 12 に置くか 22 に置くかの選択肢があるだけで、 その後の手順は1つの手順に集約されることになります。2つのうちの最初の正解手順の3手目以降を、 詳細に見てみることにしましょう。
最初の手順は、3手目以降に複数の選択肢がない絶対的な手順になります。 2つ目の正解手順は、3手目に 13 か 33 に置くことになりどちらに置いたとしても、 その後2つの石を置くと完成図以外には到達しません。手順前後が成立するだけで、 解としては1つになります。3 x 3 盤面での正解手順が2つであるのは、 妥当なものとして受け入れることができるものと思います。4 x 4 盤面では、次の 10 の正解手順が表示されます。
11 12 13 21 22 23 24 31 32 33 42 44 1000 2100 2210 1210 1110 1120 1120 1120 1120 1120 1120 1120 0000 0000 0000 1000 2100 2210 2221 1221 1121 1111 1111 1111 0000 0000 0000 0000 0000 0000 0000 1000 2100 2210 2110 2110 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100 0101 11 12 13 21 22 23 24 31 32 34 42 43 1000 2100 2210 1210 1110 1120 1120 1120 1120 1120 1120 1120 0000 0000 0000 1000 2100 2210 2221 1221 1121 1122 1122 1122 0000 0000 0000 0000 0000 0000 0000 1000 2100 2101 2201 2201 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100 0210 11 12 13 21 22 23 24 31 34 33 43 42 1000 2100 2210 1210 1110 1120 1120 1120 1120 1120 1120 1120 0000 0000 0000 1000 2100 2210 2221 1221 1222 1212 1212 1212 0000 0000 0000 0000 0000 0000 0000 1000 1001 1012 1022 1022 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010 0120 11 12 13 21 22 23 24 34 33 32 41 43 1000 2100 2210 1210 1110 1120 1120 1120 1120 1120 1120 1120 0000 0000 0000 1000 2100 2210 2221 2222 2212 2112 2112 2112 0000 0000 0000 0000 0000 0000 0000 0001 0012 0122 0122 0112 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1000 1010 11 12 13 21 22 31 33 34 24 43 42 1000 2100 2210 1210 1110 1110 1110 1110 1110 1110 1110 0000 0000 0000 1000 2100 1100 1100 1100 1101 1101 1101 0000 0000 0000 0000 0000 1000 1010 1021 1022 1012 1012 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010 0120 11 12 13 21 22 33 32 34 24 41 43 1000 2100 2210 1210 1110 1110 1110 1110 1110 1110 1110 0000 0000 0000 1000 2100 2100 2200 2200 2201 2201 2201 0000 0000 0000 0000 0000 0010 0120 0111 0112 0112 0122 0000 0000 0000 0000 0000 0000 0000 0000 0000 1000 1010 11 12 21 22 33 23 14 31 34 43 42 1000 2100 1100 1200 1200 1200 1201 1201 1201 1201 1201 0000 0000 1000 2100 2100 2210 2210 1210 1210 1210 1210 0000 0000 0000 0000 0010 0020 0020 1020 1011 1021 1021 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010 0120 11 12 21 22 33 23 14 32 34 41 43 1000 2100 1100 1200 1200 1200 1201 1201 1201 1201 1201 0000 0000 1000 2100 2100 2210 2210 2110 2110 2110 2110 0000 0000 0000 0000 0010 0020 0020 0110 0121 0121 0111 0000 0000 0000 0000 0000 0000 0000 0000 0000 1000 1010 11 12 21 23 14 32 33 34 41 43 1000 2100 1100 1100 1101 1101 1101 1101 1101 1101 0000 0000 1000 1010 1010 1010 1020 1020 1020 1020 0000 0000 0000 0000 0000 0100 0210 0221 0221 0211 0000 0000 0000 0000 0000 0000 0000 0000 1000 1010 11 22 33 23 13 24 32 31 42 44 1000 1000 1000 1000 1010 1010 1010 1010 1010 1010 0000 0100 0100 0210 0220 0211 0111 0111 0111 0111 0000 0000 0010 0020 0020 0020 0110 1210 1110 1110 0000 0000 0000 0000 0000 0000 0000 0000 0100 0101
(2010/08/15)