I have attempted to a zebra puzzle in prolog and I was seeking some feedback as to the way I went about solving the puzzle.
Here is the puzzle:
Two weeks ago, four enthusiasts made sightings of objects in the sky in their neighborhood. Each of the four reported his or her sightings on a different day. The FBI came and was able to give each person a different explanation of what he or she had "really" seen. Can you determine the day (Tuesday through Friday) each person sighted the object, as well as the object that it turned out to be?
- Mr. K made his sighting at some point earlier in the week than the one who saw the balloon, but at some point later in the week, than the one who spotted the Kite (who isn't Ms. G).
- Friday's sighting was made by either Ms. Barn or the one who saw a plane (or both).
- Mr. Nik did not make his sighting on Tuesday.
- Mr. K isn't the one whose object turned out to be a telephone pole.
Here is a representation of how I found the solution to the problem:
I know K didn't spot the balloon (1) or the kite (2) or the telephone pole (6), so K spotted the plane. Also, K's day can't be Friday (1), so Friday was B's day (4).
I also know the kite wasn't spotted by K (2) or G (3). Nor was it spotted by B, since B's day was Friday and the kite can't have been spotted on Friday (2). So N spotted the kite. Also, we know kite day is two days before balloon day (1,2), so kite day must have been Tuesday or Wednesday; but N's day wasn't Tuesday (5), so kite day was Wednesday, which means K's day was Thursday (2) and balloon day was Friday (1).
And the rest I got by elimination. Summing up:
G spotted a telephone pole on Tuesday.
N spotted a kite on Wednesday.
K spotted a plane on Thursday.
B spotted a balloon on Friday.
And here is my prolog code:
before(X,Y,Ds) :-
remainder(X,Ds,Rs),
member(Y,Rs).
remainder(X,[X|Ds],Ds).
remainder(X,[_|Ds],Rs) :- remainder(X,Ds,Rs).
members([],_).
members([X|Xs],Ds) :-
member(X,Ds),
members(Xs,Ds).
puzzle :-
Days = [[tuesday,_,_],[wednesday,_,_],[thursday,_,_],[friday,_,_]],
before([_,mr_klien,_],[_,_,balloon],Days),
before([_,_,frisbee],[_,mr_klien,_],Days),
(member([friday,ms_barnum,_],Days);
member([friday,_,clothesline],Days);
member([friday,ms_barnum,clothesline],Days)),
members([[_,mr_klien,_],[_,ms_barnum,_],[_,ms_green,_],[_,mr_niven,_]],Days),
members([[_,_,balloon],[_,_,frisbee],[_,_,clothesline], [_,_,water_tower]],Days),
member([_,NOT_ms_green,frisbee],Days), NOT_ms_green \= ms_green,
member([tuesday,NOT_mr_niven,_],Days), NOT_mr_niven \= mr_niven,
member([_,NOT_mr_klien,water_tower],Days), NOT_mr_klien \= mr_klien,
write(Days),
nl,
fail.