From 4a731b3d7f5aadb8d4681f43a104791d4dfc912e Mon Sep 17 00:00:00 2001 From: Ishan Jain Date: Sat, 4 Dec 2021 12:55:54 +0530 Subject: [PATCH] Added Day 4 Part 2 --- inputs/day4.sample.txt | 3 +- src/main.rs | 116 ++++++++++++++++++++++------------------- 2 files changed, 62 insertions(+), 57 deletions(-) diff --git a/inputs/day4.sample.txt b/inputs/day4.sample.txt index f06791d..49d17bc 100644 --- a/inputs/day4.sample.txt +++ b/inputs/day4.sample.txt @@ -16,5 +16,4 @@ 10 16 15 9 19 18 8 23 26 20 22 11 13 6 5 - 2 0 12 3 7 - + 2 0 12 3 7 \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 95389b6..75a9ee3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,17 +6,62 @@ const INPUTS: [&'static str; 2] = [ include_str!("../inputs/day4.txt"), ]; -#[derive(Copy, Clone, Debug)] +const WINNING_COMBINATIONS: [[(usize, usize); 5]; 5] = [ + // Row wins + [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4)], + [(1, 0), (1, 1), (1, 2), (1, 3), (1, 4)], + [(2, 0), (2, 1), (2, 2), (2, 3), (2, 4)], + [(3, 0), (3, 1), (3, 2), (3, 3), (3, 4)], + [(4, 0), (4, 1), (4, 2), (4, 3), (4, 4)], +]; + +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] enum BoardEntry { Entry(u64), - CalledEntry(u64), + Called(u64), Null, } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] struct Board { board: [[BoardEntry; 5]; 5], sum: u64, + won: bool, +} + +impl Board { + fn mark_draw(&mut self, draw: u64) { + for row in self.board.iter_mut() { + for val in row.iter_mut() { + if let BoardEntry::Entry(v) = val { + if *v == draw { + self.sum -= *v; + *val = BoardEntry::Called(*v); + } + } + } + } + } + + fn is_winner(&self) -> bool { + for set in WINNING_COMBINATIONS.iter() { + let col_match = set + .iter() + .map(|&(x, y)| self.board[y][x]) + .all(|entry| matches!(entry, BoardEntry::Called(_))); + + let row_match = set + .iter() + .map(|&(x, y)| self.board[x][y]) + .all(|entry| matches!(entry, BoardEntry::Called(_))); + + if row_match || col_match { + return true; + } + } + + false + } } fn cmds(input: &'static str) -> (Vec, Vec) { @@ -35,6 +80,7 @@ fn cmds(input: &'static str) -> (Vec, Vec) { let mut bblock = Board { board: [[BoardEntry::Null; 5]; 5], sum: 0, + won: false, }; for (i, line) in block.split('\n').enumerate() { @@ -52,63 +98,23 @@ fn cmds(input: &'static str) -> (Vec, Vec) { } fn solution((draws, mut boards): (Vec, Vec)) -> u64 { + let mut answer = 0; + for draw in draws { - // Mark boards - - mark_entry(&mut boards, draw); - - if let Some(board) = check_winner(&boards) { - return board.sum * draw; - } - } - - 0 -} - -fn check_winner(boards: &[Board]) -> Option<&Board> { - for board in boards { - let grid = board.board; - - for i in 0..5 { - if grid[i] - .iter() - .all(|x| matches!(x, BoardEntry::CalledEntry(_))) - { - return Some(board); + for board in boards.iter_mut() { + if board.won { + continue; } - } + board.mark_draw(draw); - for j in 0..5 { - let mut all_called = true; - for i in 0..5 { - if !matches!(grid[i][j], BoardEntry::CalledEntry(_)) { - all_called = false; - break; - } - } - - if all_called { - return Some(board); + if board.is_winner() { + answer = board.sum * draw; + board.won = true; } } } - None -} - -fn mark_entry(boards: &mut [Board], called: u64) { - for board in boards { - for row in board.board.iter_mut() { - for col in row.iter_mut() { - if let BoardEntry::Entry(val) = col { - if *val == called { - board.sum -= *val; - *col = BoardEntry::CalledEntry(*val); - } - } - } - } - } + answer } fn main() { @@ -121,9 +127,9 @@ fn main() { #[bench] fn solution_bench(b: &mut test::Bencher) { + let input = cmds(INPUTS[1]); b.iter(|| { - let input = cmds(INPUTS[1]); - let result = solution(input); + let result = solution(input.clone()); test::black_box(result); }) }