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