###################################### ペントミノの解を求めるプログラム May,1991. K.Mori ###################################### □概要□  ″ペントミノ″というパズルを御存じですか? 正方形を5つ繋ぎ合わせてできる図形 □□□□ □□□ □ □□ ↑こんなの や ↑こんなの これらは,全部で12種類あります.それらの図形を1種類ずつ使って,6×10の マス目を隙間なく埋めようというパズルです.ひまつぶしにはもってこいなのですが, 人間がやっていたのでは,すべての組み合わせを見つけ出すことはできません.  そういうのは,パソコンにやらせようとなるわけです. □作成の動機□  最初は,リカーシブ(再帰)の例題にするため,C言語で記述しました.MS−C でコンパイルしたところ,かなりの処理速度を得ました.ところがXCでは,期待し たスピードは得られませんでした(MSC+286/10MHzの4倍以上かかる). そこで,「アセンブラで書いたら,Z80でもXCより速くなるのではないか」と思 い,作成してみました. □アルゴリズム□ (0)  先に,ペントミノのブロックは,全部で12種類あると述べましたが,これらのブ ロックに$1〜$Cの番号をつけます.さらに90゜回転させたもの,対称形などを 組み合わせると,そのバリエーションは63種類になります.これらの図形データを, 左上の正方形を基準(0,0)とし,4組の整数値で表わし,テーブルとして用意し ておきます. 例) ■□ 黒い正方形は,白い正方形から見て □ 左へ1つ,下へ0 □□ 左へ1つ,下へ1つ 左へ1つ,下へ2つ 左へ2つ,下へ2つの位置にある. → DEFB 1,0, 1,1, 1,2, 2,2 (1) この図形テーブルからデータを1つ取り出して,6×10のマス目に置けるかどう かチェックしてゆきます.図形データは重複して使わないよう,既に使用済みのブロ ックは除かれます.また,マス目は,上から下,左から右に向かって埋めてゆくよう にします. (2) 取り出した図形が,指定の場所に置くことができれば,その場所にブロックの番号 を書き込んで,使用済みのフラグを立てて,(1)をコールします.そのブロックが ~~~~~~ 置けなければ,次のブロックのチェックとなります. (3)  もし,指定の場所にどのブロックも置くことができなかったとすると,1つ前に置 いたブロックが間違いだったことになります.そこで,そのブロックをマス目から取 り除いて,(もちろん使用済みのフラグからも削除して)リターンします. ~~~~~~~~ (4)  この手順で,すべての使用済みフラグが立てば(あるいは,サブルーチン・コール のネスティングが12レベルに達した時),めでたく完成となります.完成図を画面 に出して,つぎの解を求めるためリターンします. ~~~~~~~~  完成図の表示は、都合上1〜Cの記号で行なわれます。例えば □ C □□□ ならば、 CCC □ C といった具合です。 (5)  (1)をコールするときに,現在チェックしているブロックの番号をスタックに積 んでおくので,リターンしてきたときは,続きのブロックからのチェックになります. これで,プログラム終了までにすべての解を求めることができます. このアルゴリズムの具体的な内容は,ソースリストを参照してください. □起動方法□  ″SWORD″のコマンド・ラインから # PENTOMINO とキーインしてください.1つ目の解が出力されるのに1分程かかります. プリンタ出力される場合は, # PENTOMINO:/P としてください.画面表示と平行して,プリントアウトが行なわれます. □後味など□  時間がなかったので,最適化のようなものはやってません.すべての解(対称形な ど,重複するものを含んでいます)を表示するのに,4MHzで2日かかりませんで した.これでも充分XCより速いですが,手を加えれば,さらに速くなるでしょう.  時間があれば,正方形を立方体にして,3×4×5のかたまりをつくるパズル(3 Dペントミノとでも言おうか)に挑戦したいと思います. (EOF)