Augustana logo

Programming Languages

The Zebra Puzzle

According to an e-mail source, this puzzle originated with the German Institute of Logical Thinking, Berlin, 1981. [It's possible.]

  1. There are five houses.
  2. Each house has its own unique color.
  3. All house owners are of different nationalities.
  4. They all have different pets.
  5. They all drink different drinks.
  6. They all smoke different cigarettes.
  7. The English man lives in the red house.
  8. The Swede has a dog.
  9. The Dane drinks tea.
  10. The green house is on the left side of the white house.
  11. In the green house, they drink coffee.
  12. The man who smokes Pall Mall has birds.
  13. In the yellow house, they smoke Dunhill.
  14. In the middle house, they drink milk.
  15. The Norwegian lives in the first house.
  16. The man who smokes Blend lives in the house next to the house with cats.
  17. In the house next to the house with the horse, they smoke Dunhill.
  18. The man who smokes Blue Master drinks beer.
  19. The German smokes Prince.
  20. The Norwegian lives next to the blue house.
  21. They drink water in the house that is next to the house where they smoke Blend.
  22. Who owns the zebra?

Try solving this puzzle on your own.

Now imagine writing a computer program to solve it.

Which was more difficult?

This is an example of a completely specified solution which doesn't appear to be specified at all. The constraints are such that the answer is unique, but they are stated in such a way that it is not at all obvious (to this human, at least) what the answer is.

In Prolog, we could express each of these specifications, then let Prolog's search strategy (database search engine, automated theorem prover) search for a solution. We don't have to worry about how to solve the problem -- we only have the specify what is to be solved.


Part of the problem is encoded in the data structure used to represent it: a list consisting of five sublists, each representing the five attributes of a house and its resident (Color, Nationality, Pet, Drink, Smoke), where the order of the sublists corresponds to the order of the houses from left to right:

    S = [[C1,N1,P1,D1,S1],

Each fact is then encoded by using a constant symbol to directly represent the attributes of some house/resident (or pair of houses/residents). Sometimes we use the predefined member predicate to assert that the pattern given must correspond to one of the sublists of the solution list; other times we use next_to (defined in the sample solution) to assert a relationship between two houses. The uniqueness conditions (two through six above) turn out not to be necessary, since the puzzle is so constrained, but one wouldn't know that in advance.

Alternative Solution

This solution uses five separate lists, one each for colors, nationalities, pets, drinks, and smokes. It uses predicates to define the relationships between the houses: in the same house, or in adjacent houses (either ordered from left to right or unordered).

A Poor (slow) Solution

This solution indicates how not to solve a puzzle like this in Prolog. It uses a generate-and-test strategy, by which all the possible permutations of lists of colors, nationalities, pets, drinks, and smokes are generated, and these are then tested against the constraints of the puzzle to see if they are consistent with them. This is a very slow way to solve the problem (unless you cheat by putting one or more of the lists into an order that makes the solution easy to find). Study the first and second solutions to see how they avoid the exponential cost of this slow solution.

Copyright © 2002, 2004 Jonathan Mohr