diff --git a/input/04-test.txt b/input/04-test.txt new file mode 100644 index 0000000..669a51d --- /dev/null +++ b/input/04-test.txt @@ -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 diff --git a/input/04.txt b/input/04.txt new file mode 100644 index 0000000..5bab2b0 --- /dev/null +++ b/input/04.txt @@ -0,0 +1,601 @@ +1,76,38,96,62,41,27,33,4,2,94,15,89,25,66,14,30,0,71,21,48,44,87,73,60,50,77,45,29,18,5,99,65,16,93,95,37,3,52,32,46,80,98,63,92,24,35,55,12,81,51,17,70,78,61,91,54,8,72,40,74,68,75,67,39,64,10,53,9,31,6,7,47,42,90,20,19,36,22,43,58,28,79,86,57,49,83,84,97,11,85,26,69,23,59,82,88,34,56,13 + +85 23 65 78 93 +27 53 10 12 26 + 5 34 83 25 6 +56 40 73 29 54 +33 68 41 32 82 + + 8 31 14 70 91 +53 49 86 13 21 +66 28 76 78 93 +39 63 80 43 23 +56 25 60 67 72 + +67 78 36 64 14 +46 16 80 23 94 +22 47 51 65 57 +33 76 21 92 97 +31 95 54 27 20 + + 1 77 86 43 30 +28 88 7 5 60 +66 24 3 57 33 +38 23 59 84 44 +74 47 17 29 85 + +21 50 86 2 70 +85 19 22 93 25 +99 38 74 30 65 +81 0 47 78 63 +34 11 51 88 64 + +45 15 29 81 30 +75 21 88 91 49 +39 20 4 17 78 +10 12 38 11 7 +98 6 65 69 86 + +36 20 31 44 69 +30 65 55 88 64 +74 85 82 61 5 +57 17 90 43 54 +58 83 52 23 7 + +42 16 82 86 76 +60 26 27 59 55 + 7 53 22 78 5 +18 61 10 15 17 +28 46 14 87 77 + +21 43 15 47 61 +24 76 28 3 27 +19 62 69 82 93 +49 29 97 74 41 +92 36 37 99 40 + +31 4 3 62 51 +24 57 78 67 53 +13 5 76 38 55 +79 9 75 98 71 +65 1 39 18 47 + +59 4 38 95 99 +85 68 69 93 43 +83 57 48 42 15 +47 50 80 79 90 +56 87 78 64 25 + +21 37 14 67 95 +88 39 26 38 49 +89 83 54 77 96 +48 86 94 19 20 +43 41 8 74 58 + + 1 36 12 90 91 +63 21 98 82 66 +39 86 7 52 77 +80 81 44 33 58 +78 30 11 51 28 + +81 74 7 33 96 +75 60 87 47 91 +39 73 30 50 13 + 4 41 9 43 77 +34 82 72 48 12 + +93 63 74 25 57 +29 76 9 45 70 +98 77 71 16 41 +47 54 18 14 55 +31 89 67 87 83 + + 8 72 45 93 68 +74 26 69 94 65 +28 9 20 47 41 +46 54 21 56 22 +84 62 18 15 48 + +20 51 81 40 69 +71 10 13 93 75 +44 86 0 95 37 +99 39 76 80 66 +14 64 49 62 27 + +75 7 51 86 79 +43 30 61 39 16 +85 63 90 28 96 +88 78 72 31 73 +98 87 23 19 58 + +20 95 47 97 12 +92 25 68 87 91 +37 10 78 23 63 +74 93 58 39 5 +76 51 48 72 16 + +37 18 32 34 85 +22 31 98 42 19 +29 72 48 76 25 +47 1 21 7 53 +79 82 86 52 78 + +20 16 47 78 92 +88 15 71 67 2 + 5 52 90 70 9 +22 49 28 82 27 + 6 19 61 73 48 + +71 26 7 11 79 +52 30 47 1 31 +17 75 94 91 28 +81 98 23 55 21 +77 15 39 24 16 + + 5 75 44 88 65 +89 45 23 69 19 +41 61 67 52 54 +47 38 57 12 98 +62 70 26 87 53 + +50 4 65 77 25 + 6 21 5 27 92 +39 63 97 75 79 +60 34 87 26 74 +99 24 44 85 2 + +13 64 38 78 21 +74 17 83 57 94 +25 39 69 53 4 +54 33 81 50 76 +42 75 19 77 26 + +63 31 70 19 39 +38 87 15 90 75 +61 98 6 29 86 +78 62 32 11 60 +55 97 13 73 82 + +51 63 68 84 36 +12 33 37 31 8 +18 41 34 74 23 +72 39 85 48 60 +24 19 29 88 0 + +46 51 17 23 13 +20 93 97 99 81 +57 47 33 84 44 +28 96 2 43 56 +68 36 62 15 5 + +81 99 5 30 10 +38 62 57 8 37 + 7 86 98 3 54 +46 82 96 15 72 +83 1 75 25 50 + +47 57 11 61 27 +53 10 31 91 98 +76 85 55 38 23 + 6 81 67 71 70 +35 29 17 50 56 + +24 65 15 1 89 +45 60 97 23 14 +84 56 58 5 54 + 3 72 51 46 79 +67 70 78 34 77 + +38 11 54 23 2 +33 14 10 96 63 +43 5 36 20 30 +70 53 66 71 9 +91 90 21 7 88 + +94 44 4 86 26 +39 70 54 50 30 +55 40 12 72 71 +68 7 66 47 91 +31 24 13 1 96 + +79 14 40 87 68 +16 32 53 46 98 +38 95 21 89 69 +62 60 19 81 33 +70 52 28 83 0 + +62 42 38 48 64 +61 79 78 97 98 +89 7 3 29 68 +92 76 14 67 1 +41 99 72 47 60 + + 5 75 18 42 33 +72 61 36 31 29 +19 58 1 34 94 +54 84 92 99 38 +76 68 79 53 37 + +14 91 37 5 98 +68 29 34 76 43 +75 0 67 33 69 +81 47 58 30 93 +88 92 42 77 54 + +64 24 28 54 53 +72 68 3 73 4 +83 6 59 66 94 +87 80 55 20 16 +13 82 74 31 70 + +63 92 71 0 83 +98 40 50 55 2 +88 5 85 30 23 +10 75 81 58 68 +51 31 14 89 1 + +67 93 94 54 53 +38 71 34 40 24 +31 63 30 99 75 + 4 57 86 19 70 +60 49 87 68 74 + +56 94 79 53 7 +24 12 19 6 99 +82 51 41 46 43 +17 49 52 78 55 +75 48 61 70 87 + +14 55 32 21 31 +88 83 23 44 4 + 1 77 45 90 85 +46 81 51 27 62 +60 24 29 18 0 + +95 92 91 27 26 +22 43 45 64 62 +83 23 25 85 94 +84 53 72 28 20 +75 60 52 18 73 + +95 41 7 21 32 +58 65 16 56 97 +68 25 91 83 24 +66 89 15 55 6 + 2 30 84 10 90 + +58 86 44 19 74 +57 89 17 6 83 +77 35 60 32 13 +97 63 62 28 76 +55 31 11 0 52 + +33 39 59 42 45 +61 50 92 9 79 +15 0 28 5 72 +91 24 21 29 87 +86 76 43 31 93 + +63 11 86 45 85 +96 74 66 93 32 +95 30 99 23 18 +69 97 48 15 1 +42 87 47 83 80 + +93 5 40 64 2 +44 51 15 54 83 +69 77 90 58 11 + 0 48 43 30 55 +25 72 38 73 52 + +89 58 71 68 15 +23 65 9 36 74 +21 29 42 79 98 +55 47 33 39 28 +16 75 91 69 57 + +13 79 12 71 2 +60 94 99 43 82 +84 89 29 91 87 +74 80 25 32 21 +70 14 68 92 11 + +78 1 16 51 87 +58 94 59 15 43 +79 41 50 47 39 +53 37 9 28 72 +34 63 89 35 18 + +31 67 70 42 43 +60 2 89 49 22 +56 17 81 24 74 +20 65 1 96 51 +68 7 0 38 25 + +59 14 29 53 19 + 9 2 11 33 44 +81 6 10 47 58 +20 34 62 55 40 +71 38 69 45 78 + +59 36 70 42 21 + 3 16 49 79 98 +74 25 8 84 19 +61 80 47 65 64 +91 62 52 9 40 + + 1 85 63 7 2 + 0 20 61 26 77 +99 37 74 42 76 +25 94 19 78 60 +79 72 95 22 11 + +51 21 79 76 32 +55 23 69 19 61 +71 54 94 47 92 + 5 64 6 68 16 +91 81 9 99 30 + +61 69 82 86 68 +66 81 28 38 36 +26 29 31 11 8 +72 51 12 95 63 +18 30 88 17 32 + +34 8 14 42 67 +66 79 65 20 52 +37 87 74 24 3 +59 54 21 32 89 +31 4 62 76 30 + +11 93 8 92 55 +38 72 99 3 83 +12 75 0 41 46 +17 25 5 39 48 +14 18 86 29 84 + + 6 20 41 51 48 + 5 67 30 24 47 + 3 8 92 22 39 + 4 56 36 31 75 + 2 45 85 81 96 + +47 43 72 22 3 +19 87 53 12 60 +29 40 56 68 18 +66 97 70 33 39 +85 37 0 90 98 + +61 35 81 84 94 +11 1 58 45 77 + 6 99 67 36 43 + 5 7 0 87 80 +44 78 39 70 20 + +58 34 49 29 75 +17 15 28 23 84 +59 25 92 48 0 +20 81 47 3 71 +68 60 5 22 87 + +90 32 41 39 6 +36 78 67 24 50 +55 72 52 75 44 +87 15 92 31 58 +83 89 68 19 43 + +99 44 53 68 25 +71 67 16 19 36 +35 58 14 86 48 +88 18 61 24 23 +87 9 91 37 15 + +37 5 63 68 28 +41 50 76 99 64 +34 92 78 94 71 +11 96 97 42 58 +33 45 0 93 48 + +33 68 9 12 81 +60 98 28 8 99 +14 17 6 82 15 +57 69 43 38 29 +47 84 76 22 18 + +79 70 92 38 47 +12 82 98 46 0 +76 15 53 59 97 +18 52 49 29 96 +44 64 68 89 24 + +95 14 17 27 42 +55 43 57 29 25 +34 73 86 50 16 +69 37 75 63 39 +78 79 3 4 30 + +27 31 15 92 46 +36 23 72 40 50 +51 99 55 89 21 +12 70 84 63 85 +78 88 77 75 0 + +15 67 40 39 28 + 9 79 22 52 75 +96 65 86 98 14 +97 87 44 84 68 +36 26 89 43 27 + +79 59 48 27 36 +85 92 93 76 24 + 2 25 7 42 90 +23 29 74 35 86 +58 60 31 75 57 + +10 43 83 75 8 +88 12 38 30 9 +60 67 59 76 6 +55 45 74 34 25 +97 49 65 96 69 + +59 86 15 3 19 +89 4 74 61 23 +52 98 8 79 39 +95 17 22 14 51 +50 18 94 30 84 + +19 63 58 72 67 +35 93 29 91 0 +39 26 43 84 21 +70 42 2 53 12 +59 99 8 1 86 + +23 86 34 22 65 +71 10 16 50 91 +66 89 49 81 43 +40 7 26 75 61 +62 59 2 46 95 + +24 21 0 49 25 +92 42 48 12 7 +81 93 59 68 3 +14 23 63 39 29 +35 43 6 44 89 + +67 74 95 34 10 +39 90 59 44 51 +17 16 97 24 62 +20 54 76 63 88 +87 66 14 78 82 + +96 86 67 59 79 +66 3 30 77 71 + 2 91 99 82 31 +48 65 75 98 53 +63 54 64 76 1 + +85 96 40 98 24 +16 20 10 23 17 +79 59 53 42 65 +67 2 5 80 75 +62 38 19 74 73 + +43 10 79 92 8 +52 36 4 5 67 +56 29 33 24 97 +85 17 53 75 65 +62 64 1 21 83 + +93 92 79 17 12 +40 88 6 82 34 +90 96 53 25 43 +14 62 54 10 39 +49 68 41 16 44 + +67 99 24 58 76 +43 53 59 54 51 +47 6 61 8 2 +80 68 90 14 4 +29 46 94 89 50 + +14 45 19 33 43 + 6 55 4 31 80 +51 2 69 68 61 +71 70 79 91 93 +66 18 54 13 87 + + 8 45 61 54 30 +85 16 19 82 37 +56 39 11 47 4 +74 70 10 60 91 +21 63 95 53 72 + +71 21 63 86 27 +53 52 40 23 81 + 2 47 92 68 15 +46 45 31 8 1 +34 80 37 11 69 + +96 0 15 90 66 +65 43 92 83 18 + 3 47 19 8 32 +71 26 42 34 28 +62 99 55 5 12 + +37 99 30 21 3 +63 18 68 47 27 +57 0 65 85 20 + 7 58 40 92 43 +15 19 5 4 53 + +46 16 45 95 68 + 6 44 31 47 73 +84 82 71 75 94 +26 25 17 32 49 +18 96 13 58 9 + +71 36 13 68 10 +84 7 60 79 41 + 1 83 43 81 97 +90 53 80 19 38 +48 25 32 42 29 + +37 68 86 44 78 +87 67 77 70 60 +45 34 27 15 47 +12 21 13 55 26 +81 41 63 40 74 + +24 50 93 94 57 +99 4 56 5 28 +42 31 22 6 76 +90 89 16 49 59 + 9 7 43 71 54 + +69 75 94 38 46 +52 64 50 72 42 +76 63 13 60 10 +99 80 43 33 17 +25 31 4 89 22 + +88 57 22 66 34 +85 16 87 95 59 +73 2 46 5 29 +25 69 53 6 14 +96 77 19 91 43 + +46 99 52 47 76 +89 53 24 13 59 +45 5 1 30 19 +68 25 22 10 73 +42 27 31 0 94 + +42 44 98 89 87 +65 10 80 56 41 + 3 35 95 48 43 +85 97 83 12 94 +50 38 93 47 17 + +16 73 18 81 89 + 6 48 54 93 19 +35 52 88 49 31 +43 79 83 14 28 +50 62 98 26 22 + +38 47 7 20 35 +45 76 63 96 24 +98 53 2 87 80 +83 86 92 48 1 +73 60 26 94 6 + +80 50 29 53 92 +66 90 79 98 46 +40 21 58 38 60 +35 13 72 28 6 +48 76 51 96 12 + +79 80 24 37 51 +86 70 1 22 71 +52 69 10 83 13 +12 40 3 0 30 +46 50 48 76 5 diff --git a/src/bin/04.rs b/src/bin/04.rs new file mode 100644 index 0000000..719dd34 --- /dev/null +++ b/src/bin/04.rs @@ -0,0 +1,147 @@ +use std::fmt::Display; + +fn main() { + println!("First score: {}\n", part1()); + println!("Second score: {}", part2()); +} + +fn part1() -> u32 { + let (mut boards, rng) = input(); + + for n in rng { + for board in &mut boards { + board.mark(n); + if board.wins() { + println!("{}", board); + return board.score(n); + } + } + } + + 0 +} + +fn part2() -> u32 { + let (mut boards, mut rng) = input(); + + let mut last_n = 0; + while boards.len() > 1 { + last_n = rng.next().unwrap(); + for board in &mut boards { + board.mark(last_n); + } + boards.retain(|b| !b.wins()); + } + + // Only one board remains, play until it wins + let board = &mut boards[0]; + while !board.wins() { + last_n = rng.next().unwrap(); + board.mark(last_n); + } + println!("{}", board); + + board.score(last_n) +} + +#[derive(Debug)] +struct Board { + nums: [u32; 25], + marked: [bool; 25], +} + +impl Board { + fn mark(&mut self, n: u32) { + for i in 0..25 { + if self.nums[i] == n { + self.marked[i] = true; + } + } + } + + fn score(&self, last_n: u32) -> u32 { + let sum: u32 = self + .nums + .iter() + .zip(self.marked.iter()) + .filter(|(_, &marked)| !marked) + .map(|(n, _)| n) + .sum(); + sum * last_n + } + + fn wins(&self) -> bool { + // Check rows + for row in 0..5 { + let mut win = true; + for col in 0..5 { + if !self.marked[row * 5 + col] { + win = false; + break; + } + } + if win { + return true; + } + } + // Check cols + for col in 0..5 { + let mut win = true; + for row in 0..5 { + if !self.marked[row * 5 + col] { + win = false; + break; + } + } + if win { + return true; + } + } + false + } +} + +impl Display for Board { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for row in 0..5 { + for col in 0..5 { + let idx = row * 5 + col; + write!( + f, + "{}{:02} ", + if self.marked[idx] { "*" } else { " " }, + self.nums[idx] + )?; + } + writeln!(f)?; + } + + Ok(()) + } +} + +// Return a list of boards and an rng +fn input() -> (Vec, impl Iterator) { + let mut lines = include_str!("../../input/04.txt").lines(); + + let rng = lines.next().unwrap().split(',').map(|n| n.parse().unwrap()); + + let lines: Vec<_> = lines.collect(); + + let mut boards = Vec::new(); + + // Chunks have one empty line and five board lines + for board in lines.chunks_exact(6) { + let b: Vec = board + .iter() + .flat_map(|l| l.split_ascii_whitespace()) + .map(|n| n.parse().unwrap()) + .collect(); + boards.push(Board { + nums: b.try_into().unwrap(), + marked: [false; 25], + }) + } + + (boards, rng) +}