Table of content

What is this :grey_question:

The rules of the game are explained in my original.

78th Challenge

Challenge

Not reading the prompt properly.. :) Here is a visualization of the puzzel by dalle3 of today’s challenge.

Solution :white_check_mark:

    fn main() {

        let game = Game {
            red: 12,
            blue: 14,
            green: 13,
        };

        let input = include_str!("input.txt");
        println!("Part 1: {}", part_1(input, &game));
        println!("Part 2: {}", part_2(input));
    }

    struct Game{
        red: usize,
        blue: usize,
        green: usize,
    }

    impl Game {
        fn from_str(input: &str) -> Game {
            let mut red = 0;
            let mut blue = 0;
            let mut green = 0;

            // Split the input string by comma to separate color-count pairs
            for pair in input.split(',') {
                let parts: Vec<&str> = pair.trim().split_whitespace().collect();
                if parts.len() == 2 {
                    let count = parts[0].parse().unwrap_or(0);
                    match parts[1] {
                        "red" => red = count,
                        "blue" => blue = count,
                        "green" => green = count,
                        _ => {}
                    }
                }
            }

            Game { red, blue, green }
        }
    }


    fn part_1(input: &str, game: &Game) -> usize {
        input.lines().filter_map(|line| {
            line.split(":").nth(1)
                .map(|games_str| games_str.split(";")
                    .map(Game::from_str)
                    .all(|game_instance| 
                        game_instance.red <= game.red && 
                        game_instance.blue <= game.blue && 
                        game_instance.green <= game.green
                    )
                )
        }).enumerate().filter(|(_, valid)| *valid).map(|(i, _)| i + 1).sum()
    }


    fn part_2(input: &str) -> usize {
        input.lines().filter_map(|line| {
            let x = line.split(":").nth(1)
                .map(|games_str| games_str.split(";")
                    .map(Game::from_str)
                    .fold(Game { red: 0, blue: 0, green: 0 }, |acc, game_instance| 
                        Game {
                            red: std::cmp::max(acc.red, game_instance.red),
                            blue: std::cmp::max(acc.blue, game_instance.blue),
                            green: std::cmp::max(acc.green, game_instance.green),
                        }
                    )
                ).unwrap();
            Some(x.red*x.blue*x.green)
        }).sum()
    }

    const TEST_INPUT: &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";

    #[cfg(test)]
    mod tests {
        use super::*;

        #[test]
        fn test_part_1() {
            let game = Game {
                red: 12,
                blue: 13,
                green: 14,
            };
            assert_eq!(part_1(TEST_INPUT,&game), 8);
        }

        #[test]
        fn test_part_2() {
            assert_eq!(part_2(TEST_INPUT),2286);
        }

    }