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

@ -17,4 +17,3 @@
18 8 23 26 20
22 11 13 6 5
2 0 12 3 7

View File

@ -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<u64>, Vec<Board>) {
@ -35,6 +80,7 @@ fn cmds(input: &'static str) -> (Vec<u64>, Vec<Board>) {
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<u64>, Vec<Board>) {
}
fn solution((draws, mut boards): (Vec<u64>, Vec<Board>)) -> 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;
}
for board in boards.iter_mut() {
if board.won {
continue;
}
board.mark_draw(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 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) {
b.iter(|| {
let input = cmds(INPUTS[1]);
let result = solution(input);
b.iter(|| {
let result = solution(input.clone());
test::black_box(result);
})
}