The following Prolog program due to Bill Clementsen and Ng Pheng Siong solves the problem in less than a second:
next_to(X, Y, List) :- iright(X, Y, List).
next_to(X, Y, List) :- iright(Y, X, List).
iright(L, R, [L | [R | _]]).
iright(L, R, [_ | Rest]) :- iright(L, R, Rest).
einstein(Houses, Fish_Owner) :-
=(Houses, [[house, norwegian, _, _, _, _], _, [house, _, _, _, milk, _], _, _]),
member([house, brit, _, _, _, red], Houses),
member([house, swede, dog, _, _, _], Houses),
member([house, dane, _, _, tea, _], Houses),
iright([house, _, _, _, _, green], [house, _, _, _, _, white], Houses),
member([house, _, _, _, coffee, green], Houses),
member([house, _, bird, pallmall, _, _], Houses),
member([house, _, _, dunhill, _, yellow], Houses),
next_to([house, _, _, dunhill, _, _], [house, _, horse, _, _, _], Houses),
member([house, _, _, _, milk, _], Houses),
next_to([house, _, _, marlboro, _, _], [house, _, cat, _, _, _], Houses),
next_to([house, _, _, marlboro, _, _], [house, _, _, _, water, _], Houses),
member([house, _, _, winfield, beer, _], Houses),
member([house, german, _, rothmans, _, _], Houses),
next_to([house, norwegian, _, _, _, _], [house, _, _, _, _, blue], Houses),
member([house, Fish_Owner, fish, _, _, _], Houses).
Here's the transcript:
[root@somejuan]# pl
% /root/.plrc compiled 0.00 sec, 396 bytes
Welcome to SWI-Prolog (Multi-threaded, Version 5.6.20)
Copyright (c) 1990-2006 University of Amsterdam.
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
Please visit http://www.swi-prolog.org for details.
For help, use ?- help(Topic). or ?- apropos(Word).
?- consult('/root/einstein').
% /root/einstein compiled 0.00 sec, 5,208 bytes
Yes
?- einstein(Houses, Fish_Owner).
Houses = [[house, norwegian, cat, dunhill, water, yellow], [house, dane, horse, marlboro, tea, blue],
[house, brit, bird, pallmall, milk, red]
, [house, german, fish, rothmans, coffee|...], [house, swede, dog, winfield|...]]
Fish_Owner = german
|