1
0
Fork 0
aoc2021/src/main.rs

119 lines
2.8 KiB
Rust
Raw Normal View History

2021-12-01 05:51:55 +00:00
#![feature(test)]
extern crate test;
2021-12-03 05:38:45 +00:00
const INPUTS: [&'static str; 2] = [
2021-12-05 05:24:30 +00:00
include_str!("../inputs/sample.txt"),
include_str!("../inputs/input.txt"),
2021-12-03 05:38:45 +00:00
];
2021-12-02 05:14:07 +00:00
2021-12-14 08:17:16 +00:00
use std::collections::HashMap;
fn parse_input(input: &'static str) -> (Vec<char>, HashMap<(char, char), char>) {
2021-12-13 07:46:22 +00:00
let mut input = input.split("\n\n");
2021-12-12 20:34:08 +00:00
2021-12-14 08:17:16 +00:00
let template = input.next().unwrap().chars().collect();
let folds: HashMap<(char, char), char> = input
2021-12-13 07:46:22 +00:00
.next()
.unwrap()
.lines()
.map(|line| {
2021-12-14 08:17:16 +00:00
let (s, d) = line.split_once(" -> ").unwrap();
let mut ss = s.chars();
let p = ss.next().unwrap();
let q = ss.next().unwrap();
2021-12-10 06:28:11 +00:00
2021-12-14 08:17:16 +00:00
((p, q), d.chars().next().unwrap())
2021-12-13 07:46:22 +00:00
})
.collect();
2021-12-14 08:17:16 +00:00
(template, folds)
}
fn solution((template, pairs): (Vec<char>, HashMap<(char, char), char>)) -> u64 {
let mut map = [0; 26];
let mut memo = HashMap::new();
for i in 0..template.len() - 1 {
let a = template[i];
let b = template[i + 1];
let out = recurse(&pairs, &mut memo, a, b, 10);
for (a, b) in map.iter_mut().zip(out.into_iter()) {
*a += b;
}
if i != template.len() - 2 {
map[b as usize - b'A' as usize] -= 1;
}
}
2021-12-13 07:46:22 +00:00
2021-12-14 08:17:16 +00:00
let mut most_common = 0;
let mut least_common = std::u64::MAX;
for a in map {
most_common = std::cmp::max(most_common, a);
if a != 0 {
least_common = std::cmp::min(least_common, a);
}
}
most_common - least_common
2021-12-12 19:46:58 +00:00
}
2021-12-14 08:17:16 +00:00
fn recurse(
pairs: &HashMap<(char, char), char>,
memo: &mut HashMap<(char, char, i32), [u64; 26]>,
a: char,
b: char,
steps: i32,
) -> [u64; 26] {
if steps == 0 {
let mut out = [0; 26];
out[a as usize - b'A' as usize] += 1;
out[b as usize - b'A' as usize] += 1;
return out;
}
if steps < 0 {
return [0; 26];
2021-12-12 19:46:58 +00:00
}
2021-12-14 08:17:16 +00:00
if let Some(v) = memo.get(&(a, b, steps)) {
return *v;
2021-12-12 20:34:08 +00:00
}
2021-12-14 08:17:16 +00:00
if let Some(&token) = pairs.get(&(a, b)) {
let mut out1 = recurse(pairs, memo, a, token, steps - 1);
let out2 = recurse(pairs, memo, token, b, steps - 1);
for (a, b) in out1.iter_mut().zip(out2.into_iter()) {
*a += b;
2021-12-13 07:46:22 +00:00
}
2021-12-12 20:34:08 +00:00
2021-12-14 08:17:16 +00:00
out1[token as usize - b'A' as usize] -= 1;
memo.insert((a, b, steps), out1);
return out1;
}
let mut out = [0; 26];
out[a as usize - b'A' as usize] += 1;
out[b as usize - b'A' as usize] += 1;
out
2021-12-09 16:46:57 +00:00
}
2021-12-01 05:51:55 +00:00
fn main() {
2021-12-10 06:20:18 +00:00
for input in INPUTS {
let input = parse_input(input);
2021-12-14 08:17:16 +00:00
let result = solution(input);
println!("Result = {}", result);
2021-12-10 06:20:18 +00:00
}
2021-12-01 05:16:08 +00:00
}
2021-12-01 05:51:55 +00:00
#[bench]
fn solution_bench(b: &mut test::Bencher) {
2021-12-12 19:46:58 +00:00
let input = parse_input(INPUTS[1]);
2021-12-01 05:51:55 +00:00
b.iter(|| {
2021-12-12 19:46:58 +00:00
let result = solution(input.clone());
2021-12-04 05:41:16 +00:00
test::black_box(result);
2021-12-01 05:51:55 +00:00
})
}