summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/day16.rs88
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
+}