Day 04
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Julius 2021-12-04 09:52:49 +01:00
parent 183db991f9
commit 0c28d31523
Signed by: j00lz
GPG key ID: AF241B0AA237BBA2
3 changed files with 832 additions and 1 deletions

601
input/day04 Normal file
View file

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

227
src/day04.rs Normal file
View file

@ -0,0 +1,227 @@
use crate::Day;
#[derive(Clone)]
pub struct Day04 {
numbers: Vec<u32>,
boards: Vec<Board>,
}
#[derive(Clone, Eq, PartialEq, Debug)]
struct Board(Vec<Vec<Option<u32>>>);
impl Day for Day04 {
fn init(content: String) -> Self where Self: Sized {
let mut l = content.lines().collect::<Vec<&str>>();
let first = l[0];
let a = l.drain(0..2);
drop(a);
let nums = first.split(',').map(|x| x.parse::<u32>().expect("wat?")).collect();
let split = l.split(|x| x.is_empty());
let mut boards = vec![];
for vecs in split {
let mut rows = vec![];
for vec in vecs {
let v = vec.split_ascii_whitespace().map(|x| x.parse::<u32>().expect("foo")).map(Option::Some).collect();
rows.push(v);
}
boards.push(Board(rows));
}
Day04 {
numbers: nums,
boards,
}
}
fn part1(&self) -> String {
let z = self.clone();
let mut boards = z.boards;
for number in z.numbers {
for board in &mut boards {
let res = board.mark(number);
if res {
let s = board.unmarked_sum();
return format!("{}", s * number);
}
}
}
panic!("no board can win?")
}
fn part2(&self) -> String {
let z = self.clone();
let mut boards = z.boards.iter().cloned().map(Option::Some).collect::<Vec<Option<Board>>>();
for number in z.numbers {
let some_count = boards.iter().map(|x| if x.is_some() { 1 } else { 0 }).sum::<u32>();
#[allow(clippy::manual_flatten)]
for boardd in &mut boards {
if let Some(board) = boardd {
let res = board.mark(number);
if res {
if some_count == 1 {
let s = board.unmarked_sum();
return format!("{}", s * number);
}
*boardd = None;
}
}
}
}
panic!("no board can win?")
}
}
impl Board {
fn mark(&mut self, num: u32) -> bool {
#[allow(clippy::manual_flatten)]
for columns in &mut self.0 {
for row in columns.iter_mut() {
if let Some(v) = row {
if *v == num {
*row = None;
}
}
}
}
self.check_rows() || self.check_columns()
}
fn check_rows(&self) -> bool {
for columns in &self.0 {
if columns.iter().all(Option::is_none) {
return true;
}
}
false
}
fn check_columns(&self) -> bool {
let t = Board::transpose(&self.0);
for rows in t {
if rows.iter().all(Option::is_none) {
return true;
}
}
false
}
fn transpose<T: Clone>(v: &[Vec<T>]) -> Vec<Vec<T>> {
assert!(!v.is_empty());
let len = v[0].len();
let mut iters: Vec<_> = v.iter().map(|n| n.iter()).collect();
(0..len)
.map(|_| {
iters
.iter_mut()
.map(|n| n.next().unwrap())
.cloned()
.collect::<Vec<T>>()
})
.collect()
}
fn unmarked_sum(&self) -> u32 {
self.0.iter().map(|x| x.iter().flatten().sum::<u32>()).sum()
}
}
#[cfg(test)]
mod tests {
use std::fs::read_to_string;
use crate::Day04;
use crate::day04::Board;
use crate::day::Day;
const INPUT: &str = r"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";
#[test]
fn board_mark_test() {
let mut b = Board(vec![vec![Some(10)]]);
let res = b.mark(10);
assert_eq!(b.0[0][0], None);
assert!(res)
}
#[test]
fn board_rows_are_marked() {
let b = Board(vec![vec![None, None, None, None], vec![Some(10), Some(10), Some(10), Some(10)]]);
assert!(b.check_rows())
}
#[test]
fn board_rows_are_not_marked() {
let b = Board(vec![vec![None, None, Some(10), None]]);
assert!(!b.check_rows())
}
#[test]
fn board_cols_are_marked() {
let b = Board(vec![vec![None], vec![None], vec![None], vec![None]]);
assert!(b.check_columns())
}
#[test]
fn board_cols_are_not_marked() {
let b = Board(vec![vec![None], vec![None], vec![Some(10)], vec![None]]);
assert!(!b.check_columns())
}
#[test]
fn board_cols_are_not_rows() {
let b = Board(vec![vec![None, Some(10)], vec![None, Some(10)], vec![None, Some(10)], vec![None, Some(10)]]);
assert!(!b.check_rows())
}
#[test]
fn part1_test() {
let t = Day04::init(INPUT.to_string());
let p1 = t.part1();
assert_eq!("4512", p1)
}
#[test]
fn part2_test() {
let t = Day04::init(INPUT.to_string());
let p2 = t.part2();
assert_eq!("1924", p2)
}
#[test]
fn part1_real() {
let f = read_to_string("./input/day04").expect("Could not load input");
let t = Day04::init(f);
let p1 = t.part1();
assert_eq!("8136", p1)
}
#[test]
fn part2_real() {
let f = read_to_string("./input/day04").expect("Could not load input");
let t = Day04::init(f);
let p2 = t.part2();
assert_eq!("12738", p2)
}
}

View file

@ -4,12 +4,14 @@ use clap::{App, Arg};
use crate::day01::Day01;
use crate::day02::Day02;
use crate::day03::Day03;
use crate::day04::Day04;
use crate::day::Day;
mod day;
mod day01;
mod day02;
mod day03;
mod day04;
fn load_input(day: &str) -> String {
read_to_string(format!("./input/day{}", day)).expect("Could not load input")
@ -45,7 +47,8 @@ fn main() {
.get_matches();
let days: Vec<Box<dyn Day>> = vec![Box::new(Day01::init(load_input("01"))), Box::new(Day02::init(load_input("02"))),
Box::new(Day03::init(load_input("03")))];
Box::new(Day03::init(load_input("03"))),
Box::new(Day04::init(load_input("04")))];
let _verbosity = matches.occurrences_of("v");
if matches.is_present("all") {