add day 14
This commit is contained in:
parent
12c10cf056
commit
99ec7923f2
102
input/day14.txt
Normal file
102
input/day14.txt
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
OOFNFCBHCKBBVNHBNVCP
|
||||||
|
|
||||||
|
PH -> V
|
||||||
|
OK -> S
|
||||||
|
KK -> O
|
||||||
|
BV -> K
|
||||||
|
CV -> S
|
||||||
|
SV -> C
|
||||||
|
CK -> O
|
||||||
|
PC -> F
|
||||||
|
SC -> O
|
||||||
|
KC -> S
|
||||||
|
KF -> N
|
||||||
|
SN -> C
|
||||||
|
SF -> P
|
||||||
|
OS -> O
|
||||||
|
OP -> N
|
||||||
|
FS -> P
|
||||||
|
FV -> N
|
||||||
|
CP -> S
|
||||||
|
VS -> P
|
||||||
|
PB -> P
|
||||||
|
HP -> P
|
||||||
|
PK -> S
|
||||||
|
FC -> F
|
||||||
|
SB -> K
|
||||||
|
NC -> V
|
||||||
|
PP -> B
|
||||||
|
PN -> N
|
||||||
|
VN -> C
|
||||||
|
NV -> O
|
||||||
|
OV -> O
|
||||||
|
BS -> K
|
||||||
|
FP -> V
|
||||||
|
NK -> K
|
||||||
|
PO -> B
|
||||||
|
HF -> H
|
||||||
|
VK -> S
|
||||||
|
ON -> C
|
||||||
|
KH -> F
|
||||||
|
HO -> P
|
||||||
|
OO -> H
|
||||||
|
BC -> V
|
||||||
|
CS -> O
|
||||||
|
OC -> B
|
||||||
|
VB -> N
|
||||||
|
OF -> P
|
||||||
|
FK -> H
|
||||||
|
OH -> H
|
||||||
|
CF -> K
|
||||||
|
CC -> V
|
||||||
|
BK -> O
|
||||||
|
BH -> F
|
||||||
|
VV -> N
|
||||||
|
KS -> V
|
||||||
|
FO -> F
|
||||||
|
SH -> F
|
||||||
|
OB -> O
|
||||||
|
VH -> F
|
||||||
|
HH -> P
|
||||||
|
PF -> C
|
||||||
|
NF -> V
|
||||||
|
VP -> S
|
||||||
|
CN -> V
|
||||||
|
SK -> O
|
||||||
|
FB -> S
|
||||||
|
FN -> S
|
||||||
|
BF -> H
|
||||||
|
FF -> V
|
||||||
|
CB -> P
|
||||||
|
NN -> O
|
||||||
|
VC -> F
|
||||||
|
HK -> F
|
||||||
|
BO -> H
|
||||||
|
KO -> C
|
||||||
|
CH -> N
|
||||||
|
KP -> C
|
||||||
|
HS -> P
|
||||||
|
NP -> O
|
||||||
|
NS -> V
|
||||||
|
NB -> H
|
||||||
|
HN -> O
|
||||||
|
BP -> C
|
||||||
|
VF -> S
|
||||||
|
KN -> P
|
||||||
|
HC -> C
|
||||||
|
PS -> K
|
||||||
|
BB -> O
|
||||||
|
NO -> N
|
||||||
|
NH -> F
|
||||||
|
BN -> F
|
||||||
|
KV -> V
|
||||||
|
SS -> K
|
||||||
|
CO -> H
|
||||||
|
KB -> P
|
||||||
|
FH -> C
|
||||||
|
SP -> C
|
||||||
|
SO -> V
|
||||||
|
PV -> S
|
||||||
|
VO -> O
|
||||||
|
HV -> N
|
||||||
|
HB -> V
|
|
@ -1,2 +1,3 @@
|
||||||
pub mod day1;
|
pub mod day1;
|
||||||
|
pub mod day14;
|
||||||
pub mod day5;
|
pub mod day5;
|
||||||
|
|
107
src/days/day14.rs
Normal file
107
src/days/day14.rs
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
#![libaoc::day(14, "../../input/day14.txt")]
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use libaoc::miette::{bail, miette, Result};
|
||||||
|
|
||||||
|
fn part1() -> Result<()> {
|
||||||
|
run(10)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2() -> Result<()> {
|
||||||
|
run(40)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(iters: u8) -> Result<()> {
|
||||||
|
let Input { start, rules } = parse_input()?;
|
||||||
|
let mut solution = [0; 26];
|
||||||
|
solution[start[0] as usize] = 1;
|
||||||
|
|
||||||
|
let mut cache = HashMap::new();
|
||||||
|
for win in start.windows(2) {
|
||||||
|
solution = compute_pair((win[0], win[1]), &rules, iters, &mut cache)
|
||||||
|
.zip(solution)
|
||||||
|
.map(|(a, b)| a + b);
|
||||||
|
}
|
||||||
|
|
||||||
|
let min = solution.iter().filter(|&&n| n != 0).min().unwrap_or(&0);
|
||||||
|
let max = solution.iter().filter(|&&n| n != 0).max().unwrap_or(&0);
|
||||||
|
|
||||||
|
println!("{}", max - min);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
struct CacheKey {
|
||||||
|
left: u8,
|
||||||
|
right: u8,
|
||||||
|
iter: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
// This big brain algo isn't by me. I found it in someone else's solutions, but fully understood
|
||||||
|
// and rewrote it.
|
||||||
|
fn compute_pair<'cache>(
|
||||||
|
pair: (u8, u8),
|
||||||
|
rules: &HashMap<(u8, u8), u8>,
|
||||||
|
iter: u8,
|
||||||
|
cache: &'cache mut HashMap<CacheKey, [u64; 26]>,
|
||||||
|
) -> &'cache [u64; 26] {
|
||||||
|
let key = CacheKey {
|
||||||
|
left: pair.0,
|
||||||
|
right: pair.1,
|
||||||
|
iter,
|
||||||
|
};
|
||||||
|
|
||||||
|
if !cache.contains_key(&key) {
|
||||||
|
if let (Some(&ins), 1..) = (rules.get(&pair), iter) {
|
||||||
|
let arr_a = *compute_pair((pair.0, ins), rules, iter - 1, cache);
|
||||||
|
let arr_b = *compute_pair((ins, pair.1), rules, iter - 1, cache);
|
||||||
|
let sum = arr_a.zip(arr_b).map(|(a, b)| a + b);
|
||||||
|
cache.insert(key, sum);
|
||||||
|
} else {
|
||||||
|
let mut arr = [0; 26];
|
||||||
|
arr[pair.1 as usize] = 1;
|
||||||
|
cache.insert(key, arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&cache[&key]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn char_to_idx(c: char) -> u8 {
|
||||||
|
c as u8 - b'A'
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Input {
|
||||||
|
start: Vec<u8>,
|
||||||
|
rules: HashMap<(u8, u8), u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_input() -> Result<Input> {
|
||||||
|
let mut lines = INPUT.lines();
|
||||||
|
let poly = lines
|
||||||
|
.next()
|
||||||
|
.ok_or_else(|| miette!("input empty"))?
|
||||||
|
.chars()
|
||||||
|
.map(char_to_idx)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut rules = HashMap::new();
|
||||||
|
|
||||||
|
for line in lines.skip(1) {
|
||||||
|
let mut line = line.chars();
|
||||||
|
let a = line.next();
|
||||||
|
let b = line.next();
|
||||||
|
let c = line.nth(4);
|
||||||
|
|
||||||
|
match (a, b, c) {
|
||||||
|
(Some(a), Some(b), Some(c)) => {
|
||||||
|
rules.insert((char_to_idx(a), char_to_idx(b)), char_to_idx(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => bail!("invalid input"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Input { start: poly, rules })
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
#![libaoc::day(5, "../../input/day5.txt")]
|
#![libaoc::day(5, "../../input/day5.txt")]
|
||||||
|
|
||||||
use std::cmp::{max, min, Ordering};
|
use std::cmp::{max, Ordering};
|
||||||
use std::io::BufRead;
|
|
||||||
|
|
||||||
use libaoc::miette::{miette, IntoDiagnostic, Result};
|
use libaoc::miette::{miette, IntoDiagnostic, Result};
|
||||||
|
|
||||||
|
@ -39,6 +38,8 @@ fn solve(diagonal: bool) -> Result<()> {
|
||||||
if x1 == x2 {
|
if x1 == x2 {
|
||||||
let (y1, y2) = small_large(y1, y2);
|
let (y1, y2) = small_large(y1, y2);
|
||||||
|
|
||||||
|
// this lint would actually make this more ugly
|
||||||
|
#[allow(clippy::needless_range_loop)]
|
||||||
for y in y1..=y2 {
|
for y in y1..=y2 {
|
||||||
mtx[y][x1] += 1;
|
mtx[y][x1] += 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
|
#![feature(array_zip)]
|
||||||
#![feature(custom_inner_attributes)]
|
#![feature(custom_inner_attributes)]
|
||||||
|
#![feature(linked_list_cursors)]
|
||||||
#![feature(proc_macro_hygiene)]
|
#![feature(proc_macro_hygiene)]
|
||||||
|
|
||||||
mod days;
|
mod days;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
use days::*;
|
use days::*;
|
||||||
|
|
||||||
fn main() -> libaoc::miette::Result<()> {
|
fn main() -> libaoc::miette::Result<()> {
|
||||||
libaoc::run_days!(
|
libaoc::run_days!(day1, day5, day14,)
|
||||||
day1,
|
|
||||||
day5,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue