Finished day 4

This commit is contained in:
David Lenfesty 2021-12-04 12:08:50 -07:00
parent 8359a6b308
commit 0fb63e65e9
3 changed files with 143 additions and 0 deletions

View File

@ -1,5 +1,6 @@
struct Position {
pub x: i64,
#[allow(dead_code)]
pub y: i64,
pub z: i64,
}

135
src/day4.rs Normal file
View File

@ -0,0 +1,135 @@
use std::convert::TryInto;
struct BingoBoard {
board: [[u8; 5]; 5],
marked: [[bool; 5]; 5],
bingo: bool,
}
impl BingoBoard {
fn new(board: [[u8; 5]; 5]) -> Self {
Self {
board,
marked: [[false; 5]; 5],
bingo: false,
}
}
/// Checks to see if bingo has been achieved.
///
/// Returns true if any row or column is fully marked. (Ignores diagonals)
fn check_bingo(&mut self) -> bool {
// Check rows
for row in self.marked {
if row.iter().all(|marked| *marked) {
self.bingo = true;
return true;
}
}
// Check columns
for i in 0..self.marked.len() {
if self.marked.iter().map(|row| row[i]).all(|marked| marked) {
self.bingo = true;
return true;
}
}
false
}
fn is_bingo(&self) -> bool {
self.bingo
}
/// Checks number for existance on board and marks off any instances of it.
fn check_number(&mut self, number: u8) {
for i in 0..self.board.len() {
for j in 0..self.board[i].len() {
if self.board[i][j] == number {
self.marked[i][j] = true;
}
}
}
}
// Scores board based on input number
fn score(&self, number: u8) -> usize {
let mut score = 0usize;
for i in 0..self.board.len() {
for j in 0..self.board[i].len() {
if !self.marked[i][j] {
score += self.board[i][j] as usize;
}
}
}
score * number as usize
}
}
fn parse_input(input: String) -> (Vec<u8>, Vec<BingoBoard>) {
let mut lines = input.lines();
let input: Vec<u8> = lines
.next()
.unwrap()
.split(',')
.map(|s| str::parse::<u8>(s).unwrap())
.collect();
// Keep building boards until we don't have any more lines to parse
let mut boards = Vec::<BingoBoard>::new();
while let Some(_) = lines.next() {
let mut board = [[0u8; 5]; 5];
for i in 0..board.len() {
let line: Vec<u8> = lines
.next()
.unwrap()
.split_whitespace()
.map(|s| str::parse::<u8>(s).unwrap())
.collect();
board[i] = line.try_into().unwrap();
}
boards.push(BingoBoard::new(board));
}
(input, boards)
}
pub fn part1(input: String) {
let (input, mut boards) = parse_input(input);
for call in input {
// Mark and check boards
// NOTE: making big assumption here that only one board wins
for board in &mut boards {
board.check_number(call);
if board.check_bingo() {
println!("Final score: {}", board.score(call));
return;
}
}
}
}
pub fn part2(input: String) {
let (input, mut boards) = parse_input(input);
let mut final_score = 0usize;
for call in input {
for board in &mut boards {
if !board.is_bingo() {
board.check_number(call);
if board.check_bingo() {
final_score = board.score(call);
}
}
}
}
println!("Last winner's score: {}", final_score);
}

View File

@ -3,6 +3,7 @@ use clap::{App, Arg};
mod day1;
mod day2;
mod day3;
mod day4;
fn main() {
let matches = App::new("AOC 2021 Code")
@ -34,6 +35,7 @@ fn main() {
let input = read_input(day).unwrap();
// TODO macro-ify
match day {
1 => match part {
1 => day1::day1_p1(input),
@ -50,6 +52,11 @@ fn main() {
2 => day3::part2(input),
_ => (),
},
4 => match part {
1 => day4::part1(input),
2 => day4::part2(input),
_ => (),
},
_ => println!("Day {} not completed yet!", day),
}
}