スケルトンが好きだ

注)今日の日記はいろいろ粗いので後日書き直すかも。

先日、Sugar制約ソルバーで、ひとりにしてくれの穴埋めを試みる話題を書きました。

Sugarを開発している田村研で、ニコリのパズルを解く実例は示されていますし、藤原博文さんの記事でニコリ以外のパズルを解く実例が示されていますので、基本的にはそちらを参照するのがいろいろ実りがあると思います。

じゃあぼくは、先達がやろうとしないことをやろうか、と思いまして、第一弾がひとくれの穴埋めだったわけです。次はじゃあ、言葉系のパズルを扱ってみたいなと、適当に思ってみました。
とはいうものの、豚辞書を丸ごと読み込んで、ナンクロをどうこう、とかはやはり手に余るので、数理系のパズルに近いところで、スケルトンを取り上げてみたいと思います。
ケルトンといえば、つい最近の1月に作った桜高軽音部ケルトンがありますね。これを題材にしましょう。

さて、突然あなたが桜高軽音部の中の人をテーマにしてパズルを作って欲しい、と依頼されたとしましょう。対象はファンの方々で、桜高軽音部の方々の名前を記入していればそれでシアワセ。パズル的な面白さは二の次三の次で、すべての部員のお名前が過不足なく使われていることがなによりも重要、という仕様だったとします。

でしたらスケルトンでいかがですか、と返事をする前に、はたして桜高軽音部のみなさんのお名前は、スケルトン枠にひとつながりに入るのかしらん? と、いう辺りを確かめておこう、という時に役立つスクリプトを組むこと、が目標です。

とりあえず1月に組んであるので、タテ6×ヨコ8の枠に収まることは判っています。簡単のため、これは固定しておきましょう。
さて、制約ソルバーなので制約を加えます。まずは、「とよさき」さんがどこかに入ることを表現してみます。「とよさき」がタテ6×ヨコ8の枠に入るということは、

(中略)

(中略)

の、いずれかになるということです。ということで、ひとつひとつの状態を記述して、orでつなげば、『どこかに「とよさき」が入る』が表現できます。他のお名前に関しても同じように記述します。

次に、スケルトン枠を形成する条件として、全体がひとつながりになっている、を考えます。まじめに設定してもいいんですが、
(リストの文字数−リストの単語数+1)>盤面に入る文字数
で良いんじゃないの? と思いついたのでこれでやってみます。実のところ、単語が輪を形成する場合、これは破綻するので、ちっとも良くはないのですが、まあ破綻したときは破綻したときでやり直しましょう。

最後に、余計な文字のつながりができない、という条件ですが、これは文字が2×2のカタマリにならない、という条件で良いんじゃないの、と思いついたのでこれでやってみます。少し考えればわかりますが、この条件も破綻してます。もう一度言いますが破綻したときは破綻したときです。

さて、以上の条件を全部突っ込んで作ってみたCSPファイルがこれ。ひらがなは直接扱えないので数字で置換してます。0は入らないとこですね。

(以下、マシンパワーによると思いますが、ぼくの環境で、ということで。。。)

さっそくSugarくんに渡してみます。10分。。。20分。。。1時間待ちましたが返答がありません。プログラムが悪いのか単にまだ頑張っているだけなのか、区別がつかないので、いったん止めて小さい盤面で確認することにします。この部分。

タテ3×ヨコ5のエリアに「とよさき」「さとみ」「みなこ」を入れてスケルトン盤面を作ってね、とお願いするわけですね。試してみると、数秒で答えを返してくれます。どうも意図したように動いてはいる模様です。じゃあってんでだんだん範囲を広げてみます。すると、ここまでは数十秒で思ったような反応を返してくれました。

ちなみに結果の出力はこんな感じ。

もしかしたらこのままいくんじゃないの、と期待したのですが、「さとう」さんを追加したら30分戻って来なくなりました。うーん。残念ですが、ソルバーの部分はぼくの手が入らないので、とりあえずここまで。
トータルでは、部分的には成功、といったところでしょうか。


以下は今回作ったもののサンプルです。(ぼくの環境では終わらなかったもののサンプルもあります)

入力単語リストサンプル

上の入力単語サンプルを、数値データに変換するawkスクリプト

このスクリプトの出力の、先頭1行目に盤面の横サイズ、先頭2行目に盤面の縦サイズを入力してください。こんな感じ。

こんな感じ、のファイルを、今回検討したCSPファイル形式に変換するawkスクリプト

ただし、途中にある(int x_0_0 0 7)みたいな部分は、先頭に持ってこないと動かないようです、カット&ペーストして下さい。