local fmt = require "fmt" require "perm" local colors = {"Red", "Green", "White", "Yellow", "Blue"} local nations = {"English", "Swede", "Danish", "Norwegian", "German"} local animals = {"Dog", "Birds", "Cats", "Horse", "Zebra"} local drinks = {"Tea", "Coffee", "Milk", "Beer", "Water"} local smokes = {"Pall Mall", "Dunhill", "Blend", "Blue Master", "Prince"} local p = perm.list({1, 2, 3, 4, 5}) local function check(a1, a2, v1, v2) for i = 1, 5 do if p[a1][i] == v1 then return p[a2][i] == v2 end end return false end local function check_left(a1, a2, v1, v2) for i = 1, 4 do if p[a1][i] == v1 then return p[a2][i + 1] == v2 end end return false end local function check_right(a1, a2, v1, v2) for i = 2, 5 do if p[a1][i] == v1 then return p[a2][i - 1] == v2 end end return false end local function check_adjacent(a1, a2, v1, v2) return check_left(a1, a2, v1, v2) or check_right(a1, a2, v1, v2) end local function print_houses(c, n, a, d, s) local owner = "" print("House Color Nation Animal Drink Smokes") print("===== ====== ========= ====== ====== ===========") for i = 1, 5 do local f = "%3d %-6s %-9s %-6s %-6s %-11s" local l = {i, colors[p[c][i]], nations[p[n][i]], animals[p[a][i]], drinks[p[d][i]], smokes[p[s][i]]} fmt.print(f, l:unpack()) if animals[p[a][i]] == "Zebra" then owner = nations[p[n][i]] end end print($"\nThe {owner} owns the Zebra\n") end local function fill_houses() local solutions = 0 for c = 1, 120 do if !check_left(c, c, 2, 3) then continue end -- C5 : Green left of white for n = 1, 120 do if p[n][1] != 4 then continue end -- C10: Norwegian in First if !check(n, c, 1, 1) then continue end -- C2 : English in Red if !check_adjacent(n, c, 4, 5) then continue end -- C15: Norwegian next to Blue for a = 1, 120 do if !check(a, n, 1, 2) then continue end -- C3 : Swede has Dog for d = 1, 120 do if p[d][3] != 3 then continue end -- C9 : Middle drinks Milk if !check(d, n, 1, 3) then continue end -- C4 : Dane drinks Tea if !check(d, c, 2, 2) then continue end -- C6 : Green drinks Coffee for s = 1, 120 do if !check(s, a, 1, 2) then continue end -- C7 : Pall Mall has Birds if !check(s, c, 2, 4) then continue end -- C8 : Yellow smokes Dunhill if !check(s, d, 4, 4) then continue end -- C13: Blue Master drinks Beer if !check(s, n, 5, 5) then continue end -- C14: German smokes Prince if !check_adjacent(s, a, 3, 3) then continue end -- C11: Blend next to Cats if !check_adjacent(s, a, 2, 4) then continue end -- C12: Dunhill next to Horse if !check_adjacent(s, d, 3, 5) then continue end -- C16: Blend next to Water ++solutions print_houses(c, n, a, d, s) end end end end end return solutions end local solutions = fill_houses() local plural = fmt.plural(solutions, "solution") print($"{solutions} {plural} found")