58 lines
2.4 KiB
Text
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
|