アルゴリズム・パズルです。
クロスワードを作る場合、空白と黒マスについて次のルールがあります。
黒マスルール - Wikipedia
- 黒マスは縦横に連続しない。
- 黒マスによって盤面が分断されてはいけない。
これを「黒マスルール」といいます。
さて、縦 5、横 6 のクロスワードパズルを作るとき、空白と黒マスの配置の仕方(盤面)は何とおりあるでしょうか。
Ruby で解いてみました。コード。
q67.rb
X, Y = 6, 5 @field = Array.new(L = X * Y, 0) #盤面。最初はすべて空白 @co = 0 #盤面が分断されていないか? def check area = @field.dup set = ->(n) { area[n] = 2 [-1, 1, X, -X].each do |dir| next if dir == -1 and (n % X).zero? next if dir == 1 and n % X == X - 1 next if dir == X and n >= L - X next if dir == -X and n < X m = n + dir set.(m) if area[m].zero? end } set.(area.find_index(0)) !area.find_index(0) end def try(i) if i >= L @co += 1 if check else #空白をセットしてひとつ先へ try(i + 1) #可能であれば黒マスをセットしてひとつ先へ if ((i % X).zero? or @field[i - 1].zero?) and (i < X or @field[i - X].zero?) @field[i] = 1 try(i + 1) @field[i] = 0 end end end try(0) puts @co
結果。
$ time ruby q67.rb 149283 real 0m9.822s user 0m9.788s sys 0m0.000s
結構むずかしかったですね。盤面の小さい場合で確かめながらコーディングしてようやくできました。
プログラマ脳を鍛える数学パズル シンプルで高速なコードが書けるようになる70問
- 作者: 増井敏克
- 出版社/メーカー: 翔泳社
- 発売日: 2015/10/16
- メディア: Kindle版
- この商品を含むブログ (9件) を見る