110 lines
2.7 KiB
Rust
110 lines
2.7 KiB
Rust
use std::{
|
|
fs::File,
|
|
io::{BufRead, BufReader},
|
|
};
|
|
|
|
use regex::Regex;
|
|
|
|
const MAX_RED_CUBES: i32 = 12;
|
|
const MAX_GREEN_CUBES: i32 = 13;
|
|
const MAX_BLUE_CUBES: i32 = 14;
|
|
|
|
/// Returns ([red], [green], [blue])
|
|
fn get_subset_values(subset: String) -> (i32, i32, i32) {
|
|
let regexp = Regex::new(r"(\d* [a-z]{0,6})*").unwrap();
|
|
let mut strings = regexp
|
|
.find_iter(&subset)
|
|
.map(|m| m.as_str().trim())
|
|
.collect::<Vec<&str>>();
|
|
|
|
let red = strings
|
|
.iter()
|
|
.find(|s| s.ends_with("red"))
|
|
.unwrap_or(&"0 red")
|
|
.split(" ")
|
|
.nth(0)
|
|
.unwrap()
|
|
.parse::<i32>()
|
|
.unwrap_or(0);
|
|
let green = strings
|
|
.iter()
|
|
.find(|s| s.ends_with("green"))
|
|
.unwrap_or(&"0 green")
|
|
.split(" ")
|
|
.nth(0)
|
|
.unwrap()
|
|
.parse::<i32>()
|
|
.unwrap_or(0);
|
|
let blue = strings
|
|
.iter()
|
|
.find(|s| s.ends_with("blue"))
|
|
.unwrap_or(&"0 blue")
|
|
.split(" ")
|
|
.nth(0)
|
|
.unwrap()
|
|
.parse::<i32>()
|
|
.unwrap_or(0);
|
|
|
|
(red, green, blue)
|
|
}
|
|
|
|
/// Returns (Some([id]), [lowest cubes]) if OK
|
|
fn validate_game(game_results: String) -> (Option<i32>, (i32, i32, i32)) {
|
|
let regexp = Regex::new(r"Game (\d*): (.*)").unwrap();
|
|
let result = regexp.captures(&game_results).unwrap();
|
|
let id: i32 = result.get(1).unwrap().as_str().parse().unwrap();
|
|
let subsets: Vec<(i32, i32, i32)> = result
|
|
.get(2)
|
|
.unwrap()
|
|
.as_str()
|
|
.split(";")
|
|
.map(|s| get_subset_values(s.to_string()))
|
|
.collect();
|
|
|
|
let mut lowest = (0, 0, 0);
|
|
for subset in &subsets {
|
|
if subset.0 > lowest.0 {
|
|
lowest.0 = subset.0
|
|
}
|
|
if subset.1 > lowest.1 {
|
|
lowest.1 = subset.1
|
|
}
|
|
if subset.2 > lowest.2 {
|
|
lowest.2 = subset.2
|
|
}
|
|
}
|
|
|
|
for subset in &subsets {
|
|
if subset.0 > MAX_RED_CUBES {
|
|
return (None, lowest);
|
|
}
|
|
if subset.1 > MAX_GREEN_CUBES {
|
|
return (None, lowest);
|
|
}
|
|
if subset.2 > MAX_BLUE_CUBES {
|
|
return (None, lowest);
|
|
}
|
|
}
|
|
|
|
(Some(id), lowest)
|
|
}
|
|
|
|
fn main() {
|
|
let input_file = File::open("input.txt").unwrap();
|
|
let reader = BufReader::new(input_file);
|
|
|
|
let mut sum = 0;
|
|
let mut sum2 = 0;
|
|
for line in reader.lines() {
|
|
if let Ok(line) = line {
|
|
if let (id, lowest) = validate_game(line) {
|
|
if let Some(id) = id {
|
|
sum += id;
|
|
}
|
|
sum2 += lowest.0 * lowest.1 * lowest.2;
|
|
}
|
|
}
|
|
}
|
|
|
|
println!("ids: {sum}, powers: {sum2}");
|
|
}
|