|
@@ -21,12 +21,14 @@ fn read_lines(filename: &str) -> Vec<String> {
|
|
|
|
|
|
|
|
result
|
|
result
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
#[derive(Clone)]
|
|
#[derive(Clone)]
|
|
|
struct Reveal {
|
|
struct Reveal {
|
|
|
red: i32,
|
|
red: i32,
|
|
|
green: i32,
|
|
green: i32,
|
|
|
blue: i32,
|
|
blue: i32,
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
#[derive(Clone)]
|
|
#[derive(Clone)]
|
|
|
struct Game {
|
|
struct Game {
|
|
|
id: i32,
|
|
id: i32,
|
|
@@ -124,6 +126,50 @@ fn sum_game_ids(games: Vec<Game>) -> i32 {
|
|
|
s
|
|
s
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+fn min_cubes_in_game(game: Game) -> (i32, i32, i32) {
|
|
|
|
|
+ let mut min_red: i32 = i32::default();
|
|
|
|
|
+ let mut min_green: i32 = i32::default();
|
|
|
|
|
+ let mut min_blue: i32 = i32::default();
|
|
|
|
|
+ for reveal in game.reveals {
|
|
|
|
|
+ if min_red == i32::default() {
|
|
|
|
|
+ min_red = reveal.red;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if reveal.red >= min_red {
|
|
|
|
|
+ min_red = reveal.red;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if min_green == i32::default() {
|
|
|
|
|
+ min_green = reveal.green;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if reveal.green >= min_green {
|
|
|
|
|
+ min_green = reveal.green;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if min_blue == i32::default() {
|
|
|
|
|
+ min_blue = reveal.blue;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if reveal.blue >= min_blue {
|
|
|
|
|
+ min_blue = reveal.blue;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ (min_red, min_green, min_blue)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+fn calc_power_of_game(game: Game) -> i32 {
|
|
|
|
|
+ let (min_red, min_green, min_blue) = min_cubes_in_game(game);
|
|
|
|
|
+ min_red * min_green * min_blue
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+fn sum_powers(games: Vec<Game>) -> i32 {
|
|
|
|
|
+ let mut sum_powers: i32 = i32::default();
|
|
|
|
|
+ for game in games {
|
|
|
|
|
+ let power: i32 = calc_power_of_game(game);
|
|
|
|
|
+ sum_powers += power;
|
|
|
|
|
+ }
|
|
|
|
|
+ sum_powers
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
fn main() {
|
|
fn main() {
|
|
|
let lines: Vec<String> = read_lines("input.txt");
|
|
let lines: Vec<String> = read_lines("input.txt");
|
|
|
|
|
|
|
@@ -133,15 +179,20 @@ fn main() {
|
|
|
let max_green: i32 = 13;
|
|
let max_green: i32 = 13;
|
|
|
let max_blue: i32 = 14;
|
|
let max_blue: i32 = 14;
|
|
|
|
|
|
|
|
- let games_filtered: Vec<Game> = filter_games(games, max_red, max_green, max_blue);
|
|
|
|
|
|
|
+ let games_filtered: Vec<Game> = filter_games(games.clone(), max_red, max_green, max_blue);
|
|
|
let s: i32 = sum_game_ids(games_filtered);
|
|
let s: i32 = sum_game_ids(games_filtered);
|
|
|
println!("{}", s);
|
|
println!("{}", s);
|
|
|
|
|
+
|
|
|
|
|
+ // part 2
|
|
|
|
|
+ let sum_powers: i32 = sum_powers(games);
|
|
|
|
|
+ println!("{}", sum_powers);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
#[cfg(test)]
|
|
|
mod tests {
|
|
mod tests {
|
|
|
use crate::{
|
|
use crate::{
|
|
|
- filter_games, parse_game, parse_games, parse_reveal, parse_reveals, sum_game_ids, Game,
|
|
|
|
|
|
|
+ calc_power_of_game, filter_games, min_cubes_in_game, parse_game, parse_games, parse_reveal,
|
|
|
|
|
+ parse_reveals, sum_game_ids, sum_powers, Game,
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -318,4 +369,168 @@ mod tests {
|
|
|
// assert
|
|
// assert
|
|
|
assert_eq!(sum, 8);
|
|
assert_eq!(sum, 8);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ #[test]
|
|
|
|
|
+ fn test_min_cubes_in_game_1() {
|
|
|
|
|
+ // arrange
|
|
|
|
|
+ let g: Game = parse_game("Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green");
|
|
|
|
|
+
|
|
|
|
|
+ // act
|
|
|
|
|
+ let (min_red, min_green, min_blue) = min_cubes_in_game(g);
|
|
|
|
|
+
|
|
|
|
|
+ // assert
|
|
|
|
|
+ assert_eq!(min_red, 4);
|
|
|
|
|
+ assert_eq!(min_green, 2);
|
|
|
|
|
+ assert_eq!(min_blue, 6);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ #[test]
|
|
|
|
|
+ fn test_min_cubes_in_game_2() {
|
|
|
|
|
+ // arrange
|
|
|
|
|
+ let g: Game =
|
|
|
|
|
+ parse_game("Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue");
|
|
|
|
|
+
|
|
|
|
|
+ // act
|
|
|
|
|
+ let (min_red, min_green, min_blue) = min_cubes_in_game(g);
|
|
|
|
|
+
|
|
|
|
|
+ // assert
|
|
|
|
|
+ assert_eq!(min_red, 1);
|
|
|
|
|
+ assert_eq!(min_green, 3);
|
|
|
|
|
+ assert_eq!(min_blue, 4);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ #[test]
|
|
|
|
|
+ fn test_min_cubes_in_game_3() {
|
|
|
|
|
+ // arrange
|
|
|
|
|
+ let g: Game =
|
|
|
|
|
+ parse_game("Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red");
|
|
|
|
|
+
|
|
|
|
|
+ // act
|
|
|
|
|
+ let (min_red, min_green, min_blue) = min_cubes_in_game(g);
|
|
|
|
|
+
|
|
|
|
|
+ // assert
|
|
|
|
|
+ assert_eq!(min_red, 20);
|
|
|
|
|
+ assert_eq!(min_green, 13);
|
|
|
|
|
+ assert_eq!(min_blue, 6);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ #[test]
|
|
|
|
|
+ fn test_min_cubes_in_game_4() {
|
|
|
|
|
+ // arrange
|
|
|
|
|
+ let g: Game =
|
|
|
|
|
+ parse_game("Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red");
|
|
|
|
|
+
|
|
|
|
|
+ // act
|
|
|
|
|
+ let (min_red, min_green, min_blue) = min_cubes_in_game(g);
|
|
|
|
|
+
|
|
|
|
|
+ // assert
|
|
|
|
|
+ assert_eq!(min_red, 14);
|
|
|
|
|
+ assert_eq!(min_green, 3);
|
|
|
|
|
+ assert_eq!(min_blue, 15);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ #[test]
|
|
|
|
|
+ fn test_min_cubes_in_game_5() {
|
|
|
|
|
+ // arrang
|
|
|
|
|
+ let g: Game = parse_game("Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green");
|
|
|
|
|
+
|
|
|
|
|
+ // act
|
|
|
|
|
+ let (min_red, min_green, min_blue) = min_cubes_in_game(g);
|
|
|
|
|
+
|
|
|
|
|
+ // assert
|
|
|
|
|
+ assert_eq!(min_red, 6);
|
|
|
|
|
+ assert_eq!(min_green, 3);
|
|
|
|
|
+ assert_eq!(min_blue, 2);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ #[test]
|
|
|
|
|
+ fn test_calc_power_of_game_1() {
|
|
|
|
|
+ // arrange
|
|
|
|
|
+ let g: Game = parse_game("Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green");
|
|
|
|
|
+
|
|
|
|
|
+ // act
|
|
|
|
|
+ let power: i32 = calc_power_of_game(g);
|
|
|
|
|
+
|
|
|
|
|
+ // assert
|
|
|
|
|
+ assert_eq!(power, 48);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ #[test]
|
|
|
|
|
+ fn test_calc_power_of_game_2() {
|
|
|
|
|
+ // arrange
|
|
|
|
|
+ let g: Game =
|
|
|
|
|
+ parse_game("Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue");
|
|
|
|
|
+
|
|
|
|
|
+ // act
|
|
|
|
|
+ let power: i32 = calc_power_of_game(g);
|
|
|
|
|
+
|
|
|
|
|
+ // assert
|
|
|
|
|
+ assert_eq!(power, 12);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ #[test]
|
|
|
|
|
+ fn test_calc_power_of_game_3() {
|
|
|
|
|
+ // arrange
|
|
|
|
|
+ let g: Game =
|
|
|
|
|
+ parse_game("Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red");
|
|
|
|
|
+
|
|
|
|
|
+ // act
|
|
|
|
|
+ let power: i32 = calc_power_of_game(g);
|
|
|
|
|
+
|
|
|
|
|
+ // assert
|
|
|
|
|
+ assert_eq!(power, 1560);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ #[test]
|
|
|
|
|
+ fn test_calc_power_of_game_4() {
|
|
|
|
|
+ // arrange
|
|
|
|
|
+ let g: Game =
|
|
|
|
|
+ parse_game("Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red");
|
|
|
|
|
+
|
|
|
|
|
+ // act
|
|
|
|
|
+ let power: i32 = calc_power_of_game(g);
|
|
|
|
|
+
|
|
|
|
|
+ // assert
|
|
|
|
|
+ assert_eq!(power, 630);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ #[test]
|
|
|
|
|
+ fn test_calc_power_of_game_5() {
|
|
|
|
|
+ // arrange
|
|
|
|
|
+ let g: Game = parse_game("Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green");
|
|
|
|
|
+
|
|
|
|
|
+ // act
|
|
|
|
|
+ let power: i32 = calc_power_of_game(g);
|
|
|
|
|
+
|
|
|
|
|
+ // assert
|
|
|
|
|
+ assert_eq!(power, 36);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ #[test]
|
|
|
|
|
+ fn test_sum_powers() {
|
|
|
|
|
+ // arrange
|
|
|
|
|
+ let mut v: Vec<String> = Vec::new();
|
|
|
|
|
+ v.push(String::from(
|
|
|
|
|
+ "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green",
|
|
|
|
|
+ ));
|
|
|
|
|
+ v.push(String::from(
|
|
|
|
|
+ "Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue",
|
|
|
|
|
+ ));
|
|
|
|
|
+ v.push(String::from(
|
|
|
|
|
+ "Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red",
|
|
|
|
|
+ ));
|
|
|
|
|
+ v.push(String::from(
|
|
|
|
|
+ "Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red",
|
|
|
|
|
+ ));
|
|
|
|
|
+ v.push(String::from(
|
|
|
|
|
+ "Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green",
|
|
|
|
|
+ ));
|
|
|
|
|
+ let games: Vec<Game> = parse_games(v);
|
|
|
|
|
+
|
|
|
|
|
+ // act
|
|
|
|
|
+ let sum_powers: i32 = sum_powers(games);
|
|
|
|
|
+
|
|
|
|
|
+ // assert
|
|
|
|
|
+ assert_eq!(sum_powers, 2286);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|