Day 14
This commit is contained in:
parent
c34101dd03
commit
c081f2287c
3 changed files with 237 additions and 0 deletions
18
input/14-test.txt
Normal file
18
input/14-test.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
|
102
input/14.txt
Normal file
102
input/14.txt
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
NCOPHKVONVPNSKSHBNPF
|
||||||
|
|
||||||
|
ON -> C
|
||||||
|
CK -> H
|
||||||
|
HC -> B
|
||||||
|
NP -> S
|
||||||
|
NH -> H
|
||||||
|
CB -> C
|
||||||
|
BB -> H
|
||||||
|
BC -> H
|
||||||
|
NN -> C
|
||||||
|
OH -> B
|
||||||
|
SF -> V
|
||||||
|
PB -> H
|
||||||
|
CP -> P
|
||||||
|
BN -> O
|
||||||
|
NB -> B
|
||||||
|
KB -> P
|
||||||
|
PV -> F
|
||||||
|
SH -> V
|
||||||
|
KP -> S
|
||||||
|
OF -> K
|
||||||
|
BS -> V
|
||||||
|
PF -> O
|
||||||
|
BK -> S
|
||||||
|
FB -> B
|
||||||
|
SV -> B
|
||||||
|
BH -> V
|
||||||
|
VK -> N
|
||||||
|
CS -> V
|
||||||
|
FV -> F
|
||||||
|
HS -> C
|
||||||
|
KK -> O
|
||||||
|
SP -> N
|
||||||
|
FK -> B
|
||||||
|
CF -> C
|
||||||
|
HP -> F
|
||||||
|
BF -> O
|
||||||
|
KC -> C
|
||||||
|
VP -> O
|
||||||
|
BP -> P
|
||||||
|
FF -> V
|
||||||
|
NO -> C
|
||||||
|
HK -> C
|
||||||
|
HV -> B
|
||||||
|
PK -> P
|
||||||
|
OV -> F
|
||||||
|
VN -> H
|
||||||
|
PC -> K
|
||||||
|
SB -> H
|
||||||
|
VO -> V
|
||||||
|
BV -> K
|
||||||
|
NC -> H
|
||||||
|
OB -> S
|
||||||
|
SN -> B
|
||||||
|
HF -> P
|
||||||
|
VF -> B
|
||||||
|
HN -> H
|
||||||
|
KS -> S
|
||||||
|
SC -> S
|
||||||
|
CV -> B
|
||||||
|
NS -> P
|
||||||
|
KO -> V
|
||||||
|
FS -> O
|
||||||
|
PH -> K
|
||||||
|
BO -> C
|
||||||
|
FH -> B
|
||||||
|
CO -> O
|
||||||
|
FO -> F
|
||||||
|
VV -> N
|
||||||
|
CH -> V
|
||||||
|
NK -> N
|
||||||
|
PO -> K
|
||||||
|
OK -> K
|
||||||
|
PP -> O
|
||||||
|
OC -> P
|
||||||
|
FC -> N
|
||||||
|
VH -> S
|
||||||
|
PN -> C
|
||||||
|
VB -> C
|
||||||
|
VS -> P
|
||||||
|
HO -> F
|
||||||
|
OP -> S
|
||||||
|
HB -> N
|
||||||
|
CC -> K
|
||||||
|
KN -> S
|
||||||
|
SK -> C
|
||||||
|
OS -> N
|
||||||
|
KH -> B
|
||||||
|
FP -> S
|
||||||
|
NF -> S
|
||||||
|
CN -> S
|
||||||
|
KF -> C
|
||||||
|
SS -> C
|
||||||
|
SO -> S
|
||||||
|
NV -> O
|
||||||
|
FN -> B
|
||||||
|
PS -> S
|
||||||
|
HH -> C
|
||||||
|
VC -> S
|
||||||
|
OO -> C
|
||||||
|
KV -> P
|
117
src/bin/14.rs
Normal file
117
src/bin/14.rs
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
use std::{collections::HashMap, hash::Hash};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut puzzle = input();
|
||||||
|
for _ in 0..10 {
|
||||||
|
puzzle.step();
|
||||||
|
}
|
||||||
|
println!("First solution: {}", puzzle.score());
|
||||||
|
for _ in 0..30 {
|
||||||
|
puzzle.step();
|
||||||
|
}
|
||||||
|
println!("Second solution: {}", puzzle.score());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
struct Digram(char, char);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Puzzle {
|
||||||
|
/// polymer is a count of all digrams in it.
|
||||||
|
polymer: HashMap<Digram, usize>,
|
||||||
|
/// start and end need to be kept track of, since all other chars are counted doubly,
|
||||||
|
/// due to the nature of counting the digrams.
|
||||||
|
start: char,
|
||||||
|
end: char,
|
||||||
|
instructions: Vec<Instruction>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ab -> to
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
struct Instruction {
|
||||||
|
from: Digram,
|
||||||
|
to: char,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Puzzle {
|
||||||
|
fn step(&mut self) {
|
||||||
|
let mut new_polymer = HashMap::new();
|
||||||
|
for (&old_digram, &count) in &self.polymer {
|
||||||
|
if let Some(i) = self.find_instruction(old_digram) {
|
||||||
|
for new_digram in i.output() {
|
||||||
|
let counter = new_polymer.entry(new_digram).or_default();
|
||||||
|
*counter += count;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let counter = new_polymer.entry(old_digram).or_default();
|
||||||
|
*counter += count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.polymer = new_polymer;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_instruction(&self, d: Digram) -> Option<Instruction> {
|
||||||
|
self.instructions.iter().copied().find(|i| i.from == d)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn score(&self) -> usize {
|
||||||
|
// All chars were counted doubly, due to the nature of the digrams, except start and end.
|
||||||
|
// Add one for those manually here.
|
||||||
|
let mut char_count: HashMap<char, usize> =
|
||||||
|
[(self.start, 1), (self.end, 1)].into_iter().collect();
|
||||||
|
|
||||||
|
for (&d, &count) in &self.polymer {
|
||||||
|
for c in [d.0, d.1] {
|
||||||
|
let counter = char_count.entry(c).or_default();
|
||||||
|
*counter += count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut doubly_counted: Vec<usize> = char_count.values().copied().collect();
|
||||||
|
doubly_counted.sort_unstable();
|
||||||
|
|
||||||
|
(doubly_counted.last().unwrap() - doubly_counted.first().unwrap()) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Instruction {
|
||||||
|
fn output(&self) -> [Digram; 2] {
|
||||||
|
[Digram(self.from.0, self.to), Digram(self.to, self.from.1)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn input() -> Puzzle {
|
||||||
|
let file = include_str!("../../input/14.txt");
|
||||||
|
|
||||||
|
let polymer_chars: Vec<char> = file.lines().next().unwrap().trim().chars().collect();
|
||||||
|
let polymer = polymer_chars
|
||||||
|
.windows(2)
|
||||||
|
.into_iter()
|
||||||
|
.map(|w| Digram(w[0], w[1]))
|
||||||
|
.fold(HashMap::new(), |mut acc, d| {
|
||||||
|
let count = acc.entry(d).or_default();
|
||||||
|
*count += 1;
|
||||||
|
acc
|
||||||
|
});
|
||||||
|
|
||||||
|
let instructions = file
|
||||||
|
.lines()
|
||||||
|
.filter(|l| l.contains("->"))
|
||||||
|
.filter_map(|l| l.split_once(" -> "))
|
||||||
|
.map(|(from, to)| {
|
||||||
|
let a = from.chars().next().unwrap();
|
||||||
|
let b = from.chars().nth(1).unwrap();
|
||||||
|
Instruction {
|
||||||
|
from: Digram(a, b),
|
||||||
|
to: to.chars().next().unwrap(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Puzzle {
|
||||||
|
polymer,
|
||||||
|
instructions,
|
||||||
|
start: polymer_chars.first().copied().unwrap(),
|
||||||
|
end: polymer_chars.last().copied().unwrap(),
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue