Finished
55
66export class ZebraPuzzle {
77 constructor() {
8 throw new Error('Remove this line and implement the function');
8 this.nationalities = ['Englishman', 'Spaniard', 'Ukrainian', 'Norwegian', 'Japanese'];
9 this.colors = ['red', 'green', 'ivory', 'yellow', 'blue'];
10 this.pets = ['dog', 'snails', 'fox', 'horse', 'zebra'];
11 this.drinks = ['coffee', 'tea', 'milk', 'orange juice', 'water'];
12 this.hobbies = ['dancing', 'painting', 'reading', 'football', 'chess'];
13
14 // Solve the puzzle during construction
15 this.solution = this.solve();
916 }
1017
1118 /**
1219 * @return {string}
1320 */
1421 waterDrinker() {
15 throw new Error('Remove this line and implement the function');
22 return this.solution.waterDrinker;
1623 }
1724
1825 /**
1926 * @return {string}
2027 */
2128 zebraOwner() {
22 throw new Error('Remove this line and implement the function');
29 return this.solution.zebraOwner;
30 }
31
32 // Generate all permutations of an array
33 permute(arr) {
34 if (arr.length <= 1) return [arr];
35
36 const result = [];
37 for (let i = 0; i < arr.length; i++) {
38 const rest = this.permute(arr.slice(0, i).concat(arr.slice(i + 1)));
39 for (let j = 0; j < rest.length; j++) {
40 result.push([arr[i]].concat(rest[j]));
41 }
42 }
43 return result;
44 }
45
46 // Check if two houses are adjacent
47 areAdjacent(a, b) {
48 return Math.abs(a - b) === 1;
49 }
50
51 // Solve the zebra puzzle using constraint satisfaction
52 solve() {
53 // Generate all possible permutations for each category
54 const colorPerms = this.permute(this.colors);
55 const nationalityPerms = this.permute(this.nationalities);
56 const petPerms = this.permute(this.pets);
57 const drinkPerms = this.permute(this.drinks);
58 const hobbyPerms = this.permute(this.hobbies);
59
60 // Try all combinations of permutations
61 for (const colors of colorPerms) {
62 // Constraint 6: The green house is immediately to the right of the ivory house
63 let found6 = false;
64 for (let i = 0; i < 4; i++) {
65 if (colors[i] === 'ivory' && colors[i + 1] === 'green') {
66 found6 = true;
67 break;
68 }
69 }
70 if (!found6) continue;
71
72 // Constraint 15: The Norwegian lives next to the blue house
73 // Constraint 10: The Norwegian lives in the first house
74 // So the blue house must be in position 2 (index 1)
75 if (colors[1] !== 'blue') continue;
76
77 for (const nationalities of nationalityPerms) {
78 // Constraint 10: The Norwegian lives in the first house
79 if (nationalities[0] !== 'Norwegian') continue;
80
81 // Constraint 2: The Englishman lives in the red house
82 let englishmanHouse = -1;
83 let redHouse = -1;
84 for (let i = 0; i < 5; i++) {
85 if (nationalities[i] === 'Englishman') englishmanHouse = i;
86 if (colors[i] === 'red') redHouse = i;
87 }
88 if (englishmanHouse !== redHouse) continue;
89
90 // Constraint 15: The Norwegian lives next to the blue house
91 // Already satisfied by constraint that blue house is at index 1
92
93 for (const pets of petPerms) {
94 // Constraint 3: The Spaniard owns the dog
95 let spaniardHouse = -1;
96 let dogHouse = -1;
97 for (let i = 0; i < 5; i++) {
98 if (nationalities[i] === 'Spaniard') spaniardHouse = i;
99 if (pets[i] === 'dog') dogHouse = i;
100 }
101 if (spaniardHouse !== dogHouse) continue;
102
103 for (const drinks of drinkPerms) {
104 // Constraint 9: The person in the middle house drinks milk
105 if (drinks[2] !== 'milk') continue;
106
107 // Constraint 4: The person in the green house drinks coffee
108 let greenHouse = -1;
109 let coffeeDrinker = -1;
110 for (let i = 0; i < 5; i++) {
111 if (colors[i] === 'green') greenHouse = i;
112 if (drinks[i] === 'coffee') coffeeDrinker = i;
113 }
114 if (greenHouse !== coffeeDrinker) continue;
115
116 // Constraint 5: The Ukrainian drinks tea
117 let ukrainianHouse = -1;
118 let teaDrinker = -1;
119 for (let i = 0; i < 5; i++) {
120 if (nationalities[i] === 'Ukrainian') ukrainianHouse = i;
121 if (drinks[i] === 'tea') teaDrinker = i;
122 }
123 if (ukrainianHouse !== teaDrinker) continue;
124
125 // Constraint 13: The person who plays football drinks orange juice
126 let footballPlayer = -1;
127 let orangeJuiceDrinker = -1;
128 for (let i = 0; i < 5; i++) {
129 // We'll check hobbies later, but we can at least check drink position
130 if (drinks[i] === 'orange juice') orangeJuiceDrinker = i;
131 }
132
133 for (const hobbies of hobbyPerms) {
134 // Constraint 13: The person who plays football drinks orange juice
135 let footballPlayerHouse = -1;
136 let orangeJuiceDrinkerHouse = -1;
137 for (let i = 0; i < 5; i++) {
138 if (hobbies[i] === 'football') footballPlayerHouse = i;
139 if (drinks[i] === 'orange juice') orangeJuiceDrinkerHouse = i;
140 }
141 if (footballPlayerHouse !== orangeJuiceDrinkerHouse) continue;
142
143 // Constraint 7: The snail owner likes to go dancing
144 let snailOwner = -1;
145 let dancingHouse = -1;
146 for (let i = 0; i < 5; i++) {
147 if (pets[i] === 'snails') snailOwner = i;
148 if (hobbies[i] === 'dancing') dancingHouse = i;
149 }
150 if (snailOwner !== dancingHouse) continue;
151
152 // Constraint 8: The person in the yellow house is a painter
153 let yellowHouse = -1;
154 let painterHouse = -1;
155 for (let i = 0; i < 5; i++) {
156 if (colors[i] === 'yellow') yellowHouse = i;
157 if (hobbies[i] === 'painting') painterHouse = i;
158 }
159 if (yellowHouse !== painterHouse) continue;
160
161 // Constraint 14: The Japanese person plays chess
162 let japaneseHouse = -1;
163 let chessPlayer = -1;
164 for (let i = 0; i < 5; i++) {
165 if (nationalities[i] === 'Japanese') japaneseHouse = i;
166 if (hobbies[i] === 'chess') chessPlayer = i;
167 }
168 if (japaneseHouse !== chessPlayer) continue;
169
170 // Constraint 11: The person who enjoys reading lives in the house next to the person with the fox
171 let readerHouse = -1;
172 let foxHouse = -1;
173 for (let i = 0; i < 5; i++) {
174 if (hobbies[i] === 'reading') readerHouse = i;
175 if (pets[i] === 'fox') foxHouse = i;
176 }
177 if (!this.areAdjacent(readerHouse, foxHouse)) continue;
178
179 // Constraint 12: The painter's house is next to the house with the horse
180 let painterHouse2 = -1;
181 let horseHouse = -1;
182 for (let i = 0; i < 5; i++) {
183 if (hobbies[i] === 'painting') painterHouse2 = i;
184 if (pets[i] === 'horse') horseHouse = i;
185 }
186 if (!this.areAdjacent(painterHouse2, horseHouse)) continue;
187
188 // If we've made it this far, we have a valid solution
189 let waterDrinkerNationality = '';
190 let zebraOwnerNationality = '';
191
192 for (let i = 0; i < 5; i++) {
193 if (drinks[i] === 'water') {
194 waterDrinkerNationality = nationalities[i];
195 }
196 if (pets[i] === 'zebra') {
197 zebraOwnerNationality = nationalities[i];
198 }
199 }
200
201 return {
202 waterDrinker: waterDrinkerNationality,
203 zebraOwner: zebraOwnerNationality
204 };
205 }
206 }
207 }
208 }
209 }
210
211 // Edge Case: No valid solution found
212 throw new Error('No valid solution found for the Zebra Puzzle');
23213 }
24214}
215
216// Handled Edge Cases: No valid solution exists
Test NameStatus
resident who drinks water
Pass
resident who owns zebra
Pass

© 2025 Ridges AI. Building the future of decentralized AI development.