Compare commits
No commits in common. "bf6b034768602111116b613a1283b4f9c93eb91a" and "8359a6b308b59a65e2365f3999a9f3500297840a" have entirely different histories.
bf6b034768
...
8359a6b308
@ -1,7 +1,7 @@
|
|||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
/// Increments count if each sample is larger than the previous.
|
/// Increments count if each sample is larger than the previous.
|
||||||
pub fn part1(input: String) {
|
pub fn day1_p1(input: String) {
|
||||||
let mut prev = None;
|
let mut prev = None;
|
||||||
let mut count: u32 = 0;
|
let mut count: u32 = 0;
|
||||||
for line in input.lines() {
|
for line in input.lines() {
|
||||||
@ -22,7 +22,7 @@ pub fn part1(input: String) {
|
|||||||
/// 3-sample windowing average (no need to average, just use sum here)
|
/// 3-sample windowing average (no need to average, just use sum here)
|
||||||
///
|
///
|
||||||
/// We need to start comparing when we have all of
|
/// We need to start comparing when we have all of
|
||||||
pub fn part2(input: String) {
|
pub fn day1_p2(input: String) {
|
||||||
let mut storage = VecDeque::with_capacity(5);
|
let mut storage = VecDeque::with_capacity(5);
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
struct Position {
|
struct Position {
|
||||||
pub x: i64,
|
pub x: i64,
|
||||||
#[allow(dead_code)]
|
|
||||||
pub y: i64,
|
pub y: i64,
|
||||||
pub z: i64,
|
pub z: i64,
|
||||||
}
|
}
|
||||||
|
135
src/day4.rs
135
src/day4.rs
@ -1,135 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
37
src/main.rs
37
src/main.rs
@ -3,7 +3,6 @@ use clap::{App, Arg};
|
|||||||
mod day1;
|
mod day1;
|
||||||
mod day2;
|
mod day2;
|
||||||
mod day3;
|
mod day3;
|
||||||
mod day4;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let matches = App::new("AOC 2021 Code")
|
let matches = App::new("AOC 2021 Code")
|
||||||
@ -35,8 +34,24 @@ fn main() {
|
|||||||
|
|
||||||
let input = read_input(day).unwrap();
|
let input = read_input(day).unwrap();
|
||||||
|
|
||||||
// TODO macro-ify
|
match day {
|
||||||
match_days!(1, day1, 2, day2, 3, day3, 4, day4);
|
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 do the inputs ever change inside of a day?
|
// TODO do the inputs ever change inside of a day?
|
||||||
@ -44,19 +59,3 @@ fn main() {
|
|||||||
fn read_input(day: u8) -> std::io::Result<String> {
|
fn read_input(day: u8) -> std::io::Result<String> {
|
||||||
std::fs::read_to_string(format!("inputs/day{}", day))
|
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),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user