Einstein's riddle in Ruby

 ネタ切れぎみなので、『Einstein's riddle in JavaScript』で作ったプログラムをRubyに翻訳してみました。(^_^;
 get_pos()とnext_perm()は、Rubyの組み込み関数のindex()とpermutation()を使いました。

● Einstein.rb

#! ruby -Ks
# Einstein.rb
# # : 12345
# N : NDEGS
# H : YBRGW
# P : CHBFD
# D : WTMCB
# T : DMPRB

# 条件チェック: xからm個右側にyがあるか調べる
def check_cond(m, a, x, b, y)
    n = a.index(x)
    return false if n==nil || a.length<=m+n
    return true  if b[m+n]==y
    false
end

# マッチング条件
def check_match(a, x, b, y)
    check_cond(0, a, x, b, y)
end

# 順序付き隣接条件(左からx,yの順で隣接)
def check_adj_1(a, x, b, y)
    check_cond(1, a, x, b, y)
end

# 隣接条件(順不定)
def check_adj_2(a, x, b, y)
    check_adj_1(a,x,b,y)||check_adj_1(b,y,a,x)
end

# 要素を昇順にソートしたもの
PLACE =["1","2","3","4","5"]    # 場所(固定)
NATION=["D","E","G","N","S"]    # 国、国籍
HOUSE =["B","G","R","W","Y"]    # 家
PET   =["B","C","D","F","H"]    # ペット
DRINK =["B","C","M","T","W"]    # 飲み物
TABACO=["B","D","M","P","R"]    # タバコ(ポルトガル語)

# 連想配列
Nation={
    "D" => "D:デンマーク",
    "E" => "E:イギリス",
    "G" => "G:ドイツ",
    "N" => "N:ノルウェー",
    "S" => "S:スウェーデン"
}

tm=Time.now  # Timer Start
place  = PLACE .clone
NATION.permutation(5) do|nation|    # nation loop
    next if !check_match(nation,'N',place, '1')    # 条件09
    HOUSE.permutation(5) do|house|    # house loop
        next if !check_match(nation,'E',house, 'R')    # 条件01
        next if !check_adj_1(house, 'G',house, 'W')    # 条件04
        next if !check_adj_2(nation,'N',house, 'B')    # 条件14
        PET.permutation(5) do|pet|    #  pet loop
            next if !check_match(nation,'S',pet,   'D')    # 条件02
            DRINK.permutation(5) do|drink|    #  drink loop
                next if !check_match(nation,'D',drink, 'T')    # 条件03
                next if !check_match(house, 'G',drink, 'C')    # 条件05
                next if !check_match(place, '3',drink, 'M')    # 条件08
                TABACO.permutation(5) do|tabaco|    #  tabaco loop
                    next if !check_match(tabaco,'P',pet,   'B')    # 条件06
                    next if !check_match(house, 'Y',tabaco,'D')    # 条件07
                    next if !check_adj_2(tabaco,'M',pet,   'C')    # 条件10
                    next if !check_adj_2(pet,   'H',tabaco,'D')    # 条件11
                    next if !check_match(tabaco,'B',drink, 'B')    # 条件12
                    next if !check_match(nation,'G',tabaco,'R')    # 条件13
                    next if !check_adj_2(tabaco,'M',drink, 'W')    # 条件15
                    
                    # チェックを潜り抜けたものだけを表示
                    print("#:", place .join(""),"\n")
                    print("N:", nation.join(""),"\n")
                    print("H:", house .join(""),"\n")
                    print("P:", pet   .join(""),"\n")
                    print("D:", drink .join(""),"\n")
                    print("T:", tabaco.join(""),"\n")
                    print("\n")
                    print("",Nation[nation[pet.index('F')]],"\n");
                end
            end
        end
    end
end

tm=Time.now-tm  # Timer Stop
print "Runtime : %.3f [sec]\n"%tm

●実行結果

#:12345
N:NDEGS
H:YBRGW
P:CHBFD
D:WTMCB
T:DMPRB

∴G:ドイツ人
Runtime : 0.140 [sec]

パーフェクトRuby (PERFECT SERIES 6)

パーフェクトRuby (PERFECT SERIES 6)

Ruby逆引きハンドブック

Ruby逆引きハンドブック