1
0
Fork 0
aoc2021/src/main.rs

136 lines
3.2 KiB
Rust
Raw Normal View History

2021-12-01 05:51:55 +00:00
#![feature(test)]
extern crate test;
2021-12-03 05:38:45 +00:00
const INPUTS: [&'static str; 2] = [
2021-12-04 05:41:16 +00:00
include_str!("../inputs/day4.sample.txt"),
include_str!("../inputs/day4.txt"),
2021-12-03 05:38:45 +00:00
];
2021-12-02 05:14:07 +00:00
2021-12-04 07:25:54 +00:00
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)]
2021-12-04 05:41:16 +00:00
enum BoardEntry {
Entry(u64),
2021-12-04 07:25:54 +00:00
Called(u64),
2021-12-04 05:41:16 +00:00
Null,
2021-12-01 05:16:08 +00:00
}
2021-12-04 07:25:54 +00:00
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
2021-12-04 05:41:16 +00:00
struct Board {
board: [[BoardEntry; 5]; 5],
sum: u64,
2021-12-04 07:25:54 +00:00
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
}
2021-12-03 13:33:56 +00:00
}
2021-12-04 05:41:16 +00:00
fn cmds(input: &'static str) -> (Vec<u64>, Vec<Board>) {
let mut lines = input.split("\n\n").filter(|x| !x.is_empty());
let draws: Vec<u64> = lines
.next()
.unwrap()
.split(',')
.map(|x| x.parse::<u64>().unwrap())
.collect();
let mut boards = vec![];
for block in lines {
let mut bblock = Board {
board: [[BoardEntry::Null; 5]; 5],
sum: 0,
2021-12-04 07:25:54 +00:00
won: false,
2021-12-04 05:41:16 +00:00
};
for (i, line) in block.split('\n').enumerate() {
for (j, c) in line.split(' ').filter(|x| !x.is_empty()).enumerate() {
let num = c.parse::<u64>().unwrap();
bblock.board[i][j] = BoardEntry::Entry(num);
bblock.sum += num;
}
}
boards.push(bblock)
}
(draws, boards)
}
2021-12-03 13:33:56 +00:00
2021-12-04 05:41:16 +00:00
fn solution((draws, mut boards): (Vec<u64>, Vec<Board>)) -> u64 {
2021-12-04 07:25:54 +00:00
let mut answer = 0;
2021-12-03 13:33:56 +00:00
2021-12-04 07:25:54 +00:00
for draw in draws {
for board in boards.iter_mut() {
if board.won {
continue;
2021-12-04 05:41:16 +00:00
}
2021-12-04 07:25:54 +00:00
board.mark_draw(draw);
2021-12-04 05:41:16 +00:00
2021-12-04 07:25:54 +00:00
if board.is_winner() {
answer = board.sum * draw;
board.won = true;
2021-12-04 05:41:16 +00:00
}
2021-12-03 05:38:45 +00:00
}
}
2021-12-04 07:25:54 +00:00
answer
2021-12-01 05:51:55 +00:00
}
fn main() {
2021-12-04 05:41:16 +00:00
for input in INPUTS {
let input = cmds(input);
let result = solution(input);
println!("Result {}", result);
}
2021-12-01 05:16:08 +00:00
}
2021-12-01 05:51:55 +00:00
#[bench]
fn solution_bench(b: &mut test::Bencher) {
2021-12-04 07:25:54 +00:00
let input = cmds(INPUTS[1]);
2021-12-01 05:51:55 +00:00
b.iter(|| {
2021-12-04 07:25:54 +00:00
let result = solution(input.clone());
2021-12-04 05:41:16 +00:00
test::black_box(result);
2021-12-01 05:51:55 +00:00
})
}