2023 - Day 02
This commit is contained in:
132
2023/src/bin/day02.rs
Normal file
132
2023/src/bin/day02.rs
Normal file
@@ -0,0 +1,132 @@
|
||||
#![feature(test)]
|
||||
use std::cmp::max;
|
||||
|
||||
use anyhow::Result;
|
||||
use aoc::Solver;
|
||||
|
||||
// -- Runners --
|
||||
fn main() -> Result<()> {
|
||||
Day::solve()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn part1_test1() -> Result<()> {
|
||||
Day::test(Day::part1, "test-1", 8)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part1_solution() -> Result<()> {
|
||||
Day::test(Day::part1, "input", 1931)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_test1() -> Result<()> {
|
||||
Day::test(Day::part2, "test-1", 2286)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_solution() -> Result<()> {
|
||||
Day::test(Day::part2, "input", 83105)
|
||||
}
|
||||
|
||||
// Benchmarks
|
||||
extern crate test;
|
||||
#[bench]
|
||||
#[ignore]
|
||||
fn part1_bench(b: &mut test::Bencher) {
|
||||
Day::benchmark(Day::part1, b)
|
||||
}
|
||||
#[bench]
|
||||
#[ignore]
|
||||
fn part2_bench(b: &mut test::Bencher) {
|
||||
Day::benchmark(Day::part2, b)
|
||||
}
|
||||
}
|
||||
|
||||
// -- Solution --
|
||||
pub struct Day;
|
||||
impl aoc::Solver for Day {
|
||||
type Output1 = usize;
|
||||
type Output2 = usize;
|
||||
|
||||
fn day() -> u8 {
|
||||
2
|
||||
}
|
||||
|
||||
fn part1(input: &str) -> Self::Output1 {
|
||||
let red = 12;
|
||||
let green = 13;
|
||||
let blue = 14;
|
||||
|
||||
input
|
||||
.lines()
|
||||
.filter_map(|line| {
|
||||
// Split the game id from the actual game played
|
||||
let (game, line) = line.split_once(": ").unwrap();
|
||||
|
||||
// Check if the game played by checking if all sets played are valid
|
||||
let valid = line.split("; ").all(|set| {
|
||||
// Check if each entry in the set is valid
|
||||
set.split(", ").all(|entry| {
|
||||
// Get the amount and the color of the cubes
|
||||
let (amount, color) = entry.split_once(' ').unwrap();
|
||||
let amount: usize = amount.parse().unwrap();
|
||||
|
||||
// Check if that amount of cubes is valid for the given color
|
||||
match color {
|
||||
"red" => amount <= red,
|
||||
"green" => amount <= green,
|
||||
"blue" => amount <= blue,
|
||||
_ => unreachable!("Input is invalid"),
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// If valid, get the id and add it to the sum
|
||||
if valid {
|
||||
let (_, id) = game.split_once(' ').unwrap();
|
||||
let id: usize = id.parse().unwrap();
|
||||
Some(id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn part2(input: &str) -> Self::Output2 {
|
||||
// The games do not need to be split into sets anymore for part 2
|
||||
// This replacement makes it easier to get every number + color pair without extra nesting
|
||||
let input = input.replace(';', ",");
|
||||
|
||||
input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
// Split the game id from the actual game played
|
||||
let (_, line) = line.split_once(": ").unwrap();
|
||||
|
||||
// Get the required minimum amount for each color
|
||||
let required = line.split(", ").fold((0, 0, 0), |acc, entry| {
|
||||
// Get the amount and the color of the cubes
|
||||
let (amount, color) = entry.split_once(' ').unwrap();
|
||||
let amount: usize = amount.parse().unwrap();
|
||||
|
||||
// Update the minimum amount require as neccesary.
|
||||
match color {
|
||||
"red" => (max(acc.0, amount), acc.1, acc.2),
|
||||
"green" => (acc.0, max(acc.1, amount), acc.2),
|
||||
"blue" => (acc.0, acc.1, max(acc.2, amount)),
|
||||
_ => unreachable!("Input is invalid"),
|
||||
}
|
||||
});
|
||||
|
||||
// Get the power of the set of cubes
|
||||
required.0 * required.1 * required.2
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user