aboutsummaryrefslogtreecommitdiff
path: root/2023/day-02/src/bin/part2.rs
diff options
context:
space:
mode:
Diffstat (limited to '2023/day-02/src/bin/part2.rs')
-rw-r--r--2023/day-02/src/bin/part2.rs140
1 files changed, 140 insertions, 0 deletions
diff --git a/2023/day-02/src/bin/part2.rs b/2023/day-02/src/bin/part2.rs
new file mode 100644
index 0000000..b931ba1
--- /dev/null
+++ b/2023/day-02/src/bin/part2.rs
@@ -0,0 +1,140 @@
+
+#[derive(Debug)]
+struct GameSet {
+ red: u32,
+ green: u32,
+ blue: u32
+}
+
+fn normalize(x: u32) -> u32 {
+ if x == 0 {
+ 1
+ } else {
+ x
+ }
+}
+
+impl GameSet {
+ fn power(&self) -> u32 {
+ normalize(self.red) * normalize(self.green) * normalize(self.blue)
+ }
+}
+
+struct Game {
+ id: u32,
+ sets: Vec<GameSet>
+}
+
+impl Game {
+ fn min_gameset(&self) -> GameSet {
+ let mut red = 0;
+ let mut green = 0;
+ let mut blue = 0;
+
+ for gameset in self.sets.iter() {
+ if gameset.red > 0 {
+ red = u32::max(red, gameset.red);
+ }
+ if gameset.green > 0 {
+ green = u32::max(green, gameset.green);
+ }
+ if gameset.blue > 0 {
+ blue = u32::max(blue, gameset.blue);
+ }
+ }
+
+ GameSet {
+ red, green, blue
+ }
+ }
+}
+
+fn main() {
+ let input = include_str!("./input.txt");
+ let output: u32 = input
+ .lines()
+ .map(|line| {
+ process_line(line)
+ })
+ .map(|game| {
+ game.min_gameset().power()
+ })
+ .sum();
+ println!("Result {output}")
+}
+
+fn gameset_from_pairs(pairs: Vec<(&str, u32)>) -> GameSet {
+ let mut red: u32 = 0;
+ let mut green: u32 = 0;
+ let mut blue: u32 = 0;
+
+ for pair in pairs {
+ match pair {
+ ("red", x) => { red = x },
+ ("green", x) => { green = x },
+ ("blue", x) => { blue = x },
+ what => panic!("Unknown pair {:?}", what)
+ }
+ }
+
+ GameSet { red, green, blue }
+}
+
+/// Progrss a line
+fn process_line(string: &str) -> Game {
+ let game_split: Vec<&str> = string.splitn(2, ": ").collect();
+ // Get game Id from string "Game 1"
+ let game_id = game_split[0].split(" ").last().expect("Expected id").parse::<u32>().expect("Cant parse game id");
+ let sets: Vec<_> = game_split[1]
+ .split("; ")
+ .map(|set_line| {
+ set_line.split(", ").collect()
+ })
+ .map(|gameset: Vec<&str>| {
+ let pairs: Vec<(&str, u32)> = gameset.into_iter().map(|s| {
+ let split: Vec<&str> = s.split_whitespace().collect();
+ (split[1], split[0].parse::<u32>().expect("Cant parse"))
+ }).collect();
+ gameset_from_pairs(pairs)
+ })
+ .collect();
+ Game {
+ id: game_id,
+ sets
+ }
+}
+
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_process_simple() {
+ let game = process_line("Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green");
+ assert_eq!(game.id, 1);
+ }
+
+ #[test]
+ fn test_input() {
+ let input = "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";
+ let output: u32 = input
+ .lines()
+ .map(|line| {
+ process_line(line)
+ })
+ .map(|game| {
+ game.min_gameset()
+ })
+ .inspect(|power| { dbg!(power); })
+ .map(|gs| { gs.power() })
+
+ .sum();
+
+ assert_eq!(output, 2286);
+ }
+}