1use std::fmt::Debug;
2
3use arrayvec::ArrayVec;
4
5use crate::code::{Code, Set, Order};
6
7#[must_use]
9pub fn get_verifier_by_number(number: usize) -> Verifier {
10 let verifiers: [Verifier; 48] = [
11 Verifier::from_description_and_options(
13 "the △ number compared to 1",
14 &[
15 VerifierOption::from_description_and_closure("△ = 1", |code| {
16 code.triangle() == 1
17 }),
18 VerifierOption::from_description_and_closure("△ > 1", |code| code.triangle() > 1),
19 ],
20 ),
21 Verifier::from_description_and_options(
23 "the △ number compared to 3",
24 &[
25 VerifierOption::from_description_and_closure("△ < 3", |code| code.triangle() < 3),
26 VerifierOption::from_description_and_closure("△ = 3", |code| {
27 code.triangle() == 3
28 }),
29 VerifierOption::from_description_and_closure("△ > 3", |code| code.triangle() > 3),
30 ],
31 ),
32 Verifier::from_description_and_options(
34 "the □ number compared to 3",
35 &[
36 VerifierOption::from_description_and_closure("□ < 3", |code| code.square() < 3),
37 VerifierOption::from_description_and_closure("□ = 3", |code| code.square() == 3),
38 VerifierOption::from_description_and_closure("□ > 3", |code| code.square() > 3),
39 ],
40 ),
41 Verifier::from_description_and_options(
43 "the □ number compared to 4",
44 &[
45 VerifierOption::from_description_and_closure("□ < 4", |code| code.square() < 4),
46 VerifierOption::from_description_and_closure("□ = 4", |code| code.square() == 4),
47 VerifierOption::from_description_and_closure("□ > 4", |code| code.square() > 4),
48 ],
49 ),
50 Verifier::from_description_and_options(
52 "if △ is even or odd",
53 &[
54 VerifierOption::from_description_and_closure("△ is even", |code| {
55 code.triangle() % 2 == 0
56 }),
57 VerifierOption::from_description_and_closure("△ is odd", |code| {
58 code.triangle() % 2 == 1
59 }),
60 ],
61 ),
62 Verifier::from_description_and_options(
64 "if □ is even or odd",
65 &[
66 VerifierOption::from_description_and_closure("□ is even", |code| {
67 code.square() % 2 == 0
68 }),
69 VerifierOption::from_description_and_closure("□ is odd", |code| {
70 code.square() % 2 == 1
71 }),
72 ],
73 ),
74 Verifier::from_description_and_options(
76 "if ○ is even or odd",
77 &[
78 VerifierOption::from_description_and_closure("○ is even", |code| {
79 code.circle() % 2 == 0
80 }),
81 VerifierOption::from_description_and_closure("○ is odd", |code| {
82 code.circle() % 2 == 1
83 }),
84 ],
85 ),
86 Verifier::from_description_and_options(
88 "the number of 1s in the code",
89 &[
90 VerifierOption::from_description_and_closure("zero 1s", |code| {
91 code.count_digit(1) == 0
92 }),
93 VerifierOption::from_description_and_closure("one 1", |code| {
94 code.count_digit(1) == 1
95 }),
96 VerifierOption::from_description_and_closure("two 1s", |code| {
97 code.count_digit(1) == 2
98 }),
99 VerifierOption::from_description_and_closure("three 1s", |code| {
100 code.count_digit(1) == 3
101 }),
102 ],
103 ),
104 Verifier::from_description_and_options(
106 "the number of 3s in the code",
107 &[
108 VerifierOption::from_description_and_closure("zero 3s", |code| {
109 code.count_digit(3) == 0
110 }),
111 VerifierOption::from_description_and_closure("one 3", |code| {
112 code.count_digit(3) == 1
113 }),
114 VerifierOption::from_description_and_closure("two 3s", |code| {
115 code.count_digit(3) == 2
116 }),
117 VerifierOption::from_description_and_closure("three 3s", |code| {
118 code.count_digit(3) == 3
119 }),
120 ],
121 ),
122 Verifier::from_description_and_options(
124 "the number of 4s in the code",
125 &[
126 VerifierOption::from_description_and_closure("zero 4s", |code| {
127 code.count_digit(4) == 0
128 }),
129 VerifierOption::from_description_and_closure("one 4", |code| {
130 code.count_digit(4) == 1
131 }),
132 VerifierOption::from_description_and_closure("two 4s", |code| {
133 code.count_digit(4) == 2
134 }),
135 VerifierOption::from_description_and_closure("three 4s", |code| {
136 code.count_digit(4) == 3
137 }),
138 ],
139 ),
140 Verifier::from_description_and_options(
142 "the △ number compared to the □ number",
143 &[
144 VerifierOption::from_description_and_closure("△ < □", |code| {
145 code.triangle() < code.square()
146 }),
147 VerifierOption::from_description_and_closure("△ = □", |code| {
148 code.triangle() == code.square()
149 }),
150 VerifierOption::from_description_and_closure("△ > □", |code| {
151 code.triangle() > code.square()
152 }),
153 ],
154 ),
155 Verifier::from_description_and_options(
157 "the △ number compared to the ○ number",
158 &[
159 VerifierOption::from_description_and_closure("△ < ○", |code| {
160 code.triangle() < code.circle()
161 }),
162 VerifierOption::from_description_and_closure("△ = ○", |code| {
163 code.triangle() == code.circle()
164 }),
165 VerifierOption::from_description_and_closure("△ > ○", |code| {
166 code.triangle() > code.circle()
167 }),
168 ],
169 ),
170 Verifier::from_description_and_options(
172 "the □ number compared to the ○ number",
173 &[
174 VerifierOption::from_description_and_closure("□ < ○", |code| {
175 code.square() < code.circle()
176 }),
177 VerifierOption::from_description_and_closure("□ = ○", |code| {
178 code.square() == code.circle()
179 }),
180 VerifierOption::from_description_and_closure("□ > ○", |code| {
181 code.square() > code.circle()
182 }),
183 ],
184 ),
185 Verifier::from_description_and_options(
187 "which colour's number is smaller than either of the others",
188 &[
189 VerifierOption::from_description_and_closure("△ < □, ○", |code| {
190 code.triangle() < code.square() && code.triangle() < code.circle()
191 }),
192 VerifierOption::from_description_and_closure("□ < △, ○", |code| {
193 code.square() < code.triangle() && code.square() < code.circle()
194 }),
195 VerifierOption::from_description_and_closure("○ < □, △", |code| {
196 code.circle() < code.square() && code.circle() < code.triangle()
197 }),
198 ],
199 ),
200 Verifier::from_description_and_options(
202 "which colour's number is larger than either of the others",
203 &[
204 VerifierOption::from_description_and_closure("△ > □, ○", |code| {
205 code.triangle() > code.square() && code.triangle() > code.circle()
206 }),
207 VerifierOption::from_description_and_closure("□ > △, ○", |code| {
208 code.square() > code.triangle() && code.square() > code.circle()
209 }),
210 VerifierOption::from_description_and_closure("○ > □, △", |code| {
211 code.circle() > code.square() && code.circle() > code.triangle()
212 }),
213 ],
214 ),
215 Verifier::from_description_and_options(
217 "the number of even numbers compared to the number of odd numbers",
218 &[
219 VerifierOption::from_description_and_closure("EVEN > ODD", |code| {
220 code.count_even() >= 2
221 }),
222 VerifierOption::from_description_and_closure("EVEN < ODD", |code| {
223 code.count_even() <= 1
224 }),
225 ],
226 ),
227 Verifier::from_description_and_options(
229 "how many even numbers there are in the code",
230 &[
231 VerifierOption::from_description_and_closure("zero even numbers", |code| {
232 code.count_even() == 0
233 }),
234 VerifierOption::from_description_and_closure("one even number", |code| {
235 code.count_even() == 1
236 }),
237 VerifierOption::from_description_and_closure("two even numbers", |code| {
238 code.count_even() == 2
239 }),
240 VerifierOption::from_description_and_closure("three even numbers", |code| {
241 code.count_even() == 3
242 }),
243 ],
244 ),
245 Verifier::from_description_and_options(
247 "if the sum of all the numbers is even or odd",
248 &[
249 VerifierOption::from_description_and_closure("△ + □ + ○ = EVEN", |code| {
250 (code.triangle() + code.square() + code.circle()) % 2 == 0
251 }),
252 VerifierOption::from_description_and_closure("△ + □ + ○ = ODD", |code| {
253 (code.triangle() + code.square() + code.circle()) % 2 == 1
254 }),
255 ],
256 ),
257 Verifier::from_description_and_options(
259 "the sum of △ and □ compared to 6",
260 &[
261 VerifierOption::from_description_and_closure("△ + □ < 6", |code| {
262 code.triangle() + code.square() < 6
263 }),
264 VerifierOption::from_description_and_closure("△ + □ = 6", |code| {
265 code.triangle() + code.square() == 6
266 }),
267 VerifierOption::from_description_and_closure("△ + □ > 6", |code| {
268 code.triangle() + code.square() > 6
269 }),
270 ],
271 ),
272 Verifier::from_description_and_options(
274 "if a number repeats itself in the code",
275 &[
276 VerifierOption::from_description_and_closure("a triple number", |code| {
277 code.repeating_numbers() == 2
278 }),
279 VerifierOption::from_description_and_closure("a double number", |code| {
280 code.repeating_numbers() == 1
281 }),
282 VerifierOption::from_description_and_closure("no repetition", |code| {
283 code.repeating_numbers() == 0
284 }),
285 ],
286 ),
287 Verifier::from_description_and_options(
289 "if there is a number present exactly twice",
290 &[
291 VerifierOption::from_description_and_closure("no pairs", |code| {
292 code.repeating_numbers() != 1
293 }),
294 VerifierOption::from_description_and_closure("a pair", |code| {
295 code.repeating_numbers() == 1
296 }),
297 ],
298 ),
299 Verifier::from_description_and_options(
301 "if the 3 numbers in the code are in ascending order, descending order, or no order",
302 &[
303 VerifierOption::from_description_and_closure("ascending order", |code| {
304 code.is_ascending_or_descending() == Order::Ascending
305 }),
306 VerifierOption::from_description_and_closure("descending order", |code| {
307 code.is_ascending_or_descending() == Order::Descending
308 }),
309 VerifierOption::from_description_and_closure("no order", |code| {
310 code.is_ascending_or_descending() == Order::NoOrder
311 }),
312 ],
313 ),
314 Verifier::from_description_and_options(
316 "the sum of all numbers compared to 6",
317 &[
318 VerifierOption::from_description_and_closure("△ + □ + ○ < 6", |code| {
319 code.triangle() + code.square() + code.circle() < 6
320 }),
321 VerifierOption::from_description_and_closure("△ + □ + ○ = 6", |code| {
322 code.triangle() + code.square() + code.circle() == 6
323 }),
324 VerifierOption::from_description_and_closure("△ + □ + ○ > 6", |code| {
325 code.triangle() + code.square() + code.circle() > 6
326 }),
327 ],
328 ),
329 Verifier::from_description_and_options(
331 "if there is a sequence of ascending numbers",
332 &[
333 VerifierOption::from_description_and_closure(
334 "3 numbers in ascending order",
335 |code| code.sequence_ascending() == 3,
336 ),
337 VerifierOption::from_description_and_closure(
338 "2 numbers in ascending order",
339 |code| code.sequence_ascending() == 2,
340 ),
341 VerifierOption::from_description_and_closure(
342 "no numbers in ascending order",
343 |code| code.sequence_ascending() == 0,
344 ),
345 ],
346 ),
347 Verifier::from_description_and_options(
349 "if there is a sequence of ascending or descending numbers",
350 &[
351 VerifierOption::from_description_and_closure(
352 "no sequence of numbers in ascending or descending order",
353 |code| code.sequence_ascending_or_descending() == 0,
354 ),
355 VerifierOption::from_description_and_closure(
356 "2 numbers in ascending or descending order",
357 |code| code.sequence_ascending_or_descending() == 2,
358 ),
359 VerifierOption::from_description_and_closure(
360 "3 numbers in ascending or descending order",
361 |code| code.sequence_ascending_or_descending() == 3,
362 ),
363 ],
364 ),
365 Verifier::from_description_and_options(
367 "that a specific colour is less than 3",
368 &[
369 VerifierOption::from_description_and_closure("△ < 3", |code| code.triangle() < 3),
370 VerifierOption::from_description_and_closure("□ < 3", |code| code.square() < 3),
371 VerifierOption::from_description_and_closure("○ < 3", |code| code.circle() < 3),
372 ],
373 ),
374 Verifier::from_description_and_options(
376 "that a specific colour is less than 4",
377 &[
378 VerifierOption::from_description_and_closure("△ < 4", |code| code.triangle() < 4),
379 VerifierOption::from_description_and_closure("□ < 4", |code| code.square() < 4),
380 VerifierOption::from_description_and_closure("○ < 4", |code| code.circle() < 4),
381 ],
382 ),
383 Verifier::from_description_and_options(
385 "that a specific colour is equal to 1",
386 &[
387 VerifierOption::from_description_and_closure("△ = 1", |code| {
388 code.triangle() == 1
389 }),
390 VerifierOption::from_description_and_closure("□ = 1", |code| code.square() == 1),
391 VerifierOption::from_description_and_closure("○ = 1", |code| code.circle() == 1),
392 ],
393 ),
394 Verifier::from_description_and_options(
396 "that a specific colour is equal to 3",
397 &[
398 VerifierOption::from_description_and_closure("△ = 3", |code| {
399 code.triangle() == 3
400 }),
401 VerifierOption::from_description_and_closure("□ = 3", |code| code.square() == 3),
402 VerifierOption::from_description_and_closure("○ = 3", |code| code.circle() == 3),
403 ],
404 ),
405 Verifier::from_description_and_options(
407 "that a specific colour is equal to 4",
408 &[
409 VerifierOption::from_description_and_closure("△ = 4", |code| {
410 code.triangle() == 4
411 }),
412 VerifierOption::from_description_and_closure("□ = 4", |code| code.square() == 4),
413 VerifierOption::from_description_and_closure("○ = 4", |code| code.circle() == 4),
414 ],
415 ),
416 Verifier::from_description_and_options(
418 "that a specific colour is greater than 1",
419 &[
420 VerifierOption::from_description_and_closure("△ > 1", |code| code.triangle() > 1),
421 VerifierOption::from_description_and_closure("□ > 1", |code| code.square() > 1),
422 VerifierOption::from_description_and_closure("○ > 1", |code| code.circle() > 1),
423 ],
424 ),
425 Verifier::from_description_and_options(
427 "that a specific colour is greater than 3",
428 &[
429 VerifierOption::from_description_and_closure("△ > 3", |code| code.triangle() > 3),
430 VerifierOption::from_description_and_closure("□ > 3", |code| code.square() > 3),
431 VerifierOption::from_description_and_closure("○ > 3", |code| code.circle() > 3),
432 ],
433 ),
434 Verifier::from_description_and_options(
436 "that a specific colour is even or odd",
437 &[
438 VerifierOption::from_description_and_closure("△ is even", |code| {
439 code.triangle() % 2 == 0
440 }),
441 VerifierOption::from_description_and_closure("△ is odd", |code| {
442 code.triangle() % 2 == 1
443 }),
444 VerifierOption::from_description_and_closure("□ is even", |code| {
445 code.square() % 2 == 0
446 }),
447 VerifierOption::from_description_and_closure("□ is odd", |code| {
448 code.square() % 2 == 1
449 }),
450 VerifierOption::from_description_and_closure("○ is even", |code| {
451 code.circle() % 2 == 0
452 }),
453 VerifierOption::from_description_and_closure("○ is odd", |code| {
454 code.circle() % 2 == 1
455 }),
456 ],
457 ),
458 Verifier::from_description_and_options(
460 "which colour has the smallest number (or is tied for the smallest number)",
461 &[
462 VerifierOption::from_description_and_closure("△ <= □, ○", |code| {
463 code.triangle() <= code.square() && code.triangle() <= code.circle()
464 }),
465 VerifierOption::from_description_and_closure("□ <= △, ○", |code| {
466 code.square() <= code.triangle() && code.square() <= code.circle()
467 }),
468 VerifierOption::from_description_and_closure("○ <= □, △", |code| {
469 code.circle() <= code.square() && code.circle() <= code.triangle()
470 }),
471 ],
472 ),
473 Verifier::from_description_and_options(
475 "which colour has the largest number (or is tied for the largest number)",
476 &[
477 VerifierOption::from_description_and_closure("△ >= □, ○", |code| {
478 code.triangle() >= code.square() && code.triangle() >= code.circle()
479 }),
480 VerifierOption::from_description_and_closure("□ >= △, ○", |code| {
481 code.square() >= code.triangle() && code.square() >= code.circle()
482 }),
483 VerifierOption::from_description_and_closure("○ >= □, △", |code| {
484 code.circle() >= code.square() && code.circle() >= code.triangle()
485 }),
486 ],
487 ),
488 Verifier::from_description_and_options(
490 "the sum of all the numbers is a multiple of 3 or 4 or 5",
491 &[
492 VerifierOption::from_description_and_closure("△ + □ + ○ = 3x", |code| {
493 code.digit_sum() % 3 == 0
494 }),
495 VerifierOption::from_description_and_closure("△ + □ + ○ = 4x", |code| {
496 code.digit_sum() % 4 == 0
497 }),
498 VerifierOption::from_description_and_closure("△ + □ + ○ = 5x", |code| {
499 code.digit_sum() % 5 == 0
500 }),
501 ],
502 ),
503 Verifier::from_description_and_options(
505 "the sum of 2 specific colours is equal to 4",
506 &[
507 VerifierOption::from_description_and_closure("△ + □ = 4", |code| {
508 code.triangle() + code.square() == 4
509 }),
510 VerifierOption::from_description_and_closure("△ + ○ = 4", |code| {
511 code.triangle() + code.circle() == 4
512 }),
513 VerifierOption::from_description_and_closure("□ + ○ = 4", |code| {
514 code.square() + code.circle() == 4
515 }),
516 ],
517 ),
518 Verifier::from_description_and_options(
520 "the sum of 2 specific colours is equal to 6",
521 &[
522 VerifierOption::from_description_and_closure("△ + □ = 6", |code| {
523 code.triangle() + code.square() == 6
524 }),
525 VerifierOption::from_description_and_closure("△ + ○ = 6", |code| {
526 code.triangle() + code.circle() == 6
527 }),
528 VerifierOption::from_description_and_closure("□ + ○ = 6", |code| {
529 code.square() + code.circle() == 6
530 }),
531 ],
532 ),
533 Verifier::from_description_and_options(
535 "the number of one specific colour compared to 1",
536 &[
537 VerifierOption::from_description_and_closure("△ = 1", |code| {
538 code.triangle() == 1
539 }),
540 VerifierOption::from_description_and_closure("△ > 1", |code| code.triangle() > 1),
541 VerifierOption::from_description_and_closure("□ = 1", |code| code.square() == 1),
542 VerifierOption::from_description_and_closure("□ > 1", |code| code.square() > 1),
543 VerifierOption::from_description_and_closure("○ = 1", |code| code.circle() == 1),
544 VerifierOption::from_description_and_closure("○ > 1", |code| code.circle() > 1),
545 ],
546 ),
547 Verifier::from_description_and_options(
549 "the number of one specific colour compared to 3",
550 &[
551 VerifierOption::from_description_and_closure("△ < 3", |code| code.triangle() < 3),
552 VerifierOption::from_description_and_closure("△ = 3", |code| {
553 code.triangle() == 3
554 }),
555 VerifierOption::from_description_and_closure("△ > 3", |code| code.triangle() > 3),
556 VerifierOption::from_description_and_closure("□ < 3", |code| code.square() < 3),
557 VerifierOption::from_description_and_closure("□ = 3", |code| code.square() == 3),
558 VerifierOption::from_description_and_closure("□ > 3", |code| code.square() > 3),
559 VerifierOption::from_description_and_closure("○ < 3", |code| code.circle() < 3),
560 VerifierOption::from_description_and_closure("○ = 3", |code| code.circle() == 3),
561 VerifierOption::from_description_and_closure("○ > 3", |code| code.circle() > 3),
562 ],
563 ),
564 Verifier::from_description_and_options(
566 "the number of one specific colour compared to 4",
567 &[
568 VerifierOption::from_description_and_closure("△ < 4", |code| code.triangle() < 4),
569 VerifierOption::from_description_and_closure("△ = 4", |code| {
570 code.triangle() == 4
571 }),
572 VerifierOption::from_description_and_closure("△ > 4", |code| code.triangle() > 4),
573 VerifierOption::from_description_and_closure("□ < 4", |code| code.square() < 4),
574 VerifierOption::from_description_and_closure("□ = 4", |code| code.square() == 4),
575 VerifierOption::from_description_and_closure("□ > 4", |code| code.square() > 4),
576 VerifierOption::from_description_and_closure("○ < 4", |code| code.circle() < 4),
577 VerifierOption::from_description_and_closure("○ = 4", |code| code.circle() == 4),
578 VerifierOption::from_description_and_closure("○ > 4", |code| code.circle() > 4),
579 ],
580 ),
581 Verifier::from_description_and_options(
583 "which colour is the smallest or the largest",
584 &[
585 VerifierOption::from_description_and_closure("△ < ○, □", |code| {
586 code.triangle() < code.circle() && code.triangle() < code.square()
587 }),
588 VerifierOption::from_description_and_closure("△ > ○, □", |code| {
589 code.triangle() > code.circle() && code.triangle() > code.square()
590 }),
591 VerifierOption::from_description_and_closure("□ < △, ○", |code| {
592 code.square() < code.triangle() && code.square() < code.circle()
593 }),
594 VerifierOption::from_description_and_closure("□ > △, ○", |code| {
595 code.square() > code.triangle() && code.square() > code.circle()
596 }),
597 VerifierOption::from_description_and_closure("○ < □, △", |code| {
598 code.circle() < code.square() && code.circle() < code.triangle()
599 }),
600 VerifierOption::from_description_and_closure("○ > □, △", |code| {
601 code.circle() > code.square() && code.circle() > code.triangle()
602 }),
603 ],
604 ),
605 Verifier::from_description_and_options(
607 "the △ number compared to the number of another specific colour",
608 &[
609 VerifierOption::from_description_and_closure("△ < □", |code| {
610 code.triangle() < code.square()
611 }),
612 VerifierOption::from_description_and_closure("△ < ○", |code| {
613 code.triangle() < code.circle()
614 }),
615 VerifierOption::from_description_and_closure("△ = □", |code| {
616 code.triangle() == code.square()
617 }),
618 VerifierOption::from_description_and_closure("△ = ○", |code| {
619 code.triangle() == code.circle()
620 }),
621 VerifierOption::from_description_and_closure("△ > □", |code| {
622 code.triangle() > code.square()
623 }),
624 VerifierOption::from_description_and_closure("△ > ○", |code| {
625 code.triangle() > code.circle()
626 }),
627 ],
628 ),
629 Verifier::from_description_and_options(
631 "the □ number compared to the number of another specific colour",
632 &[
633 VerifierOption::from_description_and_closure("□ < △", |code| {
634 code.square() < code.triangle()
635 }),
636 VerifierOption::from_description_and_closure("□ < ○", |code| {
637 code.square() < code.circle()
638 }),
639 VerifierOption::from_description_and_closure("□ = △", |code| {
640 code.square() == code.triangle()
641 }),
642 VerifierOption::from_description_and_closure("□ = ○", |code| {
643 code.square() == code.circle()
644 }),
645 VerifierOption::from_description_and_closure("□ > △", |code| {
646 code.square() > code.triangle()
647 }),
648 VerifierOption::from_description_and_closure("□ > ○", |code| {
649 code.square() > code.circle()
650 }),
651 ],
652 ),
653 Verifier::from_description_and_options(
655 "how many 1s OR how many 3s there are in the code",
656 &[
657 VerifierOption::from_description_and_closure("zero 1s", |code| {
658 code.count_digit(1) == 0
659 }),
660 VerifierOption::from_description_and_closure("one 1s", |code| {
661 code.count_digit(1) == 1
662 }),
663 VerifierOption::from_description_and_closure("two 1s", |code| {
664 code.count_digit(1) == 2
665 }),
666 VerifierOption::from_description_and_closure("zero 3s", |code| {
667 code.count_digit(3) == 0
668 }),
669 VerifierOption::from_description_and_closure("one 3s", |code| {
670 code.count_digit(3) == 1
671 }),
672 VerifierOption::from_description_and_closure("two 3s", |code| {
673 code.count_digit(3) == 2
674 }),
675 ],
676 ),
677 Verifier::from_description_and_options(
679 "how many 3s OR how many 4s there are in the code",
680 &[
681 VerifierOption::from_description_and_closure("zero 3s", |code| {
682 code.count_digit(3) == 0
683 }),
684 VerifierOption::from_description_and_closure("one 3", |code| {
685 code.count_digit(3) == 1
686 }),
687 VerifierOption::from_description_and_closure("two 3s", |code| {
688 code.count_digit(3) == 2
689 }),
690 VerifierOption::from_description_and_closure("zero 4s", |code| {
691 code.count_digit(4) == 0
692 }),
693 VerifierOption::from_description_and_closure("one 4", |code| {
694 code.count_digit(4) == 1
695 }),
696 VerifierOption::from_description_and_closure("two 4s", |code| {
697 code.count_digit(4) == 2
698 }),
699 ],
700 ),
701 Verifier::from_description_and_options(
703 "how many 1s OR how many 4s there are in the code",
704 &[
705 VerifierOption::from_description_and_closure("zero 1s", |code| {
706 code.count_digit(1) == 0
707 }),
708 VerifierOption::from_description_and_closure("one 1", |code| {
709 code.count_digit(1) == 1
710 }),
711 VerifierOption::from_description_and_closure("two 1s", |code| {
712 code.count_digit(1) == 2
713 }),
714 VerifierOption::from_description_and_closure("zero 4s", |code| {
715 code.count_digit(4) == 0
716 }),
717 VerifierOption::from_description_and_closure("one 4", |code| {
718 code.count_digit(4) == 1
719 }),
720 VerifierOption::from_description_and_closure("two 4s", |code| {
721 code.count_digit(4) == 2
722 }),
723 ],
724 ),
725 Verifier::from_description_and_options(
727 "one specific colour compared to another specific colour",
728 &[
729 VerifierOption::from_description_and_closure("△ < □", |code| {
730 code.triangle() < code.square()
731 }),
732 VerifierOption::from_description_and_closure("△ = □", |code| {
733 code.triangle() == code.square()
734 }),
735 VerifierOption::from_description_and_closure("△ > □", |code| {
736 code.triangle() > code.square()
737 }),
738 VerifierOption::from_description_and_closure("△ < ○", |code| {
739 code.triangle() < code.circle()
740 }),
741 VerifierOption::from_description_and_closure("△ = ○", |code| {
742 code.triangle() == code.circle()
743 }),
744 VerifierOption::from_description_and_closure("△ > ○", |code| {
745 code.triangle() > code.circle()
746 }),
747 VerifierOption::from_description_and_closure("□ < ○", |code| {
748 code.square() < code.circle()
749 }),
750 VerifierOption::from_description_and_closure("□ = ○", |code| {
751 code.square() == code.circle()
752 }),
753 VerifierOption::from_description_and_closure("□ > ○", |code| {
754 code.square() > code.circle()
755 }),
756 ],
757 ),
758 ];
759 verifiers[number - 1].clone()
760}
761
762const MAX_VERIFIER_OPTIONS: usize = 9;
763
764#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
765pub struct VerifierOption {
766 pub(crate) description: &'static str,
767 code_set: Set,
768}
769
770impl VerifierOption {
771 #[must_use]
772 pub fn code_set(&self) -> Set {
773 self.code_set
774 }
775
776 pub fn from_description_and_closure(
777 description: &'static str,
778 checker: fn(Code) -> bool,
779 ) -> VerifierOption {
780 VerifierOption {
781 description,
782 code_set: Set::from_closure(checker),
783 }
784 }
785}
786
787pub(crate) trait Intersection {
788 type To;
789 fn intersect(self) -> Self::To;
790}
791
792impl<T: Iterator<Item = Set>> Intersection for T {
793 type To = Set;
794 fn intersect(self) -> Self::To {
795 self.fold(Set::all(), |still_possible_codes, new_code_set| {
796 still_possible_codes.intersected_with(new_code_set)
797 })
798 }
799}
800
801#[derive(Clone, Eq, PartialEq, Hash)]
802pub struct Verifier {
803 description: &'static str,
804 options: ArrayVec<VerifierOption, MAX_VERIFIER_OPTIONS>,
805}
806
807impl Debug for Verifier {
808 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
809 writeln!(f, "{}", self.description)?;
810 for option in self.options.iter() {
811 writeln!(f, "- {}", option.description)?;
812 }
813 Ok(())
814 }
815}
816
817impl Verifier {
818 #[must_use]
819 pub fn description(&self) -> &'static str {
820 self.description
821 }
822
823 #[must_use]
824 pub fn number_of_options(&self) -> usize {
825 self.options.len()
826 }
827
828 #[must_use]
829 pub fn from_description_and_options(
830 description: &'static str,
831 options: &[VerifierOption],
832 ) -> Self {
833 Verifier {
834 description,
835 options: options.iter().copied().collect(),
836 }
837 }
838
839 #[must_use]
840 pub fn option(&self, choice: u8) -> &VerifierOption {
841 &self.options[choice as usize]
842 }
843
844 pub fn options(&self) -> impl Iterator<Item = &VerifierOption> + '_ {
845 self.options.iter()
846 }
847}