結城先生の薬品格納クイズ(Ruby)
「既約分数クイズ」に続いて、結城先生の「薬品格納クイズ」というというのをやってみます。
薬品格納クイズ
問題:
http://www.hyuki.com/dig/medquiz.html
6×2=12個の区画に分かれている薬品箱があります。 ここにA, Bという二種類の薬品を格納します。 ところが、薬品Bは縦や横に隣り合った区画に並べて格納すると発火してしまいます(斜めなら大丈夫。薬品Aは並べても大丈夫)。 このとき、発火しない格納方法は全部で何通りあるでしょうか。
補足しておくと、薬品 B がひとつもない場合も含みます。また、すべての区画に A か B のいずれかが入っていなければなりません。
Ruby で解いてみました。完全に brute-force でエレガントでない解き方です。
def check(ar) for i in 0...5 if ar.include?(i) && ar.include?(i + 1) or ar.include?(i + 6) && ar.include?(i + 7) or ar.include?(i) && ar.include?(i + 6) return false end end return false if ar.include?(5) && ar.include?(11) true end counter = 1 for i in 1..12 (0...12).to_a.combination(i) {|ar| counter += 1 if check(ar)} end puts counter #=>239
実行時間は、僕の環境でこうなりました。Linux Mint 18.2 @ Core i5 4210U 1.70GHz (Ruby 2.3.3)
real 0m0.113s user 0m0.080s sys 0m0.004s