diff options
Diffstat (limited to '14/src')
-rw-r--r-- | 14/src/.main.rs.swo | bin | 0 -> 20480 bytes | |||
-rw-r--r-- | 14/src/main.rs | 237 |
2 files changed, 237 insertions, 0 deletions
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() +} + |