mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-26 05:10:32 +01:00
Implementation day 14 2021
This commit is contained in:
102
2021/inputs/14.txt
Normal file
102
2021/inputs/14.txt
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
SHHBNFBCKNHCNOSHHVFF
|
||||||
|
|
||||||
|
CK -> N
|
||||||
|
VP -> B
|
||||||
|
CF -> S
|
||||||
|
FO -> V
|
||||||
|
VC -> S
|
||||||
|
BV -> V
|
||||||
|
NP -> P
|
||||||
|
SN -> C
|
||||||
|
KN -> V
|
||||||
|
NF -> P
|
||||||
|
SB -> C
|
||||||
|
PC -> B
|
||||||
|
OB -> V
|
||||||
|
NS -> O
|
||||||
|
FH -> S
|
||||||
|
NK -> S
|
||||||
|
HO -> V
|
||||||
|
NV -> O
|
||||||
|
FV -> O
|
||||||
|
FB -> S
|
||||||
|
PS -> S
|
||||||
|
FN -> K
|
||||||
|
HS -> O
|
||||||
|
CB -> K
|
||||||
|
HV -> P
|
||||||
|
NH -> C
|
||||||
|
BO -> B
|
||||||
|
FF -> N
|
||||||
|
PO -> F
|
||||||
|
BB -> N
|
||||||
|
PN -> C
|
||||||
|
BP -> C
|
||||||
|
HN -> K
|
||||||
|
CO -> P
|
||||||
|
BF -> H
|
||||||
|
BC -> S
|
||||||
|
CV -> B
|
||||||
|
VV -> F
|
||||||
|
FS -> B
|
||||||
|
BN -> P
|
||||||
|
VK -> S
|
||||||
|
PV -> V
|
||||||
|
PP -> B
|
||||||
|
PH -> N
|
||||||
|
SS -> O
|
||||||
|
SK -> S
|
||||||
|
NC -> P
|
||||||
|
ON -> F
|
||||||
|
NB -> N
|
||||||
|
CC -> N
|
||||||
|
SF -> H
|
||||||
|
PF -> H
|
||||||
|
OV -> O
|
||||||
|
KH -> C
|
||||||
|
CP -> V
|
||||||
|
PK -> O
|
||||||
|
KC -> K
|
||||||
|
KK -> C
|
||||||
|
KF -> B
|
||||||
|
HP -> C
|
||||||
|
FK -> H
|
||||||
|
BH -> K
|
||||||
|
VN -> H
|
||||||
|
OO -> S
|
||||||
|
SC -> K
|
||||||
|
SP -> B
|
||||||
|
KO -> V
|
||||||
|
KV -> F
|
||||||
|
HK -> N
|
||||||
|
FP -> N
|
||||||
|
NN -> B
|
||||||
|
VS -> O
|
||||||
|
HC -> K
|
||||||
|
BK -> N
|
||||||
|
KS -> K
|
||||||
|
VB -> O
|
||||||
|
OH -> F
|
||||||
|
KB -> F
|
||||||
|
KP -> H
|
||||||
|
HB -> N
|
||||||
|
NO -> N
|
||||||
|
OF -> O
|
||||||
|
BS -> H
|
||||||
|
VO -> H
|
||||||
|
SH -> O
|
||||||
|
SV -> K
|
||||||
|
HF -> C
|
||||||
|
CS -> F
|
||||||
|
FC -> N
|
||||||
|
VH -> H
|
||||||
|
OP -> K
|
||||||
|
OK -> H
|
||||||
|
PB -> K
|
||||||
|
HH -> S
|
||||||
|
OC -> V
|
||||||
|
VF -> B
|
||||||
|
CH -> K
|
||||||
|
CN -> C
|
||||||
|
SO -> P
|
||||||
|
OS -> O
|
||||||
@@ -1,9 +1,124 @@
|
|||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
pub fn part1(_input: &mut dyn Read) -> String {
|
use itertools::Itertools;
|
||||||
todo!()
|
use nom::bytes::complete::tag;
|
||||||
|
use nom::bytes::complete::take_while;
|
||||||
|
use nom::character::is_alphabetic;
|
||||||
|
use nom::multi::many0;
|
||||||
|
use nom::sequence::preceded;
|
||||||
|
use nom::sequence::terminated;
|
||||||
|
use nom::sequence::tuple;
|
||||||
|
use nom::Finish;
|
||||||
|
use nom::IResult;
|
||||||
|
|
||||||
|
type Rule = (u8, u8, u8);
|
||||||
|
|
||||||
|
type Pairs = [[u64; 26]; 26];
|
||||||
|
type Rules = [[u8; 26]; 26];
|
||||||
|
|
||||||
|
fn parse_input(input: &[u8]) -> IResult<&[u8], (&[u8], Vec<Rule>)> {
|
||||||
|
use nom::character::complete::char;
|
||||||
|
use nom::number::complete::u8;
|
||||||
|
|
||||||
|
let parse_start = take_while(is_alphabetic);
|
||||||
|
let parse_rule = tuple((u8, u8, preceded(tag(" -> "), u8)));
|
||||||
|
|
||||||
|
tuple((
|
||||||
|
parse_start,
|
||||||
|
preceded(tag("\n\n"), many0(terminated(parse_rule, char('\n')))),
|
||||||
|
))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part2(_input: &mut dyn Read) -> String {
|
fn read_input(input: &mut dyn Read) -> (u8, u8, Pairs, Rules) {
|
||||||
todo!()
|
let mut buffer = Vec::new();
|
||||||
|
input.read_to_end(&mut buffer).unwrap();
|
||||||
|
|
||||||
|
let (initial, rules) = parse_input(&buffer).finish().unwrap().1;
|
||||||
|
|
||||||
|
let mut pairs = Pairs::default();
|
||||||
|
|
||||||
|
for window in initial.windows(2) {
|
||||||
|
pairs[(window[0] - b'A') as usize][(window[1] - b'A') as usize] += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut rule_map = Rules::default();
|
||||||
|
for (first, second, product) in rules {
|
||||||
|
rule_map[(first - b'A') as usize][(second - b'A') as usize] = product - b'A';
|
||||||
|
}
|
||||||
|
|
||||||
|
(
|
||||||
|
initial[0] - b'A',
|
||||||
|
initial[initial.len() - 1] - b'A',
|
||||||
|
pairs,
|
||||||
|
rule_map,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(pairs: Pairs, rules: &Rules) -> Pairs {
|
||||||
|
let mut new_pairs = Pairs::default();
|
||||||
|
|
||||||
|
pairs.iter().enumerate().for_each(|(first, row)| {
|
||||||
|
row.iter().enumerate().for_each(|(second, &count)| {
|
||||||
|
let product = rules[first][second] as usize;
|
||||||
|
new_pairs[first][product] += count;
|
||||||
|
new_pairs[product][second] += count;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
new_pairs
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parts_common(input: &mut dyn Read, rounds: usize) -> String {
|
||||||
|
let (first, last, mut pairs, rules) = read_input(input);
|
||||||
|
|
||||||
|
(0..rounds).for_each(|_| pairs = update(pairs, &rules));
|
||||||
|
|
||||||
|
let mut pair_counts = [0; 26];
|
||||||
|
pairs.iter().enumerate().for_each(|(first, row)| {
|
||||||
|
row.iter().enumerate().for_each(|(second, &count)| {
|
||||||
|
pair_counts[first] += count;
|
||||||
|
pair_counts[second] += count;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
pair_counts[first as usize] += 1;
|
||||||
|
pair_counts[last as usize] += 1;
|
||||||
|
|
||||||
|
// Now everything is counted twice, so first half everything
|
||||||
|
let counts = pair_counts.map(|pair_count| pair_count / 2);
|
||||||
|
|
||||||
|
match counts.into_iter().filter(|&c| c != 0).minmax() {
|
||||||
|
itertools::MinMaxResult::NoElements => unreachable!(),
|
||||||
|
itertools::MinMaxResult::OneElement(_) => 0,
|
||||||
|
itertools::MinMaxResult::MinMax(min, max) => max - min,
|
||||||
|
}
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part1(input: &mut dyn Read) -> String {
|
||||||
|
parts_common(input, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part2(input: &mut dyn Read) -> String {
|
||||||
|
parts_common(input, 40)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
use crate::test_implementation;
|
||||||
|
|
||||||
|
const SAMPLE: &[u8] = include_bytes!("samples/14.txt");
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sample_part1() {
|
||||||
|
test_implementation(part1, SAMPLE, 1588);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sample_part2() {
|
||||||
|
test_implementation(part2, SAMPLE, 2188189693529u64);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
2021/src/samples/14.txt
Normal file
18
2021/src/samples/14.txt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
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
|
||||||
Reference in New Issue
Block a user