mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Implementation day 14 2021
This commit is contained in:
@@ -1,9 +1,124 @@
|
||||
use std::io::Read;
|
||||
|
||||
pub fn part1(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
use itertools::Itertools;
|
||||
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 {
|
||||
todo!()
|
||||
fn read_input(input: &mut dyn Read) -> (u8, u8, Pairs, Rules) {
|
||||
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