Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
First solution in Uncategorized category for The Einstein Problem-Lite by Moff
class House(object):
COLORS = ['blue', 'green', 'red', 'white', 'yellow']
PETS = ['cat', 'bird', 'dog', 'fish', 'horse']
BEVERAGES = ['beer', 'coffee', 'milk', 'tea', 'water']
CIGARETTES = ['Rothmans', 'Dunhill', 'Pall Mall', 'Winfield', 'Marlboro']
NATIONALITY = ['Brit', 'Dane', 'German', 'Norwegian', 'Swede']
NUMBERS = ['1', '2', '3', '4', '5']
QUESTIONS = ['number', 'color', 'nationality', 'beverage', 'cigarettes', 'pet']
QUESTION_PROPS = {'number': NUMBERS, 'color': COLORS, 'nationality': NATIONALITY,
'beverage': BEVERAGES, 'cigarettes': CIGARETTES, 'pet': PETS}
def __init__(self, relation):
self.props = {self.prop_name(val): val for val in relation.split('-')}
@classmethod
def prop_name(cls, value):
for name, values in cls.QUESTION_PROPS.items():
if value in values:
return name
def union(self, other):
self.props.update(other.props)
def is_same(self, other):
return any(self.props.get(key) == value for key, value in other.props.items())
def is_complete(self):
return len(self.props) == len(self.QUESTION_PROPS)
def is_conflicted(self, other):
return any(key in self.props and self.props[key] != value for key, value in other.props.items())
class Puzzle(object):
def __init__(self, relations):
self.houses = []
self.unused_props = {k: set(v) for k, v in House.QUESTION_PROPS.items()}
for r in relations:
house = House(r)
self.houses.append(house)
for k, v in house.props.items():
self.unused_props[k].discard(v)
@staticmethod
def find_same_house(houses, obj):
for house in houses:
if obj.is_same(house):
return house
@classmethod
def combine_relations(cls, houses):
found = True
while found:
found = False
combined_houses = []
for obj1 in houses:
obj2 = cls.find_same_house(combined_houses, obj1)
if obj2 is not None:
obj2.union(obj1)
found = True
else:
combined_houses.append(obj1)
houses = combined_houses
return houses
@classmethod
def combine_possibles(cls, houses):
combined_houses = []
while houses:
h1 = houses.pop(0)
if not h1.is_complete():
found = None
for h2 in houses:
if not h1.is_conflicted(h2):
found = h2
break
if found is not None:
houses.remove(h2)
h1.union(h2)
combined_houses.append(h1)
return combined_houses
def solve(self, question):
houses = self.combine_relations(self.houses)
houses = self.combine_possibles(houses)
question_value, question_name = question.split('-')
for h in houses:
for key, values in self.unused_props.items():
for v in values:
if key not in h.props:
h.props[key] = v
for key, value in h.props.items():
if value == question_value:
return h.props[question_name]
def answer(relations, question):
return Puzzle(relations).solve(question)
Aug. 31, 2015