AoC_2021/src/day04.rs

93 lines
2.9 KiB
Rust

use aoc_runner_derive::{aoc, aoc_generator};
#[derive(Debug,Clone)]
pub struct Data {
pub numbers: Vec<u8>,
pub boards: Vec<[[(u8,bool); 5]; 5]>,
}
#[aoc_generator(day04)]
pub fn input_generator(input: &str) -> Data {
let mut lines = input.lines();
let mut boards = vec![];
let numbers = lines
.next()
.unwrap()
.split(',')
.map(|s| s.parse())
.collect::<Result<Vec<u8>, _>>()
.unwrap();
let mut row = 0;
let mut board = [[(0u8,false); 5]; 5];
for line in lines {
if line.is_empty() {
continue;
}
let line = line
.split_ascii_whitespace()
.map(|s| s.parse())
.collect::<Result<Vec<u8>, _>>()
.unwrap();
line.iter().enumerate().for_each(|(i, v)| {
board[row][i] = (*v,false);
});
row = (row + 1) % 5;
if row == 0 {
boards.push(board);
board = [[(0u8,false); 5]; 5];
}
}
Data { numbers, boards }
}
#[aoc(day04, part1)]
pub fn solve_part1(input: &Data) -> usize {
let Data {numbers,mut boards} =input.clone();
for number in numbers.iter() {
for board in &mut boards {
for row in board.iter_mut() {
for (n,b) in row {
if n==number {
*b=true;
}
}
}
let win=(0..5).map(|v| {
[board[v][0],board[v][1],board[v][2],board[v][3],board[v][4]].iter().all(|v| v.1)|
[board[0][v],board[1][v],board[2][v],board[3][v],board[4][v]].iter().all(|v| v.1)
}).any(|v| v);
if win {
return board.iter().flatten().filter_map(|(v,b)| (!*b).then(|| *v as usize)).sum::<usize>()*(*number as usize)
}
}
}
unreachable!()
}
#[aoc(day04, part2)]
pub fn solve_part2(input: &Data) -> usize {
let mut ret=None;
let Data {numbers,mut boards} =input.clone();
let mut board_wins: Vec<bool> = vec![false;boards.len()];
for number in numbers.iter() {
for (board_n,board) in boards.iter_mut().enumerate() {
for row in board.iter_mut() {
for (n,b) in row {
if n==number {
*b=true;
}
}
}
let win=(0..5).map(|v| {
[board[v][0],board[v][1],board[v][2],board[v][3],board[v][4]].iter().all(|v| v.1)|
[board[0][v],board[1][v],board[2][v],board[3][v],board[4][v]].iter().all(|v| v.1)
}).any(|v| v);
if win && !board_wins[board_n] {
ret=Some(board.iter().flatten().filter(|(_,b)| !*b).map(|(v,_)| *v as usize).sum::<usize>()*(*number as usize));
board_wins[board_n]=true;
}
}
}
return ret.unwrap();
}