Finished day 4
This commit is contained in:
parent
8359a6b308
commit
0fb63e65e9
@ -1,5 +1,6 @@
|
||||
struct Position {
|
||||
pub x: i64,
|
||||
#[allow(dead_code)]
|
||||
pub y: i64,
|
||||
pub z: i64,
|
||||
}
|
||||
|
135
src/day4.rs
Normal file
135
src/day4.rs
Normal 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);
|
||||
}
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user