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