RosettaCodeData/Task/Zebra-puzzle/Crystal/zebra-puzzle.crystal
2023-07-01 13:44:08 -04:00

58 lines
2.4 KiB
Text

CONTENT = {House: [""],
Nationality: %i[English Swedish Danish Norwegian German],
Colour: %i[Red Green White Blue Yellow],
Pet: %i[Dog Birds Cats Horse Zebra],
Drink: %i[Tea Coffee Milk Beer Water],
Smoke: %i[PallMall Dunhill BlueMaster Prince Blend]}
def adjacent?(n, i, g, e)
(0..3).any? { |x| (n[x] == i && g[x + 1] == e) || (n[x + 1] == i && g[x] == e) }
end
def leftof?(n, i, g, e)
(0..3).any? { |x| n[x] == i && g[x + 1] == e }
end
def coincident?(n, i, g, e)
n.each_index.any? { |x| n[x] == i && g[x] == e }
end
def solve_zebra_puzzle
CONTENT[:Nationality].each_permutation { |nation|
next unless nation.first == :Norwegian # 10
CONTENT[:Colour].each_permutation { |colour|
next unless leftof?(colour, :Green, colour, :White) # 5
next unless coincident?(nation, :English, colour, :Red) # 2
next unless adjacent?(nation, :Norwegian, colour, :Blue) # 15
CONTENT[:Pet].each_permutation { |pet|
next unless coincident?(nation, :Swedish, pet, :Dog) # 3
CONTENT[:Drink].each_permutation { |drink|
next unless drink[2] == :Milk # 9
next unless coincident?(nation, :Danish, drink, :Tea) # 4
next unless coincident?(colour, :Green, drink, :Coffee) # 6
CONTENT[:Smoke].each_permutation { |smoke|
next unless coincident?(smoke, :PallMall, pet, :Birds) # 7
next unless coincident?(smoke, :Dunhill, colour, :Yellow) # 8
next unless coincident?(smoke, :BlueMaster, drink, :Beer) # 13
next unless coincident?(smoke, :Prince, nation, :German) # 14
next unless adjacent?(smoke, :Blend, pet, :Cats) # 11
next unless adjacent?(smoke, :Blend, drink, :Water) # 16
next unless adjacent?(smoke, :Dunhill, pet, :Horse) # 12
print_out(nation, colour, pet, drink, smoke)
}
}
}
}
}
end
def print_out(nation, colour, pet, drink, smoke)
width = CONTENT.map { |k, v| {k.to_s.size, v.max_of { |y| y.to_s.size }}.max }
fmt = width.map { |w| "%-#{w}s" }.join(" ")
national = nation[pet.index(:Zebra).not_nil!]
puts "The Zebra is owned by the man who is #{national}", ""
puts fmt % CONTENT.keys, fmt % width.map { |w| "-" * w }
[nation, colour, pet, drink, smoke].transpose.each.with_index(1) { |x, n| puts fmt % ([n] + x) }
end
solve_zebra_puzzle