summary refs log tree commit diff
path: root/14
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@gmail.com>2021-12-13 21:45:35 -0800
committerIrene Knapp <ireneista@gmail.com>2021-12-13 21:45:35 -0800
commit2a0faf3e3a421786d6295831d978c54d4e34a6e6 (patch)
tree084375f6f9584ce491363e47b0163ca52866c645 /14
parent9212ac0543ce2c8c6c5a93df841ac83c2dffd2d7 (diff)
14
Diffstat (limited to '14')
-rw-r--r--14/Cargo.toml11
-rw-r--r--14/input102
-rw-r--r--14/src/.main.rs.swobin0 -> 20480 bytes
-rw-r--r--14/src/main.rs237
-rw-r--r--14/tests/main.rs17
5 files changed, 367 insertions, 0 deletions
diff --git a/14/Cargo.toml b/14/Cargo.toml
new file mode 100644
index 0000000..58d7c98
--- /dev/null
+++ b/14/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "advent_14"
+version = "0.1.0"
+authors = ["Irene Knapp <ireneista@gmail.com>"]
+edition = "2018"
+
+[dependencies]
+advent_lib = { path = "../lib" }
+
+[dev-dependencies]
+assert_cmd = "0.10"
diff --git a/14/input b/14/input
new file mode 100644
index 0000000..ac9c0aa
--- /dev/null
+++ b/14/input
@@ -0,0 +1,102 @@
+BCHCKFFHSKPBSNVVKVSK
+
+OV -> V
+CO -> V
+CS -> O
+NP -> H
+HH -> P
+KO -> F
+VO -> B
+SP -> O
+CB -> N
+SB -> F
+CF -> S
+KS -> P
+OH -> H
+NN -> O
+SF -> K
+FH -> F
+VV -> B
+VH -> O
+BV -> V
+KF -> K
+CC -> F
+NF -> H
+VS -> O
+SK -> K
+HV -> O
+CK -> K
+VP -> F
+HP -> S
+CN -> K
+OB -> H
+NS -> F
+PS -> S
+KB -> S
+VF -> S
+FP -> H
+BB -> N
+HF -> V
+CH -> N
+BH -> F
+KK -> B
+OO -> N
+NO -> K
+BP -> K
+KH -> P
+KN -> P
+OF -> B
+VC -> F
+NK -> F
+ON -> O
+OC -> P
+VK -> O
+SH -> C
+NH -> C
+FB -> B
+FC -> K
+OP -> O
+PV -> V
+BN -> V
+PC -> K
+PK -> S
+FF -> C
+SV -> S
+HK -> H
+NB -> C
+OK -> C
+PH -> B
+SO -> O
+PP -> F
+KV -> V
+FO -> B
+FN -> H
+HN -> C
+VB -> K
+CV -> O
+BC -> C
+CP -> S
+FS -> S
+KP -> V
+BS -> V
+BK -> B
+PN -> C
+PF -> S
+HO -> V
+NC -> N
+SS -> N
+BO -> P
+BF -> N
+NV -> P
+PB -> K
+HB -> H
+VN -> H
+FV -> B
+FK -> K
+PO -> S
+SC -> S
+HS -> S
+KC -> F
+HC -> S
+OS -> K
+SN -> N
diff --git a/14/src/.main.rs.swo b/14/src/.main.rs.swo
new file mode 100644
index 0000000..dcf9781
--- /dev/null
+++ b/14/src/.main.rs.swo
Binary files differdiff --git a/14/src/main.rs b/14/src/main.rs
new file mode 100644
index 0000000..481b785
--- /dev/null
+++ b/14/src/main.rs
@@ -0,0 +1,237 @@
+use advent_lib::prelude::*;
+
+use std::collections::HashMap;
+
+
+fn main() -> Result<()> {
+  let mut args = std::env::args();
+  if args.len() != 2 {
+    eprintln!("Usage: advent input");
+  }
+  let _ = args.next();
+  let filename = args.next().unwrap();
+
+  let input = advent_lib::group_lines_by_blanks(
+    advent_lib::read_lines_file(&filename)?);
+
+  let template = input[0][0].clone();
+
+  let mut rules: HashMap<(char, char),char> = HashMap::new();
+  for line in &input[1]{
+    let words: Vec<&str> = line.split_whitespace().collect();
+    let lhs: Vec<char> = words[0].chars().collect();
+    let rhs: Vec<char> = words[2].chars().collect();
+    let left = lhs[0];
+    let right = lhs[1];
+    let inserted = rhs[0];
+    rules.insert((left, right), inserted);
+  }
+
+  let mut pairized = pairize(&template);
+  for _ in 0 .. 10 {
+    pairized = pairized_iterate(&pairized, &rules);
+  }
+  let answer = pairized_score(&template, &pairized);
+  println!("{}", answer);
+
+  for _ in 10 .. 40 {
+    pairized = pairized_iterate(&pairized, &rules);
+  }
+  let answer = pairized_score(&template, &pairized);
+  println!("{}", answer);
+
+  Ok(())
+}
+
+
+#[allow(dead_code)]
+fn iterate(template: &str, rules: &HashMap<(char, char), char>) -> String {
+  let mut result = String::new();
+  let length = template.len();
+
+  for i in 0 .. length - 1 {
+    let left = template.chars().nth(i).unwrap();
+    let right = template.chars().nth(i + 1).unwrap();
+    let inserted = rules.get(&(left, right));
+
+    result.push(left);
+
+    match inserted {
+      None => { }
+      Some(c) => {
+        result.push(*c);
+      }
+    }
+
+    if i == length - 2 {
+      result.push(right);
+    }
+  }
+
+  result
+}
+
+
+#[allow(dead_code)]
+fn score(template: &str) -> i64 {
+  let mut buckets = HashMap::new();
+
+  for c in template.chars() {
+    let value = buckets.get(&c);
+    match value {
+      None => {
+        buckets.insert(c, 1);
+      }
+      Some(total) => {
+        let new_total = total + 1;
+        buckets.insert(c, new_total);
+      }
+    }
+  }
+
+  let mut min_value = None;
+  let mut max_value = None;
+  for (_, value) in &buckets {
+    match min_value {
+      None => {
+        min_value = Some(value);
+      }
+      Some(old_value) => {
+        if value < old_value {
+          min_value = Some(value);
+        }
+      }
+    }
+
+    match max_value {
+      None => {
+        max_value = Some(value);
+      }
+      Some(old_value) => {
+        if value > old_value {
+          max_value = Some(value);
+        }
+      }
+    }
+  }
+
+  max_value.unwrap() - min_value.unwrap()
+}
+
+
+fn pairize(template: &str) -> HashMap<(char, char), usize> {
+  let mut result: HashMap<(char, char), usize> = HashMap::new();
+
+  for i in 0 .. template.len() - 1 {
+    let left = template.chars().nth(i).unwrap();
+    let right = template.chars().nth(i + 1).unwrap();
+    let key = (left, right);
+
+    match result.get(&key) {
+      None => {
+        result.insert(key, 1);
+      }
+      Some(count) => {
+        let new_count = count + 1;
+        result.insert(key, new_count);
+      }
+    }
+  }
+
+  result
+}
+
+
+fn pairized_iterate(
+    pairized: &HashMap<(char, char), usize>,
+    rules: &HashMap<(char, char), char>)
+  -> HashMap<(char, char), usize>
+{
+  let mut result: HashMap<(char, char), usize> = HashMap::new();
+
+  for (key, value) in pairized {
+    match rules.get(&key) {
+      None => {
+        result.insert(key.clone(), *value);
+      }
+      Some(inserted) => {
+        let (left, right) = key;
+        let left_key = (*left, *inserted);
+        let right_key = (*inserted, *right);
+
+        match result.get(&left_key) {
+          None => {
+            result.insert(left_key, *value);
+          }
+          Some(old_value) => {
+            let new_value = old_value + value;
+            result.insert(left_key, new_value);
+          }
+        }
+
+        match result.get(&right_key) {
+          None => {
+            result.insert(right_key, *value);
+          }
+          Some(old_value) => {
+            let new_value = old_value + value;
+            result.insert(right_key, new_value);
+          }
+        }
+      }
+    }
+  }
+
+  result
+}
+
+
+fn pairized_score(original: &str, pairized: &HashMap<(char, char), usize>)
+  -> usize
+{
+  let mut buckets = HashMap::new();
+
+  let leftmost = original.chars().nth(0).unwrap();
+  buckets.insert(leftmost, 1);
+
+  for ((_, c), value) in pairized {
+    match buckets.get(&c) {
+      None => {
+        buckets.insert(*c, *value);
+      }
+      Some(total) => {
+        let new_total = total + value;
+        buckets.insert(*c, new_total);
+      }
+    }
+  }
+
+  let mut min_value = None;
+  let mut max_value = None;
+  for (_, value) in &buckets {
+    match min_value {
+      None => {
+        min_value = Some(value);
+      }
+      Some(old_value) => {
+        if value < old_value {
+          min_value = Some(value);
+        }
+      }
+    }
+
+    match max_value {
+      None => {
+        max_value = Some(value);
+      }
+      Some(old_value) => {
+        if value > old_value {
+          max_value = Some(value);
+        }
+      }
+    }
+  }
+
+  max_value.unwrap() - min_value.unwrap()
+}
+
diff --git a/14/tests/main.rs b/14/tests/main.rs
new file mode 100644
index 0000000..0427925
--- /dev/null
+++ b/14/tests/main.rs
@@ -0,0 +1,17 @@
+use assert_cmd::prelude::*;
+//use predicates::prelude::*;
+use std::process::Command;
+
+
+#[test]
+fn personal_input() -> Result<(), Box<dyn std::error::Error>> {
+  let mut command = Command::cargo_bin("advent_14")?;
+
+  command.arg("input");
+  command.assert().success().stdout(
+      "2797\n\
+      2926813379532\n");
+
+  Ok(())
+}
+