Added Day 4 Part 2
This commit is contained in:
parent
e79094fc00
commit
4a731b3d7f
|
@ -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
|
||||||
|
|
116
src/main.rs
116
src/main.rs
|
@ -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);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue