2021: day04: part 1

This commit is contained in:
Antoine Martin 2021-12-04 14:39:22 +01:00
parent 5c3a631dde
commit 1fb5dd9ec4
5 changed files with 773 additions and 1 deletions

601
aoc2021/input/day04.txt Normal file
View file

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

View file

@ -0,0 +1,19 @@
7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
22 13 17 11 0
8 2 23 4 24
21 9 14 16 7
6 10 3 18 5
1 12 20 15 19
3 15 0 2 22
9 18 13 17 5
19 8 7 25 23
20 11 10 24 4
14 21 16 12 6
14 21 17 24 4
10 16 15 9 19
18 8 23 26 20
22 11 13 6 5
2 0 12 3 7

150
aoc2021/src/day04.rs Normal file
View file

@ -0,0 +1,150 @@
use std::collections::HashMap;
use std::fmt::Write;
use anyhow::{anyhow, Context, Result};
const INPUT: &str = include_str!("../input/day04.txt");
const GRID_WIDTH: usize = 5;
const GRID_HEIGHT: usize = 5;
const GRID_SIZE: usize = GRID_WIDTH * GRID_HEIGHT;
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<u64> {
let (draws, grids) = input
.split_once("\n\n")
.context("couldn't split draws from grids")?;
let draws = draws
.split(',')
.map(|num| num.parse::<u8>().context("couldn't parse drawn number:"))
.collect::<Result<Vec<_>>>()?;
let mut grids = grids
.split("\n\n")
.map(str::parse::<Grid>)
.collect::<Result<Vec<_>>>()?;
let (mut wdraw, mut wgrid) = (None, None);
'draw_loop: for draw in draws {
for grid in &mut grids {
if grid.mark(draw) && grid.is_winning() {
wgrid = Some(grid.clone());
wdraw = Some(draw);
break 'draw_loop;
}
}
}
match (wdraw, wgrid) {
(Some(draw), Some(grid)) => {
Ok(draw as u64 * grid.unmarked_numbers().map(|n| *n as u64).sum::<u64>())
}
_ => Err(anyhow!("couldn't find a winning grid!")),
}
}
#[derive(Debug, Clone)]
struct Grid {
number_to_pos: HashMap<u8, (usize, usize)>,
pos_to_number: HashMap<(usize, usize), u8>,
grid: [bool; GRID_SIZE],
}
impl Grid {
fn mark(&mut self, draw: u8) -> bool {
match self.number_to_pos.get(&draw) {
Some(&(x, y)) => {
*self.access_grid_mut(x, y) = true;
true
}
None => false,
}
}
fn is_winning(&self) -> bool {
let mut rows = [0u8; GRID_HEIGHT];
let mut cols = [0u8; GRID_WIDTH];
for (y, row) in rows.iter_mut().enumerate() {
for (x, col) in cols.iter_mut().enumerate() {
if self.access_grid(x, y) {
*row += 1;
*col += 1;
if *row as usize == GRID_WIDTH || *col as usize == GRID_HEIGHT {
return true;
}
}
}
}
false
}
fn unmarked_numbers(&self) -> impl Iterator<Item = &u8> {
self.number_to_pos
.iter()
.filter_map(|(num, &(x, y))| (!self.access_grid(x, y)).then(|| num))
}
fn access_grid(&self, x: usize, y: usize) -> bool {
self.grid[y * GRID_HEIGHT + x]
}
fn access_grid_mut(&mut self, x: usize, y: usize) -> &mut bool {
&mut self.grid[y * GRID_HEIGHT + x]
}
}
impl std::str::FromStr for Grid {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
let mut numbers = s.split_whitespace().map(str::parse);
let mut number_to_pos = HashMap::new();
let mut pos_to_number = HashMap::new();
for y in 0..GRID_HEIGHT {
for x in 0..GRID_WIDTH {
let pos = (x, y);
let number: u8 = numbers
.next()
.context("not enough numbers for grid")?
.context("couldn't parse number:")?;
number_to_pos.insert(number, pos);
pos_to_number.insert(pos, number);
}
}
Ok(Grid {
number_to_pos,
pos_to_number,
grid: [false; GRID_SIZE],
})
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day04_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 4512);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 45031);
}
}

View file

@ -3,3 +3,4 @@
pub mod day01;
pub mod day02;
pub mod day03;
pub mod day04;

View file

@ -5,9 +5,10 @@ use aoc::DayFunc;
use aoc2021::day01;
use aoc2021::day02;
use aoc2021::day03;
use aoc2021::day04;
fn main() -> Result<()> {
let days: &[DayFunc] = &[day01::run, day02::run, day03::run];
let days: &[DayFunc] = &[day01::run, day02::run, day03::run, day04::run];
aoc::run(days)
}