mirror of
https://github.com/Smaug123/advent-of-code-2021
synced 2025-10-06 04:28:41 +00:00
Day 14 (#15)
This commit is contained in:
57
Cargo.lock
generated
57
Cargo.lock
generated
@@ -60,9 +60,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "2.33.3"
|
version = "2.34.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"textwrap",
|
"textwrap",
|
||||||
@@ -157,7 +157,7 @@ checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bstr",
|
"bstr",
|
||||||
"csv-core",
|
"csv-core",
|
||||||
"itoa",
|
"itoa 0.4.8",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
@@ -206,6 +206,13 @@ dependencies = [
|
|||||||
"criterion",
|
"criterion",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day_14"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"criterion",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "day_16"
|
name = "day_16"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -292,9 +299,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.10.1"
|
version = "0.10.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
|
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
@@ -305,6 +312,12 @@ version = "0.4.8"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.55"
|
version = "0.3.55"
|
||||||
@@ -322,9 +335,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.108"
|
version = "0.2.112"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
|
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
@@ -343,9 +356,9 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memoffset"
|
name = "memoffset"
|
||||||
version = "0.6.4"
|
version = "0.6.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
|
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
@@ -405,9 +418,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.32"
|
version = "1.0.34"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
|
checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
@@ -478,9 +491,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.5"
|
version = "1.0.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "same-file"
|
name = "same-file"
|
||||||
@@ -505,9 +518,9 @@ checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.130"
|
version = "1.0.131"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
|
checksum = "b4ad69dfbd3e45369132cc64e6748c2d65cdfb001a2b1c232d128b4ad60561c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_cbor"
|
name = "serde_cbor"
|
||||||
@@ -521,9 +534,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.130"
|
version = "1.0.131"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
|
checksum = "b710a83c4e0dff6a3d511946b95274ad9ca9e5d3ae497b63fda866ac955358d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -532,20 +545,20 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.71"
|
version = "1.0.73"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "063bf466a64011ac24040a49009724ee60a57da1b437617ceb32e53ad61bfb19"
|
checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa 1.0.1",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.81"
|
version = "1.0.82"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
|
checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@@ -13,5 +13,6 @@ members = [
|
|||||||
"day_11",
|
"day_11",
|
||||||
"day_12",
|
"day_12",
|
||||||
"day_13",
|
"day_13",
|
||||||
|
"day_14",
|
||||||
"day_16",
|
"day_16",
|
||||||
]
|
]
|
||||||
|
15
day_14/Cargo.toml
Normal file
15
day_14/Cargo.toml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[package]
|
||||||
|
name = "day_14"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Smaug123 <patrick+github@patrickstevens.co.uk>"]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
[dev-dependencies]
|
||||||
|
criterion = "0.3"
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "bench"
|
||||||
|
harness = false
|
19
day_14/benches/bench.rs
Normal file
19
day_14/benches/bench.rs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||||
|
use day_14::day_14::{input, part_1, part_2};
|
||||||
|
|
||||||
|
fn criterion_benchmark(c: &mut Criterion) {
|
||||||
|
let input = input();
|
||||||
|
c.bench_function("day 14 part 1", |b| {
|
||||||
|
b.iter(|| {
|
||||||
|
black_box(part_1(&input));
|
||||||
|
})
|
||||||
|
});
|
||||||
|
c.bench_function("day 14 part 2", |b| {
|
||||||
|
b.iter(|| {
|
||||||
|
black_box(part_2(&input));
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
criterion_group!(benches, criterion_benchmark);
|
||||||
|
criterion_main!(benches);
|
30
day_14/day14.m
Normal file
30
day_14/day14.m
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
(* ::Package:: *)
|
||||||
|
|
||||||
|
parse[s_]:=With[{lines=StringSplit[s,"\n"]},
|
||||||
|
{lines[[1]],With[{sides=StringSplit[#," -> "]},Characters[First@sides]->{{StringTake[First@sides,{1}],Last@sides},{Last@sides,StringTake[First@sides,{2}]}}]&/@lines[[3;;]]}]
|
||||||
|
|
||||||
|
{start,rules}=parse@StringTrim@ReadString[StringJoin[NotebookDirectory[], "/input.txt"]];
|
||||||
|
|
||||||
|
|
||||||
|
(* ::Text:: *)
|
||||||
|
(*Part 1*)
|
||||||
|
|
||||||
|
|
||||||
|
step[rules_,chars_]:=Flatten[chars/.rules,1]
|
||||||
|
|
||||||
|
|
||||||
|
With[{l=SortBy[Tally[Join[StringTake[start,{{1},{-1}}],Flatten@Nest[step[rules,#]&,Partition[Characters@start,2,1],10]]],Last]},
|
||||||
|
Quotient[l[[-1]],2]-Quotient[l[[1]],2]
|
||||||
|
][[2]]
|
||||||
|
|
||||||
|
|
||||||
|
(* ::Text:: *)
|
||||||
|
(*Part 2*)
|
||||||
|
|
||||||
|
|
||||||
|
step[rules_,pairs_]:={#[[1,1]],Total[Last/@#]}&/@GatherBy[Flatten[Thread/@(pairs/.rules),1],First]
|
||||||
|
|
||||||
|
|
||||||
|
With[{l=Cases[Total@Flatten[{Times@@@Nest[step[rules,#]&,Tally@Partition[Characters@start,2,1],40],StringTake[start,{{1},{-1}}]}],_Integer,All]},
|
||||||
|
(Max[l]-Min[l])/2
|
||||||
|
]
|
102
day_14/input.txt
Normal file
102
day_14/input.txt
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
SHHNCOPHONHFBVNKCFFC
|
||||||
|
|
||||||
|
HH -> K
|
||||||
|
PS -> P
|
||||||
|
BV -> H
|
||||||
|
HB -> H
|
||||||
|
CK -> F
|
||||||
|
FN -> B
|
||||||
|
PV -> S
|
||||||
|
KK -> F
|
||||||
|
OF -> C
|
||||||
|
SF -> B
|
||||||
|
KB -> S
|
||||||
|
HO -> O
|
||||||
|
NH -> N
|
||||||
|
ON -> V
|
||||||
|
VF -> K
|
||||||
|
VP -> K
|
||||||
|
PH -> K
|
||||||
|
FF -> V
|
||||||
|
OV -> N
|
||||||
|
BO -> K
|
||||||
|
PO -> S
|
||||||
|
CH -> N
|
||||||
|
FO -> V
|
||||||
|
FB -> H
|
||||||
|
FV -> N
|
||||||
|
FK -> S
|
||||||
|
VC -> V
|
||||||
|
CP -> K
|
||||||
|
CO -> K
|
||||||
|
SV -> N
|
||||||
|
PP -> B
|
||||||
|
BS -> P
|
||||||
|
VS -> C
|
||||||
|
HV -> H
|
||||||
|
NN -> F
|
||||||
|
NK -> C
|
||||||
|
PC -> V
|
||||||
|
HS -> S
|
||||||
|
FS -> S
|
||||||
|
OB -> S
|
||||||
|
VV -> N
|
||||||
|
VO -> P
|
||||||
|
KV -> F
|
||||||
|
SK -> O
|
||||||
|
BC -> P
|
||||||
|
BP -> F
|
||||||
|
NS -> P
|
||||||
|
SN -> S
|
||||||
|
NC -> N
|
||||||
|
FC -> V
|
||||||
|
CN -> S
|
||||||
|
OK -> B
|
||||||
|
SC -> N
|
||||||
|
HN -> B
|
||||||
|
HP -> B
|
||||||
|
KP -> B
|
||||||
|
CB -> K
|
||||||
|
KF -> C
|
||||||
|
OS -> B
|
||||||
|
BH -> O
|
||||||
|
PN -> K
|
||||||
|
VN -> O
|
||||||
|
KH -> F
|
||||||
|
BF -> H
|
||||||
|
HF -> K
|
||||||
|
HC -> P
|
||||||
|
NP -> H
|
||||||
|
KO -> K
|
||||||
|
CF -> H
|
||||||
|
BK -> O
|
||||||
|
OH -> P
|
||||||
|
SO -> F
|
||||||
|
BB -> F
|
||||||
|
VB -> K
|
||||||
|
SP -> O
|
||||||
|
SH -> O
|
||||||
|
PK -> O
|
||||||
|
HK -> P
|
||||||
|
CC -> V
|
||||||
|
NB -> O
|
||||||
|
NV -> F
|
||||||
|
OO -> F
|
||||||
|
VK -> V
|
||||||
|
FH -> H
|
||||||
|
SS -> C
|
||||||
|
NO -> P
|
||||||
|
CS -> H
|
||||||
|
BN -> V
|
||||||
|
FP -> N
|
||||||
|
OP -> N
|
||||||
|
PB -> P
|
||||||
|
OC -> O
|
||||||
|
SB -> V
|
||||||
|
VH -> O
|
||||||
|
KS -> B
|
||||||
|
PF -> N
|
||||||
|
KN -> H
|
||||||
|
NF -> N
|
||||||
|
CV -> K
|
||||||
|
KC -> B
|
213
day_14/src/lib.rs
Normal file
213
day_14/src/lib.rs
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
pub mod day_14 {
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
pub struct Data {
|
||||||
|
start: char,
|
||||||
|
end: char,
|
||||||
|
rules: HashMap<(char, char), char>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn parse(s: &str) -> (Data, HashMap<(char, char), u64>) {
|
||||||
|
let mut lines = s.split('\n');
|
||||||
|
let start = lines.next().unwrap();
|
||||||
|
match lines.next().unwrap() {
|
||||||
|
"" => {}
|
||||||
|
s => panic!("Expected empty line, got {}", s),
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
for line in lines {
|
||||||
|
let mut iter = line.split(' ');
|
||||||
|
let pair = iter.next().unwrap();
|
||||||
|
match iter.next().unwrap() {
|
||||||
|
"->" => {}
|
||||||
|
s => panic!("Expected arrow, got {}", s),
|
||||||
|
}
|
||||||
|
let middle = iter.next().unwrap();
|
||||||
|
match iter.next() {
|
||||||
|
None => {}
|
||||||
|
Some(next) => panic!("Expected end of line, got {}", next),
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut chars = pair.chars();
|
||||||
|
let p1 = chars.next().unwrap();
|
||||||
|
let p2 = chars.next().unwrap();
|
||||||
|
match chars.next() {
|
||||||
|
None => {}
|
||||||
|
Some(_) => panic!("Expected pair of chars, got {}", pair),
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut chars = middle.chars();
|
||||||
|
let insert = chars.next().unwrap();
|
||||||
|
match chars.next() {
|
||||||
|
None => {}
|
||||||
|
Some(_) => panic!("Expected single char, got {}", middle),
|
||||||
|
}
|
||||||
|
map.insert((p1, p2), insert);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut pairs = HashMap::new();
|
||||||
|
let mut iter = start.chars();
|
||||||
|
let start = iter.next().unwrap();
|
||||||
|
|
||||||
|
let mut prev = start;
|
||||||
|
|
||||||
|
for next in iter {
|
||||||
|
pairs
|
||||||
|
.entry((prev, next))
|
||||||
|
.and_modify(|x| *x += 1)
|
||||||
|
.or_insert(1);
|
||||||
|
prev = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
(
|
||||||
|
Data {
|
||||||
|
start,
|
||||||
|
end: prev,
|
||||||
|
rules: map,
|
||||||
|
},
|
||||||
|
pairs,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn input() -> (Data, HashMap<(char, char), u64>) {
|
||||||
|
parse(include_str!("../input.txt"))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(
|
||||||
|
data: &Data,
|
||||||
|
pairs: &HashMap<(char, char), u64>,
|
||||||
|
steps: u8,
|
||||||
|
) -> HashMap<(char, char), u64> {
|
||||||
|
let mut pairs = pairs.clone();
|
||||||
|
for _ in 0..steps {
|
||||||
|
let mut after_step = HashMap::new();
|
||||||
|
for (&(c1, c2), &count) in pairs.iter() {
|
||||||
|
match data.rules.get(&(c1, c2)) {
|
||||||
|
None => {
|
||||||
|
after_step
|
||||||
|
.entry((c1, c2))
|
||||||
|
.and_modify(|x| *x += count)
|
||||||
|
.or_insert(count);
|
||||||
|
}
|
||||||
|
Some(&middle) => {
|
||||||
|
after_step
|
||||||
|
.entry((c1, middle))
|
||||||
|
.and_modify(|x| *x += count)
|
||||||
|
.or_insert(count);
|
||||||
|
after_step
|
||||||
|
.entry((middle, c2))
|
||||||
|
.and_modify(|x| *x += count)
|
||||||
|
.or_insert(count);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
pairs = after_step;
|
||||||
|
}
|
||||||
|
|
||||||
|
pairs
|
||||||
|
}
|
||||||
|
|
||||||
|
fn min_max<I, T, U>(mut iter: I, f: fn(T) -> U) -> Option<(T, T)>
|
||||||
|
where
|
||||||
|
I: Iterator<Item = T>,
|
||||||
|
T: Copy,
|
||||||
|
U: Ord + Copy,
|
||||||
|
{
|
||||||
|
let mut min_entry = iter.next()?;
|
||||||
|
let mut max_entry = min_entry;
|
||||||
|
let mut min = f(min_entry);
|
||||||
|
let mut max = min;
|
||||||
|
for entry in iter {
|
||||||
|
let f_val = f(entry);
|
||||||
|
if f_val < min {
|
||||||
|
min = f_val;
|
||||||
|
min_entry = entry;
|
||||||
|
} else if f_val > max {
|
||||||
|
max = f_val;
|
||||||
|
max_entry = entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some((min_entry, max_entry))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count(map: &HashMap<(char, char), u64>, start: char, end: char) -> HashMap<char, u64> {
|
||||||
|
let mut counts = HashMap::new();
|
||||||
|
for (&(c1, c2), &count) in map.iter() {
|
||||||
|
counts
|
||||||
|
.entry(c1)
|
||||||
|
.and_modify(|i| *i += count)
|
||||||
|
.or_insert(count);
|
||||||
|
counts
|
||||||
|
.entry(c2)
|
||||||
|
.and_modify(|i| *i += count)
|
||||||
|
.or_insert(count);
|
||||||
|
}
|
||||||
|
*counts.get_mut(&start).unwrap() += 1;
|
||||||
|
*counts.get_mut(&end).unwrap() += 1;
|
||||||
|
|
||||||
|
counts
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_1(data: &(Data, HashMap<(char, char), u64>)) -> u64 {
|
||||||
|
let map = run(&data.0, &data.1, 10);
|
||||||
|
let counts = count(&map, data.0.start, data.0.end);
|
||||||
|
match min_max(counts.iter(), |x| x.1) {
|
||||||
|
Some((min, max)) => max.1 / 2 - min.1 / 2,
|
||||||
|
None => panic!("Expected a nonempty map"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_2(data: &(Data, HashMap<(char, char), u64>)) -> u64 {
|
||||||
|
let map = run(&data.0, &data.1, 40);
|
||||||
|
let counts = count(&map, data.0.start, data.0.end);
|
||||||
|
match min_max(counts.iter(), |x| x.1) {
|
||||||
|
Some((min, max)) => max.1 / 2 - min.1 / 2,
|
||||||
|
None => panic!("Expected a nonempty map"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::day_14::*;
|
||||||
|
|
||||||
|
static TEST_INPUT: &str = "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";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_known() {
|
||||||
|
let data = parse(TEST_INPUT);
|
||||||
|
assert_eq!(part_1(&data), 1588);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_known() {
|
||||||
|
let data = parse(TEST_INPUT);
|
||||||
|
assert_eq!(part_2(&data), 2188189693529);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_day_14() {
|
||||||
|
let input = input();
|
||||||
|
assert_eq!(part_1(&input), 2549);
|
||||||
|
assert_eq!(part_2(&input), 2516901104210);
|
||||||
|
}
|
||||||
|
}
|
7
day_14/src/main.rs
Normal file
7
day_14/src/main.rs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
use day_14::day_14::{input, part_1, part_2};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input = input();
|
||||||
|
println!("part 1 => {}", part_1(&input));
|
||||||
|
println!("part 2 => {}", part_2(&input));
|
||||||
|
}
|
Reference in New Issue
Block a user