RosettaCodeData/Task/Zebra-puzzle/Pluto/zebra-puzzle.pluto
2025-08-11 18:05:26 -07:00

84 lines
3.5 KiB
Text

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")