trunk
Erin 2023-12-02 16:54:14 +01:00
parent 0483fa50ef
commit 2cf807f941
1 changed files with 80 additions and 0 deletions

80
src/bin/day02.rs Normal file
View File

@ -0,0 +1,80 @@
use color_eyre::{
eyre::{bail, ContextCompat},
Report, Result,
};
use std::io::stdin;
fn n_colour_pair(input: &str) -> Result<(u64, &str)> {
let (n, c) = input
.trim()
.split_once(' ')
.context("Invalid poll format; expected: <num> <colour>")?;
Ok((n.parse()?, c))
}
fn part1(id: u64, game: &str) -> Result<u64> {
let and_reducer = |acc, x| Ok(acc && x?);
Ok(game
.split(';')
.map(|game| -> Result<bool> {
game.split(',')
.map(|poll| -> Result<bool> {
let (count, colour) = n_colour_pair(poll)?;
Ok(match colour {
"red" if count <= 12 => true,
"green" if count <= 13 => true,
"blue" if count <= 14 => true,
"red" | "green" | "blue" => false,
c => {
bail!("Invalid colour: {c}, expected red, green or blue")
}
})
})
.try_fold(true, and_reducer)
})
.try_fold(true, and_reducer)?
.then_some(id)
.unwrap_or_default())
}
fn part2(_: u64, game: &str) -> Result<u64> {
game.split([',', ';'])
.try_fold([0; 3], |mut acc, seg| {
let (count, colour) = n_colour_pair(seg)?;
let i = match colour {
"red" => 0,
"green" => 1,
"blue" => 2,
c => bail!("Invalid colour: {c}, expected red, green or blue"),
};
acc[i] = acc[i].max(count);
Ok(acc)
})
.map(|arr| arr.iter().product())
}
fn main() -> Result<()> {
//let part = part1;
let part = part2;
Ok(println!(
"{}",
stdin()
.lines()
.map(|ln| {
ln.map_err(Report::from).and_then(|ln| {
let (id, game) = ln.split_once(':').context("Invalid ID")?;
let id: u64 = id
.strip_prefix("Game ")
.context("ID should start with \"Game \"")?
.parse()?;
part(id, game)
})
})
.try_fold::<_, _, Result<u64>>(0, |acc, x| Ok(acc + x?))?
))
}