AoC2021/src/bin/day4.rs

119 lines
2.9 KiB
Rust

use std::error::Error;
use std::fs::File;
use std::io::{self, BufRead};
use std::vec::Vec;
struct Board {
numbers: Vec<Vec<i32>>,
marked: Vec<Vec<bool>>,
}
impl Board {
fn from_lines(lines: &mut impl Iterator<Item = String>) -> Option<Board> {
let mut numbers = Vec::new();
let mut marked = Vec::new();
while let Some(line) = lines.next() {
if line == "" {
break;
}
let row: Vec<i32> = line
.split(" ")
.filter(|n| n.len() != 0)
.map(|n| n.parse().unwrap())
.collect();
let mut markers: Vec<bool> = Vec::new();
markers.resize(row.len(), false);
numbers.push(row);
marked.push(markers);
}
if numbers.len() != 0 {
Some(Board { numbers, marked })
} else {
None
}
}
fn mark(&mut self, num: i32) {
for y in 0..self.numbers.len() {
for x in 0..self.numbers[y].len() {
if self.numbers[y][x] == num {
self.marked[y][x] = true;
}
}
}
}
fn has_won(&self) -> bool {
if self.marked.iter().any(|r| r.iter().all(|m| *m)) {
return true;
}
for x in 0..self.marked[0].len() {
let mut col = true;
for y in 0..self.marked.len() {
col = col && self.marked[y][x];
}
if col {
return true;
}
}
false
}
fn sum_unmarked(&self) -> i32 {
let mut sum = 0;
for y in 0..self.numbers.len() {
for x in 0..self.numbers[y].len() {
if !self.marked[y][x] {
sum += self.numbers[y][x];
}
}
}
sum
}
}
fn main() -> Result<(), Box<dyn Error>> {
let file = File::open("inputs/day4.txt")?;
let mut lines = io::BufReader::new(file).lines().map(|l| l.unwrap());
let numbers_drawn: Vec<i32> = lines
.next()
.unwrap()
.split(",")
.map(|n| n.parse().unwrap())
.collect();
lines.next();
let mut boards: Vec<Board> = Vec::new();
while let Some(board) = Board::from_lines(&mut lines) {
boards.push(board);
}
let mut points_first: Option<i32> = None;
let mut points_last = 0;
for number in numbers_drawn {
for board in boards.iter_mut() {
if !board.has_won() {
board.mark(number);
if board.has_won() {
points_last = board.sum_unmarked() * number;
if points_first.is_none() {
points_first = Some(points_last);
}
}
}
}
}
println!("Answer1: {}", points_first.unwrap());
println!("Answer2: {}", points_last);
Ok(())
}