Created
December 3, 2023 00:55
-
-
Save robert-king/889c89cdb8ce4dc69c1110cb6370d242 to your computer and use it in GitHub Desktop.
Advent of code day 2, over engineered
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// youtube walkthrough: https://youtu.be/mRW8Kbb1YlA?si=lBe4mNvfBYxe9ALl | |
const DATA: &str = "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green | |
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue | |
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red | |
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red | |
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green"; | |
#[derive(Debug)] | |
enum Color { | |
Red, | |
Blue, | |
Green, | |
} | |
impl Color { | |
fn new(name: &str) -> Result<Self, String> { | |
let color = match name { | |
"red" => Self::Red, | |
"blue" => Self::Blue, | |
"green" => Self::Green, | |
_ => { | |
return Err(format!("Unknown color {name}")) | |
} | |
}; | |
Ok(color) | |
} | |
fn is_ok(&self, count: i32) -> bool { | |
match self { | |
Color::Red => count <= 12, | |
Color::Blue => count <= 14, | |
Color::Green => count <= 13 | |
} | |
} | |
} | |
#[derive(Debug, Default)] | |
struct GameSet { | |
counts: Vec<(Color, i32)> | |
} | |
impl GameSet { | |
fn new(part: &str) -> Result<Self, String> { | |
let mut game_set = GameSet::default(); | |
for color_part in part.split(", ") { | |
let (count_str, color_str) = color_part.split_once(" ") | |
.ok_or_else(|| format!("Error parsing color_part {color_part}"))?; | |
game_set.counts.push( | |
( | |
Color::new(color_str)?, | |
count_str.parse().map_err(|_e| format!("Error parsing count_str {count_str}"))? | |
) | |
) | |
} | |
Ok(game_set) | |
} | |
fn is_ok(&self) -> bool { | |
return self.counts.iter().all( | |
|(color, count)| color.is_ok(*count) | |
) | |
} | |
} | |
#[derive(Debug)] | |
struct Game { | |
id: i32, | |
sets: Vec<GameSet>, | |
} | |
impl Game { | |
fn new(line: &str) -> Result<Self, String> { | |
let Some((game_part, set_parts)) = line.split_once(": ") else { | |
return Err(format!("Invalid line {line}")); | |
}; | |
let Some((_, game_id_str)) = game_part.split_once(" ") else { | |
return Err(format!("Invalid game part {game_part}")); | |
}; | |
let mut sets = vec![]; | |
for part in set_parts.split("; ") { | |
sets.push(GameSet::new(part)?); | |
} | |
let Some(id) = game_id_str.parse().ok() else { | |
return Err(format!("Error parsing num {game_id_str}")) | |
}; | |
Ok(Game { | |
id, | |
sets | |
}) | |
} | |
fn is_ok(&self) -> bool { | |
return self.sets.iter().all(|set| set.is_ok()) | |
} | |
} | |
fn main() { | |
let ans = DATA.lines() | |
.map(|line| Game::new(line).unwrap()) | |
.filter(|game| game.is_ok()) | |
.map(|valid_game| valid_game.id as i64) | |
.sum::<i64>(); | |
println!("{ans}"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment