diff options
-rw-r--r-- | 14/Cargo.toml | 11 | ||||
-rw-r--r-- | 14/input | 102 | ||||
-rw-r--r-- | 14/src/.main.rs.swo | bin | 0 -> 20480 bytes | |||
-rw-r--r-- | 14/src/main.rs | 237 | ||||
-rw-r--r-- | 14/tests/main.rs | 17 | ||||
-rw-r--r-- | Cargo.lock | 8 | ||||
-rw-r--r-- | Cargo.toml | 1 |
7 files changed, 376 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(()) +} + diff --git a/Cargo.lock b/Cargo.lock index d6b5403..841bb26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,6 +105,14 @@ dependencies = [ ] [[package]] +name = "advent_14" +version = "0.1.0" +dependencies = [ + "advent_lib", + "assert_cmd", +] + +[[package]] name = "advent_lib" version = "0.1.0" dependencies = [ diff --git a/Cargo.toml b/Cargo.toml index 60b1b36..1bdc5f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,4 +14,5 @@ members = [ "11", "12", "13", + "14", ] |