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