Skip to content

Instantly share code, notes, and snippets.

@tbarusseau
Created December 2, 2023 07:57
Show Gist options
  • Save tbarusseau/897f7d97a86ef67a95975ac3b4990ca3 to your computer and use it in GitHub Desktop.
Save tbarusseau/897f7d97a86ef67a95975ac3b4990ca3 to your computer and use it in GitHub Desktop.
struct Game {
game_index: i32,
subsets: Vec<(i32, i32, i32)>,
}
impl TryFrom<&str> for Game {
type Error = anyhow::Error;
fn try_from(value: &str) -> Result<Self, Self::Error> {
let mut subsets = vec![];
let colon_index = value.find(':').ok_or(anyhow!("colon not found"))?;
let game_index_slice = &value[5..colon_index];
let game_index: i32 = game_index_slice
.parse()
.map_err(|_| anyhow!("invalid game index"))?;
let rest_slice = &value[colon_index + 2..];
for subset in rest_slice.split("; ") {
let mut red_count = 0;
let mut blue_count = 0;
let mut green_count = 0;
for cube in subset.split(", ") {
let space_index = cube.find(' ').ok_or(anyhow!("no space"))?;
let count: i32 = cube[..space_index]
.parse()
.map_err(|_| anyhow!("invalid cube count"))?;
let color = &cube[space_index + 1..];
match color {
"red" => red_count += count,
"blue" => blue_count += count,
"green" => green_count += count,
_ => unreachable!(),
};
}
subsets.push((red_count, blue_count, green_count));
}
Ok(Game {
game_index,
subsets,
})
}
}
fn process_input(input: &str) -> Vec<Game> {
input
.trim_end()
.lines()
.flat_map(Game::try_from)
.collect_vec()
}
fn solve_part1(input: &str) -> Box<dyn std::fmt::Display> {
let input = process_input(input);
let red_limit = 12;
let blue_limit = 14;
let green_limit = 13;
let res = input.iter().fold(0, |acc, v| {
for subset in &v.subsets {
let (red, blue, green) = subset;
let is_impossible = *red > red_limit || *blue > blue_limit || *green > green_limit;
if is_impossible {
return acc;
}
}
acc + v.game_index
});
Box::new(res)
}
fn solve_part2(input: &str) -> Box<dyn std::fmt::Display> {
let input = process_input(input);
let res = input.iter().fold(0, |acc, v| {
let mut max_red = 0;
let mut max_blue = 0;
let mut max_green = 0;
for subset in &v.subsets {
let (red, blue, green) = subset;
max_red = max_red.max(*red);
max_blue = max_blue.max(*blue);
max_green = max_green.max(*green);
}
acc + max_red * max_blue * max_green
});
Box::new(res)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment