diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/bin/day16.rs | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/bin/day16.rs b/src/bin/day16.rs new file mode 100644 index 0000000..48295ce --- /dev/null +++ b/src/bin/day16.rs @@ -0,0 +1,88 @@ +use std::collections::HashMap; +use regex::Regex; + +fn main() { + let input = advent::read_lines(16); + let search = HashMap::from([ + ("children", 3), + ("cats", 7), + ("samoyeds", 2), + ("pomeranians", 3), + ("akitas", 0), + ("vizslas", 0), + ("goldfish", 5), + ("trees", 3), + ("cars", 2), + ("perfumes", 1), + ]); + println!("16a: {}", find_aunt(&input, &search, false)); + println!("16b: {}", find_aunt(&input, &search, true)); +} + +struct Aunt { + name: u16, + attributes: HashMap<String, u8>, +} + +impl Aunt { + fn new(input: &str) -> Aunt { + let re = Regex::new(r"([a-z]+): ([0-9]+)").unwrap(); + let re_aunt = Regex::new(r"^Sue ([0-9]+):").unwrap(); + + let name = re_aunt.captures(input).unwrap()[1].parse::<u16>().unwrap(); + + let mut aunt = Aunt { + name, + attributes: HashMap::new(), + }; + + for cap in re.captures_iter(input) { + let attribute = cap[1].to_string(); + let amount = cap[2].parse::<u8>().unwrap(); + aunt.attributes.insert(attribute, amount); + } + + aunt + } + + fn has_attributes(&self, attributes: &HashMap<&str, u8>, outdated: bool) -> bool { + if outdated { + self.has_attributes_v2(attributes) + } else { + self.has_attributes_v1(attributes) + } + } + + fn has_attributes_v1(&self, attributes: &HashMap<&str, u8>) -> bool { + for (attr, val) in attributes { + if let Some(myval) = self.attributes.get(*attr) { + if myval != val { + /* found non-matching attribute */ + return false; + } + } + } + true + } + + fn has_attributes_v2(&self, attributes: &HashMap<&str, u8>) -> bool { + for (attr, val) in attributes { + if let Some(myval) = self.attributes.get(*attr) { + match attr { + x if ["cats", "trees"].contains(x) => if myval <= val { return false; }, + x if ["pomeranians", "goldfish"].contains(x) => if myval >= val { return false; }, + _ => if myval != val { return false; } + } + } + } + true + } +} + +fn find_aunt(input: &[String], search: &HashMap<&str, u8>, outdated: bool) -> u16 { + input.iter() + .map(|x| Aunt::new(x)) + .find(|x| x.has_attributes(search, outdated)) + .unwrap() + .name +} |
