ナンプレ(数独)問題作成プログラム その13
前回のプログラムを実行出来るように solve.c の main を変更する。
たいした変更じゃないのでMSaito/NumPl · GitHubを見て。
で、実行すると、
./solve -r " 6 31 9 9 427 7 1 6 7 8 5 2 5 143 9 8 24 61 " quiet = 0 recursion = 1 argc = 1 ??6?31?9? ??9???427 ?7??????? ??1??6??? ??7???8?? ???5??2?? ???????5? 143???9?? ?8?24?61? has more than 2 solution ??6?31?9? ??9???427 ?7??????? ??1??6??? ??7???8?? ???5??2?? ???????5? 143???9?? ?8?24?61? 426731598 319865427 578492136 251976345 937124861 864583279 692318754 143657982 785249613
とかいう結果が出ておかしい。困ったことに、recursion_solve がおかしいという可能性と、これまでのsolveがおかしいという可能性がある。だが、上の出力をじっと見つめると、
864583279
という行があり、8が2回出てくるので間違い。つまり、recursion_solveに問題があることは間違いない。そこでいろいろ調べたりするのだが、実は今回このブログで発表するためにかっこよく変更した部分があって、そこのバグなのであった。
それは、kill_single.c の kill_line 関数である。forループを2回まわるだけで行内のsingleを消せるという部分である。その最初のforループ
for (int i = 0; i < LINE_SIZE; i++) { int idx = line[i]; if (is_single(ar[idx])) { syms |= ar[idx].symbol; } }
上のプログラムだと、さっきのように行内に8が二つあるような場合でも、そのまま見過ごしてしまう。そこで次のように変更すると同じ数字が二つある場合にチェックできる。(count の使い回しが気になるが、count していることは確かなので別の変数を取る必要はないかなと思う)
for (int i = 0; i < LINE_SIZE; i++) { int idx = line[i]; if (is_single(ar[idx])) { syms |= ar[idx].symbol; count++; } } if (count != ones16(syms)) { return -1; } count = 0;
もうひとつの問題点は、recursion_solve が解を返さないことなので、解を返すように修正。実行すると、
$ ./solve -r " 6 31 9 9 427 7 1 6 7 8 5 2 5 143 9 8 24 61 " quiet = 0 recursion = 1 argc = 1 ??6?31?9? ??9???427 ?7??????? ??1??6??? ??7???8?? ???5??2?? ???????5? 143???9?? ?8?24?61? solved 426731598 319865427 578924136 251486379 637192845 894573261 962318754 143657982 785249613
となる。これでrecursion_solveの動作は確認できた。(本当はもっとテストするべきだけど)
ヤング図形を求めるプログラムを載せようとしてやめた
いや、別のプログラムを載せると、別の人が検索してやってくるかもと思ったのだが、ヤング図形のプログラムで検索した結果、私のプログラムよりスマートらしく見えるプログラムがあったので掲載をやめたのだ。
- 作者: 寺田至
- 出版社/メーカー: 日本評論社
- 発売日: 2002/08
- メディア: 単行本
- クリック: 4回
- この商品を含むブログ (1件) を見る