Wednesday, January 4, 2012

Jim Lies, Prolog Doesn't!

This is a rather famous puzzler, the answer to which is available on many websites. However, solving problems on a piece of paper is not always as interesting as writing a program to solve it. Prolog seems to be the best suited language to solve such constraint based problems. For those of you who do not know the problem and came to this blog anyway, here is the problem:


Jim lies a lot. He tells the truth only one day in a week. One day he said: "I lie on Mondays and Tuesdays." The next day he said: "Today is either Sunday, Saturday or Thursday." The next day he said: "I lie on Fridays and Wednesdays." On which day of the week does Jim tell the truth?

As we can see, trying to write C or Java code might get a little complicated. Here is the Prolog code that solves the problem on the predicate "start(Day)".

not(P) :- call(P),!,fail.
not(_).

dayone([false,false,Wednesday,Thursday,Friday,Saturday,Sunday]).
daytwo([Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday]) :-
(Sunday=true;Saturday=true;Thursday=true).
daythree([Monday,Tuesday,false,Thursday,false,Saturday,Sunday]).
dayafter([D1,D2,D3,D4,D5,D6,D7],[D2,D3,D4,D5,D6,D7,D1]).

start(Day) :- (
Day =[true,false,false,false,false,false,false];
Day =[false, true,false,false,false,false,false];
Day =[false,false, true,false,false,false,false];
Day =[false,false,false, true,false,false,false];
Day =[false,false,false,false, true,false,false];
Day =[false,false,false,false,false, true,false];
Day =[false,false,false,false,false,false, true]
),
dayafter(Day,Dayafter), dayafter(Dayafter,Day2After),
(
not(dayone(Day)),not(daytwo(Dayafter)),not(daythree(Day2After));
(dayone(Day)),not(daytwo(Dayafter)),not(daythree(Day2After));
not(dayone(Day)),(daytwo(Dayafter)),not(daythree(Day2After));
not(dayone(Day)),not(daytwo(Dayafter)),(daythree(Day2After))
).

Yes .. its Tuesday!

No comments:

Post a Comment