Compare commits

...

2 Commits

Author SHA1 Message Date
bf6b034768 macro-ify matching days and parts 2021-12-04 12:36:18 -07:00
0fb63e65e9 Finished day 4 2021-12-04 12:08:50 -07:00
4 changed files with 157 additions and 20 deletions

View File

@ -1,7 +1,7 @@
use std::collections::VecDeque;
/// Increments count if each sample is larger than the previous.
pub fn day1_p1(input: String) {
pub fn part1(input: String) {
let mut prev = None;
let mut count: u32 = 0;
for line in input.lines() {
@ -22,7 +22,7 @@ pub fn day1_p1(input: String) {
/// 3-sample windowing average (no need to average, just use sum here)
///
/// We need to start comparing when we have all of
pub fn day1_p2(input: String) {
pub fn part2(input: String) {
let mut storage = VecDeque::with_capacity(5);
let mut count = 0;

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,24 +35,8 @@ fn main() {
let input = read_input(day).unwrap();
match day {
1 => match part {
1 => day1::day1_p1(input),
2 => day1::day1_p2(input),
_ => (),
},
2 => match part {
1 => day2::part1(input),
2 => day2::part2(input),
_ => (),
},
3 => match part {
1 => day3::part1(input),
2 => day3::part2(input),
_ => (),
},
_ => println!("Day {} not completed yet!", day),
}
// TODO macro-ify
match_days!(1, day1, 2, day2, 3, day3, 4, day4);
}
// TODO do the inputs ever change inside of a day?
@ -59,3 +44,19 @@ fn main() {
fn read_input(day: u8) -> std::io::Result<String> {
std::fs::read_to_string(format!("inputs/day{}", day))
}
#[macro_export]
macro_rules! match_days {
( $($num:expr, $day:ident),* ) => {
match day {
$(
$num => match part {
1 => $day::part1(input),
2 => $day::part2(input),
_ => println!("Part {} invalid!", part),
},
)*
_ => println!("Day {} not completed yet!", day),
}
};
}