1+ #include < algorithm>
2+ #include < iostream>
3+ #include < map>
4+ #include < numeric>
5+ #include < vector>
6+
7+ #include " zebra_puzzle.h"
8+
9+ using namespace std ;
10+
11+ namespace zebra_puzzle {
12+
13+ enum Color { Red, Green, Ivory, Yellow, Blue };
14+ enum Nationality { Englishman, Spaniard, Ukrainian, Norwegian, Japanese };
15+ enum Pet { Dog, Snails, Fox, Horse, Zebra };
16+ enum Drink { Tea, Coffee, Milk, OrangeJuice, Water };
17+ enum Cigarette { OldGold, Kools, Chesterfields, LuckyStrike, Parliaments };
18+
19+ map<Nationality, string> nationalityStrings = {{Englishman, " Englishman" },
20+ {Spaniard, " Spaniard" },
21+ {Ukrainian, " Ukrainian" },
22+ {Norwegian, " Norwegian" },
23+ {Japanese, " Japanese" }};
24+
25+ struct House {
26+ Color color;
27+ Nationality nationality;
28+ Pet pet;
29+ Drink drink;
30+ Cigarette cigarette;
31+ };
32+
33+ vector<House> houses (5 );
34+
35+ bool check_constraints_cigarette_drink () {
36+ for (size_t i = 0 ; i < houses.size (); i++) {
37+ const auto & house = houses[i];
38+
39+ // Constraint 9: Milk is drunk in the middle house.
40+ if ((i == 2 ) && (house.drink != Milk)) {
41+ return false ;
42+ }
43+
44+ // Constraint 13: The Lucky Strike smoker drinks orange juice.
45+ if ((house.cigarette == LuckyStrike) && (house.drink != OrangeJuice)) {
46+ return false ;
47+ }
48+ }
49+ return true ;
50+ }
51+
52+ bool check_constraints_cigarette_drink_pet () {
53+ for (size_t i = 0 ; i < houses.size (); i++) {
54+ const auto & house = houses[i];
55+
56+ // Constraint 7: The Old Gold smoker owns snails.
57+ if ((house.pet == Snails) && (house.cigarette != OldGold)) {
58+ return false ;
59+ }
60+
61+ // Constraint 11: The man who smokes Chesterfields lives in the house
62+ // next to the man with the fox.
63+ if (((i > 0 ) && (house.pet == Fox) &&
64+ (houses[i - 1 ].cigarette != Chesterfields)) &&
65+ ((i < 4 ) && (house.pet == Fox) &&
66+ (houses[i + 1 ].cigarette != Chesterfields))) {
67+ return false ;
68+ }
69+
70+ if ((i == 0 ) && (house.pet == Fox) &&
71+ (houses[i + 1 ].cigarette != Chesterfields)) {
72+ return false ;
73+ }
74+
75+ if ((i == 4 ) && (house.pet == Fox) &&
76+ (houses[i - 1 ].cigarette != Chesterfields)) {
77+ return false ;
78+ }
79+
80+ // Constraint 12: Kools are smoked in a house next to the house where
81+ // the horse is kept.
82+ if (((i > 0 ) && (house.pet == Horse) &&
83+ (houses[i - 1 ].cigarette != Kools)) &&
84+ ((i < 4 ) && (house.pet == Horse) &&
85+ (houses[i + 1 ].cigarette != Kools))) {
86+ return false ;
87+ }
88+
89+ if ((i == 0 ) && (house.pet == Horse) &&
90+ (houses[i + 1 ].cigarette != Kools)) {
91+ return false ;
92+ }
93+
94+ if ((i == 4 ) && (house.pet == Horse) &&
95+ (houses[i - 1 ].cigarette != Kools)) {
96+ return false ;
97+ }
98+ }
99+ return true ;
100+ }
101+
102+ bool check_constraints_cigarette_drink_pet_nationality () {
103+ for (size_t i = 0 ; i < houses.size (); i++) {
104+ const auto & house = houses[i];
105+
106+ // Constraint 3: The Spaniard owns the dog.
107+ if ((house.nationality == Spaniard) && (house.pet != Dog)) {
108+ return false ;
109+ }
110+
111+ // Constraint 5: The Ukrainian drinks tea.
112+ if ((house.nationality == Ukrainian) && (house.drink != Tea)) {
113+ return false ;
114+ }
115+
116+ // Constraint 10: The Norwegian lives in the first house.
117+ if ((i == 0 ) && (house.nationality != Norwegian)) {
118+ return false ;
119+ }
120+
121+ // Constraint 14: The Japanese smokes Parliaments.
122+ if ((house.nationality == Japanese) &&
123+ (house.cigarette != Parliaments)) {
124+ return false ;
125+ }
126+ }
127+ return true ;
128+ }
129+
130+ bool check_constraints_cigarette_drink_pet_nationality_color () {
131+ for (size_t i = 0 ; i < houses.size (); i++) {
132+ const auto & house = houses[i];
133+
134+ // Constraint 2: The Englishman lives in the red house.
135+ if ((house.color == Red) && (house.nationality != Englishman)) {
136+ return false ;
137+ }
138+
139+ // Constraint 4: Coffee is drunk in the green house.
140+ if ((house.color == Green) && (house.drink != Coffee)) {
141+ return false ;
142+ }
143+
144+ // Constraint 6: The green house is immediately to the right of the
145+ // ivory house.
146+ if ((i > 0 ) && (house.color == Green) &&
147+ (houses[i - 1 ].color != Ivory)) {
148+ return false ;
149+ }
150+
151+ if ((i == 0 ) && (house.color == Green)) {
152+ return false ;
153+ }
154+
155+ // Constraint 8: Kools are smoked in the yellow house.
156+ if ((house.color == Yellow) && (house.cigarette != Kools)) {
157+ return false ;
158+ }
159+
160+ // Constraint 15: The Norwegian lives next to the blue house.
161+ if (((i > 0 ) && (house.nationality == Norwegian) &&
162+ (houses[i - 1 ].color != Blue)) &&
163+ ((i < 4 ) && (house.nationality == Norwegian) &&
164+ (houses[i + 1 ].color != Blue))) {
165+ return false ;
166+ }
167+
168+ if ((i == 0 ) && (house.nationality == Norwegian) &&
169+ (houses[i + 1 ].color != Blue)) {
170+ return false ;
171+ }
172+
173+ if ((i == 4 ) && (house.nationality == Norwegian) &&
174+ (houses[i - 1 ].color != Blue)) {
175+ return false ;
176+ }
177+ }
178+ return true ;
179+ }
180+
181+ void solve_with_permutation () {
182+ vector<Color> colors = {Red, Green, Ivory, Yellow, Blue};
183+ vector<Nationality> nationalities = {Englishman, Spaniard, Ukrainian,
184+ Norwegian, Japanese};
185+ vector<Pet> pets = {Dog, Snails, Fox, Horse, Zebra};
186+ vector<Drink> drinks = {Tea, Coffee, Milk, OrangeJuice, Water};
187+ vector<Cigarette> cigarettes = {OldGold, Kools, Chesterfields, LuckyStrike,
188+ Parliaments};
189+
190+ do {
191+ for (size_t i = 0 ; i < 5 ; i++) {
192+ houses[i].cigarette = cigarettes[i];
193+ }
194+
195+ do {
196+ for (size_t i = 0 ; i < 5 ; i++) {
197+ houses[i].drink = drinks[i];
198+ }
199+
200+ if (!check_constraints_cigarette_drink ()) {
201+ continue ;
202+ }
203+
204+ do {
205+ for (size_t i = 0 ; i < 5 ; i++) {
206+ houses[i].pet = pets[i];
207+ }
208+
209+ if (!check_constraints_cigarette_drink_pet ()) {
210+ continue ;
211+ }
212+
213+ do {
214+ for (size_t i = 0 ; i < 5 ; i++) {
215+ houses[i].nationality = nationalities[i];
216+ }
217+
218+ if (!check_constraints_cigarette_drink_pet_nationality ()) {
219+ continue ;
220+ }
221+
222+ do {
223+ for (size_t i = 0 ; i < 5 ; i++) {
224+ houses[i].color = colors[i];
225+ }
226+
227+ if (check_constraints_cigarette_drink_pet_nationality_color ()) {
228+ return ;
229+ }
230+
231+ } while (next_permutation (colors.begin (), colors.end ()));
232+
233+ } while (next_permutation (nationalities.begin (),
234+ nationalities.end ()));
235+
236+ } while (next_permutation (pets.begin (), pets.end ()));
237+
238+ } while (next_permutation (drinks.begin (), drinks.end ()));
239+
240+ } while (next_permutation (cigarettes.begin (), cigarettes.end ()));
241+ }
242+
243+ Solution solve () {
244+ solve_with_permutation ();
245+ Solution solution;
246+
247+ // find the house with the zebra
248+ for (size_t i = 0 ; i < houses.size (); i++) {
249+ if (houses[i].pet == Zebra) {
250+ solution.ownsZebra = nationalityStrings[houses[i].nationality ];
251+ break ;
252+ }
253+ }
254+
255+ // find the house with the water
256+ for (size_t i = 0 ; i < houses.size (); i++) {
257+ if (houses[i].drink == Water) {
258+ solution.drinksWater = nationalityStrings[houses[i].nationality ];
259+ break ;
260+ }
261+ }
262+
263+ return solution;
264+ }
265+
266+ } // namespace zebra_puzzle
0 commit comments