This commit is contained in:
2021-12-04 23:41:59 +01:00
parent cb4da1e6ec
commit 7bc5df1247
2 changed files with 751 additions and 0 deletions

601
day-4.input Normal file
View File

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

150
day-4.scm Normal file
View File

@@ -0,0 +1,150 @@
(import (srfi :43))
; returns a list of numbers parsed from the first line of the file,
; separated by commas
(define (parse-draws file)
(let loop [(draws '()) (n 0)]
(let [(c (get-char file))]
(cond
[(char=? c #\,) (loop (cons n draws) 0)]
[(char-whitespace? c) (reverse (cons n draws))]
[else (loop draws (+ (* n 10) (string->number (string c))))]))))
; returns numbers 0 to 9 from ascii character
(define (char->number c)
(- (char->integer c) 48)) ; 48 is ASCII's number zero
; returns a number from two characters
; ex: '0' and '9' => 9
; ' ' and '6' => 6
; '1' and '2' => 12
(define (char-pair->number c1 c2)
(if (char-numeric? c1)
[+ (* 10 (char->number c1)) (char->number c2)]
[char->number c2]))
; returns a vector of 25 numbers
; parsed from input file where numbers are separated by whitespace
(define (read-board file)
(let parse-loop [(i 0) (numbers '())]
(if (= i 25)
[list->vector (reverse numbers)]
[let [(c2 (get-char file))
(c1 (get-char file))]
(get-char file) ; consume space or empty line
(parse-loop
(+ i 1)
(cons (char-pair->number c1 c2) numbers))])))
; returns a list of vectors of 25 numbers parsed from input file
(define (read-boards file)
(reverse
(let loop [(boards '())]
(get-char file) ; consume empty line
(if (eof-object? (peek-char file))
boards
[loop (cons (read-board file) boards)]))))
; returns a number where bit N is set if N'th number
; in board matches given number
; bits that are already set in mark are kept
(define (mark-bingo number board mark)
(let loop [(i 0)]
(if (< i 25)
[if (= (vector-ref board i) number)
[bitwise-ior mark (bitwise-arithmetic-shift-left 1 i)]
[loop (+ i 1)]]
mark)))
; marks the corresponding n'th bit in each board if
; an n'th element of the corresponding board matches input number
(define (mark-bingos! number boards marks)
(let loop [(board (car boards))
(boards (cdr boards))
(index 0)]
(vector-set! marks index
(mark-bingo number board (vector-ref marks index)))
(when (not (null? boards))
(loop (car boards) (cdr boards) (+ index 1)))))
; all possible bitfields corresponding to a line or column of bingo
(define bingos
'#(; lines
#b1111100000000000000000000
#b0000011111000000000000000
#b0000000000111110000000000
#b0000000000000001111100000
#b0000000000000000000011111
; columns
#b1000010000100001000010000
#b0100001000010000100001000
#b0010000100001000010000100
#b0001000010000100001000010
#b0000100001000010000100001))
; check if any bitfield represented grid of marked bingo cell is bingo!
(define (check-bingos marks)
(vector-index
(lambda (mark)
(vector-any
(lambda (mask)
(= mask (bitwise-and mask mark)))
bingos))
marks))
; computes the score of the winning board
(define (score boards marks index last-draw)
(let [(board (list-ref boards index))
(mark (vector-ref marks index))]
(let loop [(score 0) (index 0)]
(if (< index 25)
[if (bitwise-bit-set? mark index)
[loop score (+ index 1)]
[loop (+ score (vector-ref board index)) (+ index 1)]]
[* last-draw score]))))
; returns list with the index of the board that won and the score
; #f if none won after all draws
(define (bingo draws boards marks)
(let loop [(draw (car draws))
(draws (cdr draws))]
(mark-bingos! draw boards marks)
(let [(check (check-bingos marks))]
(if check
[list check (score boards marks check draw)]
[if (null? draws)
#f
[loop (car draws) (cdr draws)]]))))
; returns a list without its n-th element
(define (except list n-th)
(let loop [(list list) (i 0)]
(if (= i n-th)
(cdr list)
(cons (car list) (loop (cdr list) (+ i 1))))))
(define (last-winning draws boards)
(let loop [(boards boards)
(prev-score 0)
(marks (make-vector (length boards) 0))]
(if (null? boards)
prev-score
[let [(index+score (bingo draws boards marks))]
(if index+score
[loop
(except boards (car index+score))
(cadr index+score)
(make-vector (length boards) 0)]
[cadr index+score])])))
(call-with-input-file
"day-4.input"
(lambda (file)
(let* [(draws (parse-draws file))
(boards (read-boards file))]
(printf "part 1: ~% ")
(let* [(marks (make-vector (length boards) 0))
(index+score (bingo draws boards marks))]
(printf "bingo! ~a~%" (cadr index+score)))
(printf "part 2: ~% bingo! ~a~%"
(last-winning draws boards)))))