advent-of-code/2023/02/rust/main.rs

107 lines
2.4 KiB
Rust
Raw Normal View History

2023-12-04 20:08:43 +00:00
#![feature(test)]
use std::cmp;
extern crate test;
#[cfg(test)]
mod tests {
use super::*;
use test::Bencher;
#[bench]
fn bench_a(b: &mut Bencher) {
b.iter(|| part_a(INPUT));
}
#[bench]
fn bench_b(b: &mut Bencher) {
b.iter(|| part_b(INPUT));
}
}
const INPUT: &str = include_str!("../input.txt");
const TEST: &str = include_str!("../test.txt");
#[derive(Debug)]
struct Round {
red: usize,
blue: usize,
green: usize,
}
fn max_for_game(s: &str, calc: impl Fn(Round) -> usize) -> usize {
let max = s
.split(";")
.map(|round| {
// Max count
let mut r = Round {
blue: 0,
green: 0,
red: 0,
};
for pick in round.split(",") {
let parts: Vec<&str> = pick.trim().split(" ").collect();
let num: usize = parts[0].parse().unwrap();
match parts[1] {
"blue" => r.blue = num,
"green" => r.green = num,
"red" => r.red = num,
_ => panic!("Invalid color {}", parts[1]),
}
}
r
})
.reduce(|a, b| Round {
red: cmp::max(a.red, b.red),
blue: (cmp::max(a.blue, b.blue)),
green: (cmp::max(a.green, b.green)),
})
.unwrap();
calc(max)
}
fn parse_game_b(s: &str) -> usize {
let splitted: Vec<&str> = s.split(":").collect();
max_for_game(splitted[1], |x| x.blue * x.green * x.red)
}
fn part_a(input: &str) {
let result: usize = input
.trim()
.split("\n")
.map(|line| {
let splitted: Vec<&str> = line.split(":").collect();
max_for_game(splitted[1], |r| {
if r.red <= 12 && r.green <= 13 && r.blue <= 14 {
splitted[0].split_at(5).1.parse().unwrap()
} else {
0
}
})
})
.sum();
println!("{result}");
}
fn part_b(input: &str) {
let result: usize = input
.trim()
.split("\n")
.map(|line| {
return parse_game_b(line);
})
.sum();
println!("{result}");
}
fn main() {
println!("Part A:");
part_a(TEST);
part_a(INPUT);
println!("\nPart B:");
part_b(TEST);
part_b(INPUT);
}