RosettaCodeData/Task/Zebra-puzzle/Ruby/zebra-puzzle-1.rb
2018-06-22 20:57:24 +00:00

54 lines
2.4 KiB
Ruby

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 and g[x+1]==e) or (n[x+1]==i and g[x]==e)}
end
def leftof? (n,i,g,e)
(0..3).any?{|x| n[x]==i and g[x+1]==e}
end
def coincident? (n,i,g,e)
n.each_index.any?{|x| n[x]==i and g[x]==e}
end
def solve_zebra_puzzle
CONTENT[:Nationality].permutation{|nation|
next unless nation.first == :Norwegian # 10
CONTENT[:Colour].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].permutation{|pet|
next unless coincident?(nation, :Swedish, pet, :Dog) # 3
CONTENT[:Drink].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].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{|x| x.flatten.map{|y|y.size}.max}
fmt = width.map{|w| "%-#{w}s"}.join(" ")
national = nation[ pet.find_index(:Zebra) ]
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