Skip to content

Instantly share code, notes, and snippets.

@chriskottom
Last active November 21, 2015 06:50
Show Gist options
  • Save chriskottom/c18c2bded785e44361b2 to your computer and use it in GitHub Desktop.
Save chriskottom/c18c2bded785e44361b2 to your computer and use it in GitHub Desktop.
Einstein's Riddle Solver
# EINSTEIN'S RIDDLE
#
# There are five houses in five different colours in a row. In each house lives
# a person with a different nationality. The five owners drink a certain type of
# beverage, smoke a certain brand of cigar and keep a certain pet.
#
# No owners have the same pet, smoke the same brand of cigar, or drink the same
# beverage.
#
# Other facts:
# 1. The Brit lives in the red house.
# 2. The Swede keeps dogs as pets.
# 3. The Dane drinks tea.
# 4. The green house is on the immediate left of the white house.
# 5. The green house’s owner drinks coffee.
# 6. The owner who smokes Pall Mall rears birds.
# 7. The owner of the yellow house smokes Dunhill.
# 8. The owner living in the center house drinks milk.
# 9. The Norwegian lives in the first house.
# 10. The owner who smokes Blends lives next to the one who keeps cats.
# 11. The owner who keeps the horse lives next to the one who smokes Dunhill.
# 12. The owner who smokes Bluemasters drinks beer.
# 13. The German smokes Prince.
# 14. The Norwegian lives next to the blue house.
# 15. The owner who smokes Blends lives next to the one who drinks water.
#
# The question is: who owns the fish?
Block = Struct.new(:colors, :nationalities, :pets, :beverages, :cigars) do
def to_s
data = [ ["NUMBER", *(1..colors.length).map(&:to_s)],
["COLOR", *colors],
["NATIONALITY", *nationalities],
["PET", *pets],
["BEVERAGE", *beverages],
["CIGAR", *cigars] ]
col_width = data.flatten.map(&:length).max
rows = []
rows << vertical_bar(col_width, colors.count)
data.each { |r| rows << as_row(r, col_width) }
rows << vertical_bar(col_width, colors.count)
rows.join("\n")
end
private
def vertical_bar(width, count)
"|#{ Array.new(count + 1) { "-" * (width + 2) }.join('+') }|"
end
def as_row(vals, width)
"|#{ vals.map { |v| " #{ v.to_s.ljust(width) } " }.join("|") }|"
end
end
%i(Brit Norwegian German Swede Dane).permutation.each do |nationalities|
# 9. The Norwegian lives in the first house.
next unless nationalities.first == :Norwegian
%i(red white blue yellow green).permutation.each do |colors|
# 1. The Brit lives in the red house.
next unless nationalities.index(:Brit) == colors.index(:red)
# 4. The green house is on the immediate left of the white house.
next unless colors.index(:white) - colors.index(:green) == 1
# 14. The Norwegian lives next to the blue house.
next unless (nationalities.index(:Norwegian) - colors.index(:blue)).abs == 1
%i(dog bird cat horse fish).permutation.each do |pets|
# 2. The Swede keeps dogs as pets.
next unless nationalities.index(:Swede) == pets.index(:dog)
%i(milk water beer coffee tea).permutation.each do |beverages|
# 5. The green house’s owner drinks coffee.
next unless colors.index(:green) == beverages.index(:coffee)
# 8. The owner living in the center house drinks milk.
next unless beverages.index(:milk) == (beverages.length - 1)/2
# 3. The Dane drinks tea.
next unless nationalities.index(:Dane) == beverages.index(:tea)
%i(Prince Blends Bluemasters Dunhills PallMalls).permutation.each do |cigars|
# 6. The owner who smokes Pall Mall rears birds.
next unless cigars.index(:PallMalls) == pets.index(:bird)
# 7. The owner of the yellow house smokes Dunhill.
next unless cigars.index(:Dunhills) == colors.index(:yellow)
# 10. The owner who smokes Blends lives next to the one who keeps cats.
next unless (cigars.index(:Blends) - pets.index(:cat)).abs == 1
# 11. The owner who keeps the horse lives next to the one who smokes Dunhill.
next unless (cigars.index(:Dunhills) - pets.index(:horse)).abs == 1
# 12. The owner who smokes Bluemasters drinks beer.
next unless cigars.index(:Bluemasters) == beverages.index(:beer)
# 13. The German smokes Prince.
next unless cigars.index(:Prince) == nationalities.index(:German)
# 15. The owner who smokes Blends lives next to the one who drinks water
next unless (cigars.index(:Blends) - beverages.index(:water)).abs == 1
puts Block.new(colors, nationalities, pets, beverages, cigars)
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment