add day 16 claude solution for part 1
This commit is contained in:
@@ -0,0 +1,72 @@
|
|||||||
|
use regex::Regex;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
/// One remembered Aunt Sue: her number and whatever compounds were noted.
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Sue {
|
||||||
|
number: u32,
|
||||||
|
properties: HashMap<String, u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parses the puzzle input into a list of `Sue`s.
|
||||||
|
///
|
||||||
|
/// Each line looks like `Sue 1: goldfish: 9, cars: 0, samoyeds: 9`. The
|
||||||
|
/// number of properties varies per line, so we pull out the `name: count`
|
||||||
|
/// pairs with a regex rather than assuming a fixed format.
|
||||||
|
fn parse_sues(input: &str) -> Vec<Sue> {
|
||||||
|
let line_re = Regex::new(r"^Sue (\d+): (.+)$").unwrap();
|
||||||
|
let property_re = Regex::new(r"(\w+): (\d+)").unwrap();
|
||||||
|
|
||||||
|
input
|
||||||
|
.lines()
|
||||||
|
.filter_map(|line| {
|
||||||
|
let caps = line_re.captures(line)?;
|
||||||
|
let number = caps[1].parse().unwrap();
|
||||||
|
let properties = property_re
|
||||||
|
.captures_iter(&caps[2])
|
||||||
|
.map(|prop| (prop[1].to_string(), prop[2].parse().unwrap()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Some(Sue { number, properties })
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The exact readings from the MFCSAM.
|
||||||
|
fn target_properties() -> HashMap<&'static str, u32> {
|
||||||
|
HashMap::from([
|
||||||
|
("children", 3),
|
||||||
|
("cats", 7),
|
||||||
|
("samoyeds", 2),
|
||||||
|
("pomeranians", 3),
|
||||||
|
("akitas", 0),
|
||||||
|
("vizslas", 0),
|
||||||
|
("goldfish", 5),
|
||||||
|
("trees", 3),
|
||||||
|
("cars", 2),
|
||||||
|
("perfumes", 1),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A Sue matches if every compound she's remembered for equals the target
|
||||||
|
/// reading exactly. Properties she isn't remembered for are simply skipped,
|
||||||
|
/// per the puzzle's "missing things aren't zero" rule.
|
||||||
|
fn matches_target(sue: &Sue, target: &HashMap<&str, u32>) -> bool {
|
||||||
|
sue.properties
|
||||||
|
.iter()
|
||||||
|
.all(|(name, &count)| target.get(name.as_str()) == Some(&count))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input = fs::read_to_string("input.txt").expect("failed to read input.txt");
|
||||||
|
let sues = parse_sues(&input);
|
||||||
|
let target = target_properties();
|
||||||
|
|
||||||
|
let real_sue = sues
|
||||||
|
.iter()
|
||||||
|
.find(|sue| matches_target(sue, &target))
|
||||||
|
.expect("no Sue matched the MFCSAM readings");
|
||||||
|
|
||||||
|
println!("Sue {} gave the gift.", real_sue.number);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user