1
0
Fork 0

Added Day 4 Part 2

This commit is contained in:
Ishan Jain 2021-12-04 12:55:54 +05:30
parent e79094fc00
commit 4a731b3d7f
2 changed files with 62 additions and 57 deletions

View File

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

View File

@ -6,17 +6,62 @@ const INPUTS: [&'static str; 2] = [
include_str!("../inputs/day4.txt"), 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 { enum BoardEntry {
Entry(u64), Entry(u64),
CalledEntry(u64), Called(u64),
Null, Null,
} }
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
struct Board { struct Board {
board: [[BoardEntry; 5]; 5], board: [[BoardEntry; 5]; 5],
sum: u64, 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<u64>, Vec<Board>) { fn cmds(input: &'static str) -> (Vec<u64>, Vec<Board>) {
@ -35,6 +80,7 @@ fn cmds(input: &'static str) -> (Vec<u64>, Vec<Board>) {
let mut bblock = Board { let mut bblock = Board {
board: [[BoardEntry::Null; 5]; 5], board: [[BoardEntry::Null; 5]; 5],
sum: 0, sum: 0,
won: false,
}; };
for (i, line) in block.split('\n').enumerate() { for (i, line) in block.split('\n').enumerate() {
@ -52,63 +98,23 @@ fn cmds(input: &'static str) -> (Vec<u64>, Vec<Board>) {
} }
fn solution((draws, mut boards): (Vec<u64>, Vec<Board>)) -> u64 { fn solution((draws, mut boards): (Vec<u64>, Vec<Board>)) -> u64 {
let mut answer = 0;
for draw in draws { for draw in draws {
// Mark boards for board in boards.iter_mut() {
if board.won {
mark_entry(&mut boards, draw); continue;
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);
} }
} board.mark_draw(draw);
for j in 0..5 { if board.is_winner() {
let mut all_called = true; answer = board.sum * draw;
for i in 0..5 { board.won = true;
if !matches!(grid[i][j], BoardEntry::CalledEntry(_)) {
all_called = false;
break;
}
}
if all_called {
return Some(board);
} }
} }
} }
None answer
}
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);
}
}
}
}
}
} }
fn main() { fn main() {
@ -121,9 +127,9 @@ fn main() {
#[bench] #[bench]
fn solution_bench(b: &mut test::Bencher) { fn solution_bench(b: &mut test::Bencher) {
let input = cmds(INPUTS[1]);
b.iter(|| { b.iter(|| {
let input = cmds(INPUTS[1]); let result = solution(input.clone());
let result = solution(input);
test::black_box(result); test::black_box(result);
}) })
} }