2021 solutions

master
Matthew Butterick 2 years ago
parent 4d5f19b410
commit af8752d29e

@ -0,0 +1,20 @@
#lang br
(require racket/file rackunit)
(define depths (map string->number (file->lines "01.rktd")))
(define (positive-deltas depths)
(filter positive?
(for/list ([d1 (in-list depths)]
[d2 (in-list (cdr depths))])
(- d2 d1))))
(check-equal? (length (positive-deltas depths)) 1167)
(define (trios depths)
(for/list ([d1 (in-list depths)]
[d2 (in-list (cdr depths))]
[d3 (in-list (cddr depths))])
(+ d1 d2 d3)))
(check-equal? (length (positive-deltas (trios depths))) 1130)

File diff suppressed because it is too large Load Diff

@ -0,0 +1,32 @@
#lang br
(require racket/file sugar/list rackunit)
(define instructions
(slice-at (for/list ([datum (in-port read (open-input-file "02.rktd"))])
datum) 2))
(define (solve matcher)
(for/fold ([pos 0]
[depth 0]
[aim 0]
#:result (* pos depth))
([i (in-list instructions)])
(matcher pos depth aim i)))
(define (solve-1)
(solve (λ (pos depth aim i)
(match i
[(list 'forward amt) (values (+ pos amt) depth aim)]
[(list 'down amt) (values pos (+ depth amt) aim)]
[(list 'up amt) (values pos (- depth amt) aim)]))))
(check-equal? (solve-1) 1488669)
(define (solve-2)
(solve (λ (pos depth aim i)
(match i
[(list 'forward amt) (values (+ pos amt) (+ depth (* aim amt)) aim)]
[(list 'down amt) (values pos depth (+ aim amt))]
[(list 'up amt) (values pos depth (- aim amt))]))))
(check-equal? (solve-2) 1176514794)

File diff suppressed because it is too large Load Diff

@ -0,0 +1,40 @@
#lang br
(require racket/file rackunit)
(define lines (map string->list (file->lines "03.rktd")))
(define (digit-columns lines) (apply map list lines))
(define (most-common-digit chars)
(define zeroes (count (λ (c) (char=? c #\0)) chars))
(define most-threshold (/ (length chars) 2))
(cond
[(= zeroes most-threshold) #f]
[(> zeroes most-threshold) #\0]
[else #\1]))
(define (least-common-digit chars)
(match (most-common-digit chars)
[#false #false]
[#\0 #\1]
[_ #\0]))
(define (chars->binary-number chars)
(string->number (list->string chars) 2))
(define gamma-rate (chars->binary-number (map most-common-digit (digit-columns lines))))
(define epsilon-rate (chars->binary-number (map least-common-digit (digit-columns lines))))
(check-equal? (* gamma-rate epsilon-rate) 4174964)
(define (find-digit proc default)
(for/fold ([lines lines]
#:result (chars->binary-number (car lines)))
([i (in-range (length (car lines)))]
#:break (= (length lines) 1))
(define target (or (proc (list-ref (digit-columns lines) i)) default))
(filter (λ (line) (char=? (list-ref line i) target)) lines)))
(define oxygen-rate (find-digit most-common-digit #\1))
(define co2-rate (find-digit least-common-digit #\0))
(check-equal? (* oxygen-rate co2-rate) 4474944)

File diff suppressed because it is too large Load Diff

@ -0,0 +1,43 @@
#lang br
(require racket/file sugar rackunit)
(define lines (file->lines "04.rktd"))
(define numbers-to-draw (map string->number (string-split (string-replace (car lines) "," " "))))
(define boards
(map list->vector (slice-at (map string->number (string-split (string-join (cdr lines)))) 25)))
(define winning-lines
(let ()
(define rows '((0 1 2 3 4) (5 6 7 8 9) (10 11 12 13 14) (15 16 17 18 19) (20 21 22 23 24)))
(define cols (apply map list rows))
(append rows cols)))
(define (board-wins board)
(for/or ([winning-line winning-lines])
(for/and ([idx winning-line])
(eq? (vector-ref board idx) #true))))
(define (run-game boards)
(for*/fold ([boards boards]
[winners null]
#:result (reverse winners))
([number numbers-to-draw]
#:break (empty? boards))
(for ([board boards])
(define pos-of-number (vector-member number board))
(when pos-of-number
(vector-set! board pos-of-number #true)))
(define-values (new-winners losers) (partition board-wins boards))
(values losers (append (for/list ([winner new-winners])
(cons number winner)) winners))))
(define (calc-score res)
(match res
[(cons last-number board) (* last-number (apply + (filter number? (vector->list board))))]))
(define results (run-game boards))
(check-equal? (calc-score (first results)) 64084)
(check-equal? (calc-score (last results)) 12833)

@ -0,0 +1,601 @@
27,14,70,7,85,66,65,57,68,23,33,78,4,84,25,18,43,71,76,61,34,82,93,74,26,15,83,64,2,35,19,97,32,47,6,51,99,20,77,75,56,73,80,86,55,36,13,95,52,63,79,72,9,10,16,8,69,11,50,54,81,22,45,1,12,88,44,17,62,0,96,94,31,90,39,92,37,40,5,98,24,38,46,21,30,49,41,87,91,60,48,29,59,89,3,42,58,53,67,28
31 23 52 26 8
27 89 37 80 46
97 19 63 34 79
13 59 45 12 73
42 25 22 6 39
27 71 24 3 0
79 42 32 72 62
99 52 11 92 33
38 22 16 44 39
35 26 76 49 58
39 19 82 53 57
52 98 69 77 23
1 40 18 66 83
34 85 28 48 16
15 93 38 96 27
74 50 88 84 99
34 2 11 25 17
57 4 19 83 1
59 77 42 36 33
73 22 23 37 55
98 91 56 84 78
45 21 24 83 40
46 58 8 67 4
33 97 55 7 86
2 68 64 27 69
68 29 14 49 26
4 21 87 71 32
58 5 17 46 93
45 96 8 83 2
78 91 9 20 42
49 81 19 48 37
38 23 45 82 92
93 99 67 66 42
40 74 25 56 16
21 47 26 75 61
53 66 72 30 34
55 82 77 6 92
60 56 8 22 88
5 71 49 29 74
28 2 32 84 73
52 31 24 68 41
48 82 19 29 65
51 91 97 39 80
3 55 43 40 38
20 89 53 45 75
29 74 19 89 18
32 88 93 46 63
91 4 94 64 5
57 54 49 36 40
97 81 39 77 1
7 57 94 84 39
92 3 28 15 75
88 45 65 81 63
86 4 89 37 71
8 13 66 42 85
60 66 35 47 98
96 27 40 51 39
3 64 25 28 74
58 17 97 59 29
95 31 18 44 37
3 31 97 85 71
79 82 22 61 98
87 14 17 66 75
36 89 88 83 63
44 8 81 25 48
73 84 28 90 94
25 19 44 10 23
8 59 17 9 93
20 77 97 64 6
98 82 27 70 91
18 51 16 99 2
58 22 89 13 19
39 66 91 8 32
49 24 85 94 42
45 70 10 86 4
23 81 66 13 34
25 80 97 5 42
79 35 2 78 9
0 6 91 94 45
21 90 76 50 56
50 92 2 96 75
85 82 80 97 31
61 35 55 27 56
74 42 9 29 90
86 15 88 47 1
18 20 54 92 62
45 22 32 61 75
1 38 50 81 42
82 4 21 77 65
27 51 56 39 48
36 10 62 28 70
94 99 34 54 6
15 1 41 13 12
92 52 2 63 82
90 64 29 69 32
23 77 33 90 17
45 78 5 67 28
57 73 89 81 21
49 64 37 15 14
7 59 4 43 16
81 92 25 28 90
93 72 43 94 26
24 9 13 74 10
21 2 36 32 51
87 97 55 86 71
82 71 99 17 90
69 95 65 55 10
9 92 39 62 78
59 13 61 24 44
8 31 58 0 57
17 83 55 99 27
79 4 33 76 7
81 43 44 49 72
2 48 97 20 77
47 60 35 16 63
93 95 94 1 98
61 57 84 55 22
85 40 65 46 59
21 15 63 77 7
13 99 49 3 96
8 21 14 45 41
65 63 82 62 28
91 44 22 79 96
20 75 86 3 26
74 11 42 59 36
5 52 43 92 99
46 63 10 45 81
13 66 21 32 89
25 28 96 40 88
27 18 31 73 34
3 26 43 32 36
68 87 67 65 99
73 61 20 90 7
21 52 2 82 10
58 49 56 16 80
97 25 93 63 32
87 14 5 22 76
89 92 91 3 51
0 24 95 69 20
96 11 10 1 55
95 86 44 75 70
59 76 45 2 99
1 34 71 81 41
87 14 33 84 96
8 38 9 82 68
27 71 70 75 76
25 87 2 79 96
20 88 50 37 32
48 94 63 86 22
15 6 34 78 59
30 89 51 31 77
74 10 86 71 84
29 54 58 44 5
11 90 26 50 63
64 62 20 40 46
37 9 46 23 31
68 21 25 36 90
17 33 6 50 30
11 89 20 47 60
26 59 34 62 77
84 52 40 97 7
88 30 42 58 94
64 10 2 90 83
44 35 77 91 47
14 74 9 78 53
86 14 0 39 24
87 69 58 8 73
88 74 27 40 51
63 54 55 93 61
16 66 15 21 48
43 70 9 81 42
36 54 99 34 95
98 19 90 25 44
69 56 18 77 49
58 16 67 75 57
36 44 14 98 23
31 5 83 46 3
45 21 41 11 60
33 81 88 92 65
13 51 48 59 71
12 5 70 87 32
42 18 90 73 88
68 29 76 38 55
67 62 15 77 34
39 27 51 54 19
87 8 92 93 88
77 54 15 1 43
35 97 26 21 29
13 46 96 69 47
51 38 91 32 63
73 99 30 15 16
42 58 21 88 44
45 13 27 68 9
36 6 81 53 5
78 76 11 60 1
57 76 50 78 31
45 42 68 53 16
9 88 89 19 21
96 61 97 69 34
98 87 33 82 0
4 16 89 57 64
46 75 77 65 23
71 42 96 52 38
1 21 93 0 35
59 80 53 36 58
97 62 35 1 88
98 60 17 45 94
12 43 65 23 19
71 52 3 40 59
50 76 61 20 22
92 65 38 93 13
55 26 10 46 29
85 23 19 74 34
60 14 27 36 18
53 4 52 49 17
99 56 93 70 28
25 0 77 80 57
91 50 72 76 23
53 58 95 78 59
75 85 90 44 9
30 8 5 60 6
28 35 59 70 96
20 99 98 81 79
94 78 27 71 4
7 34 43 46 51
93 65 22 69 33
92 49 75 35 11
58 39 62 86 83
64 4 76 48 82
74 1 56 95 31
1 78 98 90 55
80 14 36 99 7
85 8 10 9 92
76 11 40 70 62
43 53 74 35 58
46 78 35 28 49
84 73 65 25 34
40 59 66 36 67
16 22 29 0 45
20 56 39 88 91
32 58 35 25 79
78 94 57 38 14
89 87 68 48 76
7 67 40 51 33
95 31 43 93 92
38 21 82 31 23
54 16 77 37 42
73 99 7 34 90
71 26 5 91 52
22 27 47 85 62
2 86 28 37 55
1 82 9 36 31
52 98 89 30 60
13 17 63 38 57
73 50 42 20 12
56 3 67 62 35
59 39 19 22 27
21 58 57 41 54
75 13 82 50 32
23 5 99 66 10
7 19 45 66 78
38 57 40 73 87
58 30 99 53 83
64 1 8 56 95
70 77 16 18 82
72 83 95 37 35
54 59 92 21 79
7 81 86 29 41
52 99 42 57 71
3 15 75 34 77
7 70 5 69 4
34 60 40 73 6
74 54 67 32 38
93 62 17 51 86
57 88 99 3 16
42 74 11 34 7
82 47 71 31 58
69 23 43 4 64
32 19 98 93 41
63 97 8 85 48
63 54 34 38 86
4 27 15 49 0
61 77 53 98 74
62 23 88 97 37
93 28 25 50 13
56 82 41 27 79
23 31 64 7 65
52 98 93 16 57
88 49 10 11 62
43 95 53 51 83
41 10 87 54 86
19 22 13 40 17
37 27 45 29 63
83 85 81 90 7
57 88 47 66 56
67 44 54 88 89
20 46 61 28 92
86 49 60 83 95
42 78 97 51 96
11 62 4 26 31
18 68 87 26 70
62 84 11 33 90
0 45 66 83 6
20 19 27 44 55
52 8 5 7 3
54 94 88 76 92
13 98 22 33 26
95 62 53 81 24
29 69 15 87 25
61 40 84 90 93
7 31 3 28 46
20 51 21 18 38
30 92 39 70 61
27 88 35 96 74
23 5 66 11 42
40 61 90 57 54
41 14 99 62 59
92 10 48 81 52
22 29 77 18 87
31 79 25 94 13
17 26 44 98 57
74 83 51 14 11
76 91 96 64 33
43 45 92 72 27
66 3 28 20 40
88 82 44 71 55
83 47 51 76 24
86 19 42 34 99
30 31 87 48 62
98 53 68 9 21
3 31 6 41 61
24 77 81 96 44
78 73 1 98 11
40 80 27 65 92
62 67 2 30 10
78 46 50 65 56
84 16 32 58 86
22 12 54 99 35
9 43 55 10 94
66 81 59 92 76
78 3 55 23 83
13 42 94 91 22
14 37 31 67 71
8 61 57 34 43
74 50 0 39 65
78 16 13 91 34
14 74 86 3 97
12 89 58 65 51
29 57 48 44 93
95 1 42 39 92
93 96 16 85 25
59 3 70 19 17
21 84 58 38 86
57 10 35 95 79
81 44 73 63 9
22 1 96 7 93
40 49 2 4 66
87 21 17 32 48
44 28 42 99 26
69 8 85 86 75
21 31 37 87 28
89 43 74 83 57
95 29 92 88 35
94 25 97 81 50
15 19 73 45 63
92 62 67 95 57
30 8 4 39 64
99 31 70 63 96
25 53 24 93 35
34 51 82 91 28
41 30 20 56 46
16 32 98 60 35
67 9 43 42 88
78 90 71 5 29
49 31 37 63 18
80 40 88 5 62
3 6 74 71 97
19 58 63 59 38
50 64 34 68 45
25 30 21 33 83
10 65 67 17 50
21 51 18 68 59
29 78 77 99 76
62 35 96 7 95
82 53 42 49 69
74 65 89 6 1
18 30 72 75 24
60 50 52 55 82
68 99 4 61 22
9 37 84 57 87
96 85 56 72 2
9 38 98 12 4
34 45 74 97 86
18 94 64 70 68
91 41 58 39 66
34 13 26 80 29
0 4 21 60 90
39 73 12 2 19
64 44 61 88 45
59 50 8 91 49
34 85 55 2 75
10 15 89 12 63
90 29 87 73 71
38 17 84 45 9
97 98 77 23 61
47 43 22 58 1
63 44 2 94 99
33 81 51 49 13
38 86 42 91 23
7 67 68 39 84
4 26 12 38 41
43 16 88 71 99
50 24 19 77 98
23 73 44 10 51
56 42 30 52 59
57 16 9 62 27
26 65 56 10 82
0 74 78 12 99
77 18 38 5 37
7 60 40 90 23
14 69 18 51 8
21 79 60 36 12
68 44 59 45 16
90 50 85 25 70
91 31 30 54 26
24 40 51 72 63
31 60 62 25 96
9 44 35 28 91
97 4 34 81 2
61 68 94 52 86
0 57 95 88 94
36 38 25 35 19
13 6 8 61 98
45 85 86 69 97
41 32 7 15 59
41 82 19 29 34
44 96 6 91 76
69 21 32 94 98
4 10 88 30 2
8 74 56 65 99
36 91 73 15 54
62 55 40 27 44
11 60 95 61 46
31 32 21 41 35
74 86 83 89 79
2 96 94 82 68
39 83 49 30 15
62 11 86 99 59
51 80 12 72 58
87 66 98 53 29
44 71 18 63 85
11 75 60 66 13
36 9 94 57 8
10 12 32 3 86
4 29 54 70 21
27 33 76 83 67
77 29 65 39 44
52 34 25 93 64
35 4 57 92 84
41 51 88 96 0
21 91 82 3 26
23 8 36 20 73
54 39 60 34 57
49 99 97 69 43
41 93 95 80 63
73 77 4 9 22
17 33 15 86 79
38 16 99 98 30
64 92 76 50 68
83 85 52 87 88
57 53 13 36 76
7 10 91 3 22
8 84 56 73 59
62 80 85 38 33
68 97 47 14 96
36 8 98 43 70
85 95 31 1 51
33 41 78 89 56
76 16 15 34 82
12 18 39 4 3
98 49 41 30 95
68 89 81 48 84
15 19 90 66 14
32 1 88 34 64
73 65 6 20 86
22 18 13 74 34
75 4 60 88 46
25 97 54 94 91
42 67 40 11 81
5 12 49 48 15
82 91 18 73 57
97 50 34 16 66
29 43 81 20 15
19 44 85 4 32
90 58 39 53 42
50 53 83 10 0
93 16 84 23 13
89 63 75 69 51
65 35 67 56 70
4 37 29 47 38

@ -0,0 +1,38 @@
#lang br
(require racket/file sugar rackunit racket/set)
(define lines (map (λ (s) (map (λ (s2) (define ints (map string->number (string-split s2 ",")))
(+ (first ints) (* +i (second ints)))) (string-split s " -> "))) (file->lines "05.rktd")))
(define (Line-not-diagonal line)
(match line
[(list left right) (or (= (real-part left) (real-part right)) (= (imag-part left) (imag-part right)))]))
;; why does make-polar cause the solution to run faster?
;; both functions create an imaginary number
;; make-polar is slower to create the numbers (because it has to call trig functions)
;; but storing the polar numbers with frequency-hash is much faster
;; using inexact coefficients makes make-rectangular go faster
;; but still not as fast as make-polar
(define go-fast? #true)
(define imag-func (if go-fast? make-polar make-rectangular))
(define (expand line)
(match-define (list x1 x2) (map real-part line))
(match-define (list y1 y2) (map imag-part line))
(cond
[(= x1 x2)
(for/list ([i (in-range (apply min (list y1 y2)) (add1 (apply max (list y1 y2))))])
(imag-func x1 i))]
[(= y1 y2)
(for/list ([i (in-range (apply min (list x1 x2)) (add1 (apply max (list x1 x2))))])
(imag-func i y1))]
[else (for/list ([x (in-range x1 ((if (> x1 x2) sub1 add1) x2) (if (> x1 x2) -1 1))]
[y (in-range y1 ((if (> y1 y2) sub1 add1) y2) (if (> y1 y2) -1 1))])
(imag-func x y))]))
(define (calc-result points)
(length (filter (λ (x) (>= x 2)) (hash-values (time (frequency-hash points))))))
(check-equal? (calc-result (append-map expand (filter Line-not-diagonal lines))) 6113)
(check-equal? (calc-result (append-map expand lines)) 20373)

@ -0,0 +1,500 @@
309,347 -> 309,464
425,687 -> 300,687
226,766 -> 885,107
681,618 -> 921,378
968,54 -> 38,984
35,341 -> 321,627
493,485 -> 632,485
908,183 -> 110,981
677,378 -> 677,231
703,378 -> 703,536
179,581 -> 429,331
339,133 -> 664,458
212,680 -> 212,136
251,699 -> 858,699
163,725 -> 163,22
70,226 -> 97,226
968,119 -> 954,119
551,551 -> 415,551
768,167 -> 546,167
125,302 -> 155,332
640,201 -> 341,201
757,791 -> 757,736
406,570 -> 418,558
250,919 -> 976,193
570,362 -> 304,96
463,973 -> 463,337
322,199 -> 322,73
141,186 -> 141,906
964,940 -> 964,743
99,461 -> 15,461
255,856 -> 255,194
650,293 -> 650,136
89,98 -> 969,978
974,977 -> 37,40
641,795 -> 985,795
441,972 -> 441,427
18,942 -> 943,17
166,167 -> 617,167
182,146 -> 790,146
88,854 -> 928,14
537,38 -> 233,38
786,562 -> 867,562
251,102 -> 147,102
551,373 -> 672,252
915,713 -> 791,589
28,373 -> 28,651
463,365 -> 396,365
349,948 -> 737,948
246,860 -> 84,860
334,817 -> 866,285
880,958 -> 641,719
229,203 -> 740,714
39,220 -> 575,756
899,383 -> 275,383
49,952 -> 774,952
384,42 -> 581,42
11,731 -> 522,731
194,638 -> 679,153
922,279 -> 922,398
589,579 -> 709,579
97,716 -> 244,716
769,923 -> 769,189
636,567 -> 866,337
413,925 -> 729,925
581,524 -> 89,32
970,217 -> 851,217
716,373 -> 122,967
606,785 -> 191,785
322,432 -> 706,432
788,911 -> 788,889
904,917 -> 904,862
889,351 -> 796,351
508,18 -> 508,165
859,187 -> 879,187
531,409 -> 562,378
914,97 -> 233,778
194,191 -> 194,592
620,674 -> 55,109
194,973 -> 863,973
679,940 -> 679,296
836,108 -> 700,108
861,376 -> 585,376
166,299 -> 166,141
847,377 -> 847,217
872,972 -> 872,413
28,872 -> 28,695
876,152 -> 108,920
487,536 -> 697,536
30,28 -> 982,980
834,503 -> 834,586
927,459 -> 339,459
87,809 -> 770,126
24,973 -> 981,16
185,383 -> 185,13
850,328 -> 541,19
399,111 -> 742,111
703,305 -> 458,305
571,889 -> 803,657
356,697 -> 364,697
847,160 -> 108,899
170,954 -> 137,954
927,120 -> 897,150
687,662 -> 507,662
762,259 -> 762,951
90,612 -> 647,55
114,437 -> 483,68
138,269 -> 638,269
720,947 -> 29,947
563,52 -> 360,52
665,953 -> 187,475
283,855 -> 283,744
120,284 -> 120,319
935,422 -> 349,422
372,858 -> 372,779
68,768 -> 814,22
206,400 -> 22,400
72,954 -> 977,49
861,557 -> 794,557
893,654 -> 893,132
306,364 -> 697,364
828,165 -> 695,165
122,57 -> 986,921
509,470 -> 608,470
794,730 -> 520,456
291,305 -> 525,71
648,530 -> 92,530
329,173 -> 329,343
960,941 -> 133,114
256,523 -> 369,523
433,379 -> 195,379
199,783 -> 821,783
974,205 -> 299,205
200,400 -> 27,573
294,175 -> 294,493
320,20 -> 320,393
274,85 -> 969,780
112,73 -> 112,969
371,381 -> 121,631
942,906 -> 46,906
663,742 -> 208,287
422,258 -> 422,356
884,283 -> 859,283
750,142 -> 710,142
823,454 -> 642,273
296,366 -> 296,245
518,615 -> 852,949
74,513 -> 655,513
850,77 -> 850,950
985,980 -> 33,28
16,982 -> 979,19
265,234 -> 849,234
303,408 -> 229,334
344,63 -> 932,651
417,597 -> 548,597
729,361 -> 245,845
888,156 -> 80,964
215,29 -> 411,225
762,108 -> 115,108
63,855 -> 875,43
398,382 -> 874,858
419,78 -> 419,417
263,553 -> 131,553
766,399 -> 584,399
778,126 -> 226,678
580,781 -> 580,401
623,506 -> 966,506
364,723 -> 364,349
834,667 -> 177,10
402,515 -> 402,493
924,50 -> 22,952
64,826 -> 64,470
199,694 -> 145,694
893,900 -> 20,27
850,834 -> 725,959
47,573 -> 575,45
71,287 -> 71,296
796,728 -> 796,442
88,700 -> 726,700
230,332 -> 412,514
618,284 -> 618,661
221,738 -> 817,142
149,38 -> 474,38
563,331 -> 441,331
219,187 -> 522,187
300,341 -> 300,633
228,305 -> 70,463
396,875 -> 22,875
533,116 -> 519,116
257,781 -> 257,443
181,236 -> 181,822
10,13 -> 986,989
59,290 -> 753,984
121,89 -> 121,827
958,233 -> 653,233
685,641 -> 685,322
167,124 -> 446,403
246,170 -> 77,339
503,189 -> 503,72
666,182 -> 824,340
825,675 -> 629,479
967,915 -> 967,785
749,403 -> 92,403
950,217 -> 950,391
356,872 -> 514,872
279,900 -> 138,900
114,284 -> 502,672
700,792 -> 32,124
252,783 -> 806,229
557,215 -> 557,103
35,29 -> 963,957
650,285 -> 23,912
669,191 -> 446,414
66,283 -> 66,37
564,250 -> 175,250
425,611 -> 425,964
662,224 -> 707,224
599,979 -> 599,873
402,886 -> 402,979
329,181 -> 329,964
120,891 -> 685,326
788,438 -> 788,460
140,939 -> 338,939
496,343 -> 327,343
749,151 -> 749,339
181,527 -> 181,455
61,949 -> 966,44
138,262 -> 894,262
192,146 -> 801,146
301,405 -> 765,405
938,235 -> 938,55
543,958 -> 320,958
54,982 -> 867,169
66,147 -> 702,783
839,419 -> 97,419
519,879 -> 519,707
159,255 -> 159,787
258,897 -> 968,897
427,10 -> 427,62
782,750 -> 782,960
878,742 -> 785,649
171,74 -> 883,74
220,184 -> 910,874
696,984 -> 696,512
175,753 -> 303,753
666,515 -> 45,515
886,101 -> 14,973
121,823 -> 154,823
63,976 -> 987,52
480,478 -> 167,791
757,338 -> 757,719
593,286 -> 542,286
989,602 -> 989,135
793,857 -> 712,857
65,976 -> 843,198
729,334 -> 106,957
102,234 -> 42,294
830,223 -> 267,223
800,590 -> 921,590
526,38 -> 863,38
770,719 -> 65,14
317,267 -> 541,267
653,697 -> 653,720
506,532 -> 483,555
564,387 -> 205,387
971,669 -> 971,966
421,905 -> 421,264
506,85 -> 407,85
435,863 -> 230,863
945,133 -> 694,133
604,921 -> 604,168
66,677 -> 499,244
300,551 -> 893,551
836,228 -> 836,631
29,208 -> 443,208
546,584 -> 148,584
855,904 -> 855,315
636,694 -> 852,478
399,252 -> 399,170
46,596 -> 46,789
919,211 -> 201,929
662,983 -> 545,866
22,913 -> 908,27
441,605 -> 94,952
190,257 -> 769,836
700,395 -> 861,556
562,620 -> 562,687
34,165 -> 603,734
372,302 -> 585,302
71,857 -> 588,340
956,566 -> 738,784
778,610 -> 74,610
331,640 -> 346,655
274,473 -> 274,691
646,142 -> 144,142
911,971 -> 618,971
233,341 -> 233,505
467,990 -> 41,990
633,739 -> 57,163
585,405 -> 905,405
320,449 -> 320,628
44,738 -> 44,293
67,267 -> 770,970
933,155 -> 765,323
383,879 -> 896,366
130,986 -> 435,986
264,863 -> 979,148
114,721 -> 725,110
546,949 -> 546,790
762,42 -> 67,42
443,985 -> 245,985
689,803 -> 126,803
496,702 -> 943,255
955,963 -> 117,125
686,411 -> 979,704
226,256 -> 226,352
889,683 -> 889,437
47,161 -> 545,161
450,283 -> 450,469
461,338 -> 461,695
808,777 -> 808,962
902,459 -> 902,744
793,703 -> 158,68
100,919 -> 69,919
912,785 -> 331,204
712,609 -> 712,512
268,762 -> 268,355
972,667 -> 974,667
647,647 -> 164,647
589,180 -> 589,644
836,258 -> 376,718
676,977 -> 211,977
626,608 -> 874,360
271,911 -> 324,858
182,374 -> 182,347
14,989 -> 985,18
461,462 -> 956,957
82,79 -> 974,971
607,478 -> 607,147
898,76 -> 582,392
326,31 -> 683,31
768,47 -> 768,348
35,386 -> 185,386
803,391 -> 803,932
879,486 -> 879,658
183,39 -> 183,855
431,467 -> 499,399
434,306 -> 304,436
774,618 -> 521,618
364,426 -> 364,457
44,849 -> 791,102
70,850 -> 276,850
181,838 -> 181,736
574,18 -> 574,784
103,613 -> 537,179
34,218 -> 115,299
808,777 -> 636,777
483,112 -> 483,939
15,790 -> 15,253
433,427 -> 742,427
829,947 -> 895,947
361,180 -> 860,180
124,499 -> 124,615
879,712 -> 745,712
16,12 -> 16,149
36,981 -> 36,561
929,52 -> 30,951
845,85 -> 318,612
114,731 -> 794,51
434,280 -> 406,308
530,513 -> 114,513
417,715 -> 417,273
44,845 -> 44,225
951,122 -> 450,623
32,707 -> 32,832
51,58 -> 51,806
165,305 -> 49,189
517,221 -> 942,221
125,233 -> 193,233
903,180 -> 101,982
123,303 -> 247,179
199,174 -> 546,521
185,860 -> 538,860
825,751 -> 825,784
454,720 -> 64,720
28,10 -> 974,956
626,760 -> 586,760
91,234 -> 10,234
973,939 -> 65,31
589,308 -> 255,308
547,945 -> 239,945
909,914 -> 111,116
484,182 -> 253,182
145,575 -> 339,575
215,143 -> 611,143
963,983 -> 20,40
220,733 -> 333,846
126,860 -> 940,46
715,823 -> 715,284
832,65 -> 436,65
923,496 -> 530,889
708,517 -> 708,764
154,681 -> 22,549
909,135 -> 57,987
225,966 -> 225,941
629,491 -> 629,17
927,349 -> 72,349
15,987 -> 983,19
265,912 -> 74,912
14,985 -> 988,11
986,64 -> 129,921
697,831 -> 943,831
379,143 -> 853,617
232,887 -> 623,887
947,473 -> 947,453
898,762 -> 218,762
599,386 -> 870,386
757,137 -> 757,496
437,285 -> 437,326
515,311 -> 515,63
305,703 -> 720,703
321,770 -> 88,537
75,48 -> 457,430
38,499 -> 38,544
481,896 -> 481,944
614,483 -> 437,483
647,430 -> 368,430
641,669 -> 641,691
849,626 -> 427,204
805,688 -> 805,536
102,315 -> 102,108
729,525 -> 770,525
234,702 -> 38,702
17,457 -> 526,457
369,155 -> 369,647
216,118 -> 216,43
342,384 -> 342,905
470,832 -> 314,676
179,318 -> 179,315
40,707 -> 547,707
771,236 -> 453,236
113,823 -> 826,110
731,642 -> 707,642
36,398 -> 810,398
233,447 -> 979,447
74,286 -> 907,286
939,223 -> 939,10
866,57 -> 866,656
978,20 -> 10,988
816,176 -> 50,942
293,868 -> 293,350
900,159 -> 148,911
58,84 -> 644,84
720,416 -> 720,906
935,31 -> 13,953
41,727 -> 221,727
633,112 -> 633,695
418,947 -> 418,574
632,711 -> 791,711
73,228 -> 73,861
59,447 -> 83,447
418,938 -> 418,638
922,352 -> 636,352
66,773 -> 66,868
69,678 -> 600,147
333,251 -> 298,251
371,803 -> 740,434
976,972 -> 976,165
896,415 -> 240,415
672,476 -> 860,476
202,291 -> 195,291
99,971 -> 518,552
284,858 -> 910,232
187,282 -> 187,627
157,445 -> 157,665
421,879 -> 38,496
155,431 -> 405,431
772,472 -> 315,929
69,818 -> 132,818
70,328 -> 70,800
471,788 -> 646,788
960,900 -> 97,37
258,566 -> 186,494
345,413 -> 306,413
897,173 -> 897,896
74,740 -> 74,795
679,238 -> 679,811
870,64 -> 64,870
30,869 -> 288,869
539,380 -> 539,862
452,692 -> 748,692
527,712 -> 527,139
725,504 -> 717,504
201,338 -> 636,338
626,719 -> 626,302
580,153 -> 274,459
654,215 -> 246,215
363,738 -> 363,192
335,502 -> 970,502
266,52 -> 266,442
125,127 -> 281,127

@ -0,0 +1,18 @@
#lang br
(require racket/file sugar rackunit)
(define fish (map string->number (string-split (file->string "06.rktd") ",")))
(define (simulate fish days)
(for/fold ([freqs (frequency-hash fish)]
#:result (apply + (hash-values freqs)))
([d (in-range days)])
(hash-set*
(for/hasheq ([(k v) (in-hash freqs)]
#:unless (zero? k))
(values (sub1 k) v))
6 (+ (hash-ref freqs 7 0) (hash-ref freqs 0 0))
8 (hash-ref freqs 0 0))))
(check-equal? (simulate fish 80) 361169)
(check-equal? (simulate fish 256) 1634946868992)

@ -0,0 +1 @@
1,1,3,5,3,1,1,4,1,1,5,2,4,3,1,1,3,1,1,5,5,1,3,2,5,4,1,1,5,1,4,2,1,4,2,1,4,4,1,5,1,4,4,1,1,5,1,5,1,5,1,1,1,5,1,2,5,1,1,3,2,2,2,1,4,1,1,2,4,1,3,1,2,1,3,5,2,3,5,1,1,4,3,3,5,1,5,3,1,2,3,4,1,1,5,4,1,3,4,4,1,2,4,4,1,1,3,5,3,1,2,2,5,1,4,1,3,3,3,3,1,1,2,1,5,3,4,5,1,5,2,5,3,2,1,4,2,1,1,1,4,1,2,1,2,2,4,5,5,5,4,1,4,1,4,2,3,2,3,1,1,2,3,1,1,1,5,2,2,5,3,1,4,1,2,1,1,5,3,1,4,5,1,4,2,1,1,5,1,5,4,1,5,5,2,3,1,3,5,1,1,1,1,3,1,1,4,1,5,2,1,1,3,5,1,1,4,2,1,2,5,2,5,1,1,1,2,3,5,5,1,4,3,2,2,3,2,1,1,4,1,3,5,2,3,1,1,5,1,3,5,1,1,5,5,3,1,3,3,1,2,3,1,5,1,3,2,1,3,1,1,2,3,5,3,5,5,4,3,1,5,1,1,2,3,2,2,1,1,2,1,4,1,2,3,3,3,1,3,5

@ -0,0 +1,13 @@
#lang br
(require racket/file sugar rackunit)
(define posns (map string->number (string-split (file->string "07.rktd") ",")))
(define/caching (gauss-summation x) (* (/ x 2) (+ x 1)))
(define (fuel-cost alignment [post-proc values])
(foldl (λ (posn res) (+ res (post-proc (abs (- alignment posn))))) 0 posns))
(define possible-alignments (remove-duplicates posns))
(check-equal? (apply min (map fuel-cost possible-alignments)) 349357)
(check-equal? (apply min (map (λ (pa) (fuel-cost pa gauss-summation)) possible-alignments)) 96708205)

@ -0,0 +1 @@
1101,1,29,67,1102,0,1,65,1008,65,35,66,1005,66,28,1,67,65,20,4,0,1001,65,1,65,1106,0,8,99,35,67,101,99,105,32,110,39,101,115,116,32,112,97,115,32,117,110,101,32,105,110,116,99,111,100,101,32,112,114,111,103,114,97,109,10,33,133,43,1060,890,12,15,136,42,25,96,694,522,893,204,204,1168,311,1046,1699,26,399,299,66,644,402,65,480,711,72,894,244,249,337,331,774,126,23,484,1299,662,404,235,86,1492,556,73,478,210,82,433,597,154,130,178,491,578,856,532,1191,544,256,831,252,1001,109,37,1290,317,376,22,742,496,930,118,28,376,73,247,942,895,38,675,138,387,203,271,104,65,1099,981,167,67,57,607,1095,202,225,1067,1757,324,127,785,266,518,135,914,1006,1402,578,28,548,211,673,302,525,208,115,92,514,518,71,1298,796,780,166,1341,475,273,101,1155,838,1219,901,727,497,168,543,416,174,31,755,865,106,358,236,186,369,550,465,617,375,535,1639,513,419,1377,1024,704,77,38,0,149,5,28,1163,149,1654,614,1201,89,1141,844,1390,1081,132,1385,52,1027,80,572,377,340,39,630,875,692,289,339,358,68,205,54,149,41,1208,1528,171,204,438,571,308,556,1372,426,204,18,31,51,40,287,1845,1721,441,240,875,901,328,800,341,59,530,134,275,11,7,7,1,1571,218,374,536,992,464,234,398,300,74,99,1163,1039,430,43,659,667,1115,407,257,717,657,249,46,109,734,67,1010,581,1070,738,478,621,183,224,1372,560,1573,1026,338,485,1138,1007,910,16,846,556,423,200,962,103,570,540,900,839,319,171,14,22,205,225,569,81,381,132,127,139,123,788,1571,35,830,65,677,1745,819,804,854,346,190,480,1500,76,1049,306,17,668,113,163,755,1015,718,1037,156,267,158,74,377,26,294,203,334,1186,88,384,853,404,290,135,620,668,234,1158,2,1102,137,884,287,15,638,1003,187,24,534,24,647,683,934,275,1844,887,1746,1614,1788,632,100,332,1565,1352,341,1027,475,958,289,1564,89,1138,233,535,790,990,863,889,45,44,169,251,522,11,41,104,45,828,1206,1515,645,39,544,382,1413,995,188,310,51,39,474,14,7,1387,809,428,77,8,867,1105,718,426,146,486,191,1251,677,1139,802,585,1140,46,39,128,867,49,33,198,731,349,661,296,103,22,444,1198,1149,188,245,492,1147,230,213,300,551,295,1313,365,975,587,1416,1213,233,257,631,564,876,434,1353,51,748,1179,1428,915,115,57,90,1312,892,200,1349,35,1010,445,619,1261,108,14,1424,481,381,209,154,23,972,646,593,6,289,171,543,97,28,401,290,298,14,37,1326,1177,533,67,75,294,328,527,449,455,176,345,226,729,210,55,45,0,834,887,123,1326,931,278,449,1278,608,217,411,143,447,16,1043,29,165,88,860,582,21,811,920,162,1788,15,423,1172,842,801,845,20,155,155,642,40,1036,560,348,689,328,505,84,1013,58,93,1653,233,233,383,380,84,617,1128,305,123,508,205,6,322,118,359,1186,84,677,640,80,1357,868,1035,8,64,995,1246,266,443,346,112,523,625,206,66,565,1878,25,1277,936,283,148,987,282,368,883,542,631,946,118,53,4,235,16,950,4,998,106,25,151,1013,27,1038,77,140,82,1119,236,125,947,1446,680,301,301,936,21,609,516,280,264,281,108,43,215,36,126,401,402,693,360,321,92,1809,305,551,86,77,278,81,524,400,1458,1342,897,49,35,518,288,655,91,398,38,251,647,79,400,151,520,459,960,425,663,298,584,90,533,690,610,755,56,19,21,244,548,1116,773,43,115,171,1127,103,1199,1470,176,451,693,65,186,262,963,137,1422,431,533,210,799,17,388,600,1113,2,181,815,1153,6,618,590,719,196,39,301,424,193,560,175,351,279,603,171,423,146,158,48,398,513,115,1,1051,817,200,473,143,261,435,856,1057,503,51,846,1020,177,1091,232,500,372,475,70,485,1227,1032,64,743,299,159,1077,18,204,944,1075,29,78,63,67,9,1007,354,1046,491,448,206,222,121,955,290,381,147,146,104,576,722,163,715,1475,130,1104,586,97,352,173,713,315,1482,1221,38,10,81,457,745,323,47,197,1012,1593,128,463,373,272,90,121,1248,1451,540,681,63,950,19,208,230,1362,1225,1500,207,81,739,288,626,261,1188,356,889,408,3,368,94,858,1512,834,43,5,833,826,33,791,800,39,299,1587,41,783,498,899,296,1189,470,66,307,892,47,207,199,902,17,14,1831,11,576,729,1436,153,142,81,165,214,1543,1464,561,737,180,162,515,867,65,74,200,9,11,539,19,305,996,334,297,1825,427,169,225,53,688,420,623,111,313,324,5,376,433,135,308,94

@ -0,0 +1,71 @@
#lang br
(require racket/file rackunit racket/dict)
(define (parse-ints strs) (map (λ (str) (string-split str)) strs))
(define recs
(let* ([lines (string-split (file->string "08.rktd") "\n")]
[sublines (map (λ (str) (string-split str "|")) lines)])
(map parse-ints sublines)))
(define strlens (append-map (λ (vals) (map string-length vals)) (map second recs)))
(check-equal? (count (λ (len) (memq len '(2 3 4 7))) strlens) 278)
(require csp racket/set)
(define (infer-config #:one one-digit #:four four-digit #:seven seven-digit #:five five-segment-digits)
(define prob (make-csp))
(add-vars! prob '(s1 s2 s3 s4 s5 s6 s7) '(a b c d e f g))
(add-all-diff-constraint! prob #:same eq?)
(add-constraint! prob (λ (s3 s6) (equal? (set s3 s6) one-digit)) '(s3 s6))
(add-constraint! prob
(λ (s1 s2 s3 s4 s5 s6 s7)
(define two-pattern (set s1 s3 s4 s5 s7))
(define three-pattern (set s1 s3 s4 s6 s7))
(define five-pattern (set s1 s2 s4 s6 s7))
(for/and ([pat (list two-pattern three-pattern five-pattern)])
(member pat five-segment-digits)))
'(s1 s2 s3 s4 s5 s6 s7))
(add-constraint! prob (λ (s2 s3 s4 s6) (equal? (set s2 s3 s4 s6) four-digit)) '(s2 s3 s4 s6))
(add-constraint! prob (λ (s1 s3 s6) (equal? (set s1 s3 s6) seven-digit)) '(s1 s3 s6))
(solve prob))
(define segments-table (list
(cons (set 's1 's2 's3 's5 's6 's7) 0)
(cons (set 's3 's6) 1)
(cons (set 's1 's3 's4 's5 's7) 2)
(cons (set 's1 's3 's4 's6 's7) 3)
(cons (set 's2 's3 's4 's6) 4)
(cons (set 's1 's2 's4 's6 's7) 5)
(cons (set 's1 's2 's4 's5 's6 's7) 6)
(cons (set 's1 's3 's6) 7)
(cons (set 's1 's2 's3 's4 's5 's6 's7) 8)
(cons (set 's1 's2 's3 's4 's6 's7) 9)))
(define (string->symbols str) (map (λ (c) (string->symbol (string c))) (string->list str)))
(define (wire-config strs)
(define encdoded-digits (map (compose1 list->set string->symbols) strs))
(define (filter-length len) (filter (λ (x) (= len (set-count x))) encdoded-digits))
(define one-digit (car (filter-length 2)))
(define four-digit (car (filter-length 4)))
(define seven-digit (car (filter-length 3)))
(define five-segment-digits (filter-length 5))
(infer-config #:one one-digit #:four four-digit #:seven seven-digit #:five five-segment-digits))
(define (decode-number config pattern)
(define config-reverse (for/hasheq ([(k v) (in-dict config)])
(values v k)))
(define segments (for/set ([item pattern])
(d