Einstein's Riddle
This is a fun logic puzzle that was very tedious to transpose into prolog. But once copied, the code reads very straightforward!
default_house(house(_Number, _Color,_Country,_Beverage,_Candy,_Pet)).
house_number(house(Number,_, _, _, _, _), Number) :-
home(Number).
house_color(house(_, Color, _, _, _, _), Color) :-
color(Color).
house_country(house(_, _,Country, _, _, _), Country) :-
country(Country).
house_beverage(house(_, _,_,Beverage, _, _), Beverage) :-
beverage(Beverage).
house_candy(house(_, _,_, _, Candy, _), Candy) :-
candy(Candy).
house_pet(house(_, _,_, _, _, Pet), Pet) :-
pet(Pet).
home(1).
home(2).
home(3).
home(4).
home(5).
home_nextto(1,2).
home_nextto(2,1).
home_nextto(2,3).
home_nextto(3,2).
home_nextto(3,4).
home_nextto(4,3).
home_nextto(4,5).
home_nextto(5,4).
color(red).
color(green).
color(ivory).
color(blue).
color(yellow).
country(english).
country(spain).
country(ukraine).
country(norway).
country(japan).
beverage(coffee).
beverage(tea).
beverage(milk).
beverage(water).
beverage(oj).
candy(mandm).
candy(cadbury).
candy(snickers).
candy(kitkat).
candy(reese).
pet(horse).
pet(dog).
pet(snail).
pet(fox).
pet(zebra).
solve(Solution) :-
length(Solution, 5),
maplist(default_house, Solution),
r2(Solution),
r3(Solution),
r4(Solution),
r5(Solution),
r6(Solution),
r7(Solution),
r8(Solution),
r9(Solution),
r10(Solution),
r11(Solution),
r12(Solution),
r13(Solution),
r14(Solution),
r15(Solution),
r1(Solution).
r1(Solution) :-
maplist(house_number, Solution, HN),
findall(X, home(X), HN_all),
permutation(HN, HN_all),
maplist(house_color, Solution, HC),
findall(X, color(X), HC_all),
permutation(HC, HC_all),
maplist(house_country, Solution, HY),
findall(X, country(X), HY_all),
permutation(HY, HY_all),
maplist(house_beverage, Solution, HB),
findall(X, beverage(X), HB_all),
permutation(HB, HB_all),
maplist(house_candy, Solution, HCa),
findall(X, candy(X), HCa_all),
permutation(HCa, HCa_all),
maplist(house_pet, Solution, HP),
findall(X, pet(X), HP_all),
permutation(HP, HP_all).
r2(Solution) :-
member(H, Solution),
house_country(H, english),
house_color(H, red).
r3(Solution) :-
member(H, Solution),
house_country(H, spain),
house_pet(H, dog).
r4(Solution) :-
member(H, Solution),
house_color(H, green),
house_beverage(H, coffee).
r5(Solution) :-
member(H, Solution),
house_country(H, ukraine),
house_beverage(H, tea).
r6(Solution) :-
member(HG, Solution),
house_color(HG, green),
member(HI, Solution),
house_color(HI, ivory),
house_number(HG, HGNum),
house_number(HI, HINum),
HGNum is HINum+1.
r7(Solution) :-
member(H, Solution),
house_candy(H, mandm),
house_pet(H, snail).
r8(Solution) :-
member(H, Solution),
house_candy(H, kitkat),
house_color(H, yellow).
r9(Solution) :-
member(H, Solution),
house_beverage(H, milk),
house_number(H, 3).
r10(Solution) :-
member(H, Solution),
house_country(H, norway),
house_number(H, 1).
r11(Solution) :-
member(HC, Solution),
house_candy(HC, cadbury),
member(HF, Solution),
house_pet(HF, fox),
house_number(HC, HCNum),
house_number(HF, HFNum),
home_nextto(HCNum,HFNum).
r12(Solution) :-
member(HK, Solution),
house_candy(HK, kitkat),
member(HH, Solution),
house_pet(HH, horse),
house_number(HK, HKNum),
house_number(HH, HHNum),
home_nextto(HKNum,HHNum).
r13(Solution) :-
member(H, Solution),
house_candy(H, snickers),
house_beverage(H,oj).
r14(Solution) :-
member(H, Solution),
house_candy(H, reese),
house_country(H,japan).
r15(Solution) :-
member(HN, Solution),
house_country(HN, norway),
member(HB, Solution),
house_color(HB, blue),
house_number(HN, HNNum),
house_number(HB, HBNum),
home_nextto(HNNum,HBNum).
Then query with:
solve(Solution),
member(WaterHouse, Solution),
house_beverage(WaterHouse, water),
member(ZebraHouse, Solution),
house_pet(ZebraHouse, zebra).
To give output:
Solution = [house(3,red,english,milk,mandm,snail), house(4,ivory,spain,oj,snickers,dog), house(5,green,japan,coffee,reese,zebra), house(2,blue,ukraine,tea,cadbury,horse), house(1,yellow,norway,water,kitkat,fox)],
WaterHouse = house(1,yellow,norway,water,kitkat,fox),
ZebraHouse = house(5,green,japan,coffee,reese,zebra)
On swish this runs in 0.106 seconds. Interesting to note is that if we move r1 to in front of r2, this goes to more than 5minutes.
Also to note - using library(record) would have been nice, but swish doesn’t support it.