use std::fs::File; use std::io::{BufRead, BufReader, Lines}; use lazy_regex::{lazy_regex, Lazy}; use regex::Regex; // --- Day 2: Cube Conundrum --- // You're launched high into the atmosphere! The apex of your trajectory just barely // reaches the surface of a large island floating in the sky. You gently land in a // fluffy pile of leaves. It's quite cold, but you don't see much snow. An Elf runs over // to greet you. // The Elf explains that you've arrived at Snow Island and apologizes for the lack of // snow. He'll be happy to explain the situation, but it's a bit of a walk, so you have // some time. They don't get many visitors up here; would you like to play a game in the // meantime? // As you walk, the Elf shows you a small bag and some cubes which are either red, // green, or blue. Each time you play this game, he will hide a secret number of cubes // of each color in the bag, and your goal is to figure out information about the number // of cubes. // To get information, once a bag has been loaded with cubes, the Elf will reach into // the bag, grab a handful of random cubes, show them to you, and then put them back in // the bag. He'll do this a few times per game. // You play several games and record the information from each game (your puzzle input). // Each game is listed with its ID number (like the 11 in Game 11: ...) followed by a // semicolon-separated list of subsets of cubes that were revealed from the bag (like 3 // red, 5 green, 4 blue). // For example, the record of a few games might look like this: // 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 // In game 1, three sets of cubes are revealed from the bag (and then put back again). // The first set is 3 blue cubes and 4 red cubes; the second set is 1 red cube, 2 green // cubes, and 6 blue cubes; the third set is only 2 green cubes. // BOILERPLATE type InputIter = Lines>; fn get_input() -> InputIter { let f = File::open("input").unwrap(); let br = BufReader::new(f); br.lines() } fn main() { println!("Problem 1 solution: {}", problem1(get_input())); println!("Problem 2 solution: {}", problem2(get_input())); } // PARSING struct CubeCount { blue: u64, red: u64, green: u64, } impl Default for CubeCount { fn default() -> Self { Self { blue: 0, red: 0, green: 0, } } } impl From<&str> for CubeCount { fn from(s: &str) -> Self { let mut result = Self::default(); let counts = s.split(", "); for count in counts { let (n, color) = count.split_once(' ').unwrap(); match color { "blue" => result.blue = n.parse().unwrap(), "red" => result.red = n.parse().unwrap(), "green" => result.green = n.parse().unwrap(), _ => panic!("bad colour {}", color), } } result } } pub static GAME_ID_REGEX: Lazy = lazy_regex!(r"^Game ([0-9]+)"); struct GameResult { id: u64, results: Vec, } impl From<&str> for GameResult { fn from(s: &str) -> Self { let mut results = Vec::new(); let (s_id, rest) = s.split_once(": ").unwrap(); let id: u64 = GAME_ID_REGEX .captures(s_id) .unwrap() .get(1) .unwrap() .as_str() .parse() .unwrap(); let s_results = rest.split("; "); for s_result in s_results { results.push(CubeCount::from(s_result)); } GameResult { id, results } } } // PROBLEM 1 solution // The Elf would first like to know which games would have been possible if the bag // contained only 12 red cubes, 13 green cubes, and 14 blue cubes? // In the example above, games 1, 2, and 5 would have been possible if the bag had been // loaded with that configuration. However, game 3 would have been impossible because at // one point the Elf showed you 20 red cubes at once; similarly, game 4 would also have // been impossible because the Elf showed you 15 blue cubes at once. If you add up the // IDs of the games that would have been possible, you get 8. // Determine which games would have been possible if the bag had been loaded with only // 12 red cubes, 13 green cubes, and 14 blue cubes. What is the sum of the IDs of those // games? // possible criteria: 12 red cubes, 13 green cubes, and 14 blue cubes const PROBLEM1_MINIMUM: CubeCount = CubeCount { red: 12, green: 13, blue: 14, }; fn problem1_result_possible(game: &GameResult) -> bool { !game.results.iter().any(|result| { result.red > PROBLEM1_MINIMUM.red || result.green > PROBLEM1_MINIMUM.green || result.blue > PROBLEM1_MINIMUM.blue }) } fn problem1(input: InputIter) -> u64 { let mut n = 0u64; for line in input { let game_result = GameResult::from(line.unwrap().as_str()); if problem1_result_possible(&game_result) { n += game_result.id; } } n } // PROBLEM 2 solution fn problem2(input: InputIter) -> u64 { 0 }