AoC21/src/day04.rs

122 lines
3.1 KiB
Rust

pub fn day4() {
// let input = r#"
// 7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
// 22 13 17 11 0
// 8 2 23 4 24
// 21 9 14 16 7
// 6 10 3 18 5
// 1 12 20 15 19
// 3 15 0 2 22
// 9 18 13 17 5
// 19 8 7 25 23
// 20 11 10 24 4
// 14 21 16 12 6
// 14 21 17 24 4
// 10 16 15 9 19
// 18 8 23 26 20
// 22 11 13 6 5
// 2 0 12 3 7
// "#
// .trim();
let input = include_str!("../input/day4.txt");
let mut parts = input.split("\n\n");
let drawn = parts
.next()
.unwrap()
.split(",")
.map(|s| s.parse::<i32>().unwrap());
let mut boards: Vec<Board> = parts.map(|b| b.into()).collect();
let mut found_p1_winner = false;
let mut in_progress_indices = (0..boards.len()).collect::<Vec<_>>();
'outer: for n in drawn {
for (i, b) in boards.iter_mut().enumerate() {
b.mark(n);
if b.is_winner() {
if !found_p1_winner {
found_p1_winner = true;
println!("p1: winning board index: {}", i);
println!("p1: winning board score: {}", b.score());
println!("p1: final score: {}", b.score() * n);
}
// boo, just let me remove an element
in_progress_indices.retain(|&it| it != i);
if in_progress_indices.len() == 0 {
println!("p2: last remaining board index: {}", i);
println!("p2: board score: {}", b.score());
println!("p2: final score: {}", b.score() * n);
break 'outer;
}
}
}
}
}
#[derive(Clone)]
struct Board {
numbers: [[i32; 5]; 5],
marked: Vec<(usize, usize)>,
}
impl Board {
fn mark(&mut self, n: i32) {
for x in 0..5 {
for y in 0..5 {
if self.numbers[x][y] == n {
self.marked.push((x, y));
}
}
}
}
fn is_winner(&self) -> bool {
for i in 0..5 {
let mut row = (0..5).map(|y| (i, y));
let mut col = (0..5).map(|x| (x, i));
if row.all(|pair| self.marked.contains(&pair))
|| col.all(|pair| self.marked.contains(&pair))
{
return true;
}
}
false
}
fn score(&self) -> i32 {
let mut sum = 0;
for x in 0..5 {
for y in 0..5 {
if !self.marked.contains(&(x, y)) {
sum += self.numbers[x][y];
}
}
}
sum
}
}
impl From<&str> for Board {
fn from(str: &str) -> Self {
let mut numbers = [[0; 5]; 5];
for (i, line) in str.lines().enumerate() {
let mut row = [0; 5];
for (j, num) in line.split_whitespace().enumerate() {
row[j] = num.parse().unwrap();
}
numbers[i] = row;
}
Self {
numbers,
marked: vec![],
}
}
}