Add day 14
This commit is contained in:
parent
74925b973d
commit
b38c53b886
|
@ -4,6 +4,7 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
fnv = "1.0.7"
|
||||||
impl_ops = "0.1.1"
|
impl_ops = "0.1.1"
|
||||||
itertools = "0.10"
|
itertools = "0.10"
|
||||||
paste = "1.0"
|
paste = "1.0"
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
PBVHVOCOCFFNBCNCCBHK
|
||||||
|
|
||||||
|
FV -> C
|
||||||
|
SS -> B
|
||||||
|
SC -> B
|
||||||
|
BP -> K
|
||||||
|
VP -> S
|
||||||
|
HK -> K
|
||||||
|
FS -> F
|
||||||
|
CC -> V
|
||||||
|
VB -> P
|
||||||
|
OP -> B
|
||||||
|
FO -> N
|
||||||
|
FH -> O
|
||||||
|
VK -> N
|
||||||
|
PV -> S
|
||||||
|
HV -> O
|
||||||
|
PF -> F
|
||||||
|
HH -> F
|
||||||
|
NK -> S
|
||||||
|
NC -> S
|
||||||
|
FC -> H
|
||||||
|
FK -> K
|
||||||
|
OO -> N
|
||||||
|
HP -> C
|
||||||
|
NN -> H
|
||||||
|
BB -> H
|
||||||
|
CN -> P
|
||||||
|
PS -> N
|
||||||
|
VF -> S
|
||||||
|
CB -> B
|
||||||
|
OH -> S
|
||||||
|
CF -> C
|
||||||
|
OK -> P
|
||||||
|
CV -> V
|
||||||
|
CS -> H
|
||||||
|
KN -> B
|
||||||
|
OV -> S
|
||||||
|
HB -> C
|
||||||
|
OS -> V
|
||||||
|
PC -> B
|
||||||
|
CK -> S
|
||||||
|
PP -> K
|
||||||
|
SN -> O
|
||||||
|
VV -> C
|
||||||
|
NS -> F
|
||||||
|
PN -> K
|
||||||
|
HS -> P
|
||||||
|
VO -> B
|
||||||
|
VC -> B
|
||||||
|
NV -> P
|
||||||
|
VS -> N
|
||||||
|
FP -> F
|
||||||
|
HO -> S
|
||||||
|
KS -> O
|
||||||
|
BN -> F
|
||||||
|
VN -> P
|
||||||
|
OC -> K
|
||||||
|
SF -> P
|
||||||
|
PO -> P
|
||||||
|
SB -> O
|
||||||
|
FN -> F
|
||||||
|
OF -> F
|
||||||
|
CP -> C
|
||||||
|
HC -> O
|
||||||
|
PH -> O
|
||||||
|
BC -> O
|
||||||
|
NO -> C
|
||||||
|
BH -> C
|
||||||
|
VH -> S
|
||||||
|
KK -> O
|
||||||
|
SV -> K
|
||||||
|
KB -> K
|
||||||
|
BS -> S
|
||||||
|
HF -> B
|
||||||
|
NH -> S
|
||||||
|
PB -> N
|
||||||
|
HN -> K
|
||||||
|
SK -> B
|
||||||
|
FB -> F
|
||||||
|
KV -> S
|
||||||
|
BF -> S
|
||||||
|
ON -> S
|
||||||
|
BV -> P
|
||||||
|
KC -> S
|
||||||
|
NB -> S
|
||||||
|
NP -> B
|
||||||
|
BK -> K
|
||||||
|
NF -> C
|
||||||
|
BO -> K
|
||||||
|
KF -> B
|
||||||
|
KH -> N
|
||||||
|
SP -> O
|
||||||
|
CO -> S
|
||||||
|
KO -> V
|
||||||
|
SO -> B
|
||||||
|
CH -> C
|
||||||
|
KP -> C
|
||||||
|
FF -> K
|
||||||
|
PK -> F
|
||||||
|
OB -> H
|
||||||
|
SH -> C
|
|
@ -0,0 +1,90 @@
|
||||||
|
#![feature(array_windows)]
|
||||||
|
#![feature(test)]
|
||||||
|
extern crate test;
|
||||||
|
use aoc2021::common::*;
|
||||||
|
use fnv::FnvHashMap;
|
||||||
|
|
||||||
|
const DAY: usize = 14;
|
||||||
|
type Parsed = (FnvHashMap<[u8; 2], u8>, String);
|
||||||
|
|
||||||
|
fn parse_input(raw: &str) -> Parsed {
|
||||||
|
let (state, rules) = raw.split_once("\n\n").unwrap();
|
||||||
|
let rules = rules.lines().map(|line| line.as_bytes()).map(|bytes| ([bytes[0], bytes[1]], bytes[bytes.len() - 1])).collect();
|
||||||
|
(rules, state.to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn grow_polys((rules, raw_state): &Parsed, generations: usize) -> usize {
|
||||||
|
let mut state = FnvHashMap::default();
|
||||||
|
for polymer in raw_state.as_bytes().array_windows() {
|
||||||
|
*state.entry(*polymer).or_insert(0) += 1;
|
||||||
|
}
|
||||||
|
for _ in 0..generations {
|
||||||
|
for ([p1, p2], quantity) in state.clone() {
|
||||||
|
let output = rules[&[p1, p2]];
|
||||||
|
*state.entry([p1, output]).or_insert(0) += quantity;
|
||||||
|
*state.entry([output, p2]).or_insert(0) += quantity;
|
||||||
|
*state.get_mut(&[p1, p2]).unwrap() -= quantity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut charcounts = FnvHashMap::default();
|
||||||
|
for (p, q) in state.into_iter().flat_map(|([p1, p2], q)| [(p1, q), (p2, q)]) {
|
||||||
|
*charcounts.entry(p).or_insert(0) += q;
|
||||||
|
}
|
||||||
|
for (&p, q) in charcounts.iter_mut() {
|
||||||
|
// This implementation counts each element except the very first and very last twice.
|
||||||
|
// We add 1 for those and then divide by 2.
|
||||||
|
*q += (p == raw_state.bytes().next().unwrap()) as usize;
|
||||||
|
*q += (p == raw_state.bytes().last().unwrap()) as usize;
|
||||||
|
*q /= 2;
|
||||||
|
}
|
||||||
|
charcounts.values().max().unwrap() - charcounts.values().filter(|&&q| q != 0).min().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(parsed: &Parsed) -> usize {
|
||||||
|
grow_polys(parsed, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(parsed: &Parsed) -> usize {
|
||||||
|
grow_polys(parsed, 40)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input = parse_input(&read_file(DAY));
|
||||||
|
println!("Part 1: {}", part1(&input));
|
||||||
|
println!("Part 2: {}", part2(&input));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use aoc2021::*;
|
||||||
|
|
||||||
|
const TEST_INPUT: &str = "NNCB
|
||||||
|
|
||||||
|
CH -> B
|
||||||
|
HH -> N
|
||||||
|
CB -> H
|
||||||
|
NH -> C
|
||||||
|
HB -> C
|
||||||
|
HC -> B
|
||||||
|
HN -> C
|
||||||
|
NN -> C
|
||||||
|
BH -> H
|
||||||
|
NC -> B
|
||||||
|
NB -> B
|
||||||
|
BN -> B
|
||||||
|
BB -> N
|
||||||
|
BC -> B
|
||||||
|
CC -> N
|
||||||
|
CN -> C";
|
||||||
|
|
||||||
|
test!(part1() == 1588);
|
||||||
|
test!(part2() == 2188189693529);
|
||||||
|
bench!(part1() == 3587);
|
||||||
|
bench!(part2() == 3906445077999);
|
||||||
|
bench_input!(input_size => 120);
|
||||||
|
|
||||||
|
fn input_size((m, s): &Parsed) -> usize {
|
||||||
|
m.len() + s.len()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user