Add day 14
This commit is contained in:
parent
74925b973d
commit
b38c53b886
|
@ -4,6 +4,7 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
fnv = "1.0.7"
|
||||
impl_ops = "0.1.1"
|
||||
itertools = "0.10"
|
||||
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