This commit is contained in:
parent
7710d82945
commit
3a00251b3c
102
input/day14
Normal file
102
input/day14
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
OHFNNCKCVOBHSSHONBNF
|
||||||
|
|
||||||
|
SV -> O
|
||||||
|
KP -> H
|
||||||
|
FP -> B
|
||||||
|
VP -> V
|
||||||
|
KN -> S
|
||||||
|
KS -> O
|
||||||
|
SB -> K
|
||||||
|
BS -> K
|
||||||
|
OF -> O
|
||||||
|
ON -> S
|
||||||
|
VS -> F
|
||||||
|
CK -> C
|
||||||
|
FB -> K
|
||||||
|
CH -> K
|
||||||
|
HS -> H
|
||||||
|
PO -> F
|
||||||
|
NP -> N
|
||||||
|
FH -> C
|
||||||
|
FO -> O
|
||||||
|
FF -> C
|
||||||
|
CO -> K
|
||||||
|
NB -> V
|
||||||
|
PP -> S
|
||||||
|
BB -> N
|
||||||
|
HH -> B
|
||||||
|
KK -> H
|
||||||
|
OP -> K
|
||||||
|
OS -> V
|
||||||
|
KV -> F
|
||||||
|
VH -> F
|
||||||
|
OB -> S
|
||||||
|
CN -> H
|
||||||
|
SF -> K
|
||||||
|
SN -> P
|
||||||
|
NF -> H
|
||||||
|
HB -> V
|
||||||
|
VC -> S
|
||||||
|
PS -> P
|
||||||
|
NK -> B
|
||||||
|
CV -> P
|
||||||
|
BC -> S
|
||||||
|
NH -> K
|
||||||
|
FN -> P
|
||||||
|
SH -> F
|
||||||
|
FK -> P
|
||||||
|
CS -> O
|
||||||
|
VV -> H
|
||||||
|
OC -> F
|
||||||
|
CC -> N
|
||||||
|
HK -> N
|
||||||
|
FS -> P
|
||||||
|
VF -> B
|
||||||
|
SS -> V
|
||||||
|
PV -> V
|
||||||
|
BF -> V
|
||||||
|
OV -> C
|
||||||
|
HO -> F
|
||||||
|
NC -> F
|
||||||
|
BN -> F
|
||||||
|
HC -> N
|
||||||
|
KO -> P
|
||||||
|
KH -> F
|
||||||
|
BV -> S
|
||||||
|
SK -> F
|
||||||
|
SC -> F
|
||||||
|
VN -> V
|
||||||
|
VB -> V
|
||||||
|
BH -> O
|
||||||
|
CP -> K
|
||||||
|
PK -> K
|
||||||
|
PB -> K
|
||||||
|
FV -> S
|
||||||
|
HN -> K
|
||||||
|
PH -> B
|
||||||
|
VK -> B
|
||||||
|
PC -> H
|
||||||
|
BO -> H
|
||||||
|
SP -> V
|
||||||
|
NS -> B
|
||||||
|
OH -> N
|
||||||
|
KC -> H
|
||||||
|
HV -> F
|
||||||
|
HF -> B
|
||||||
|
HP -> S
|
||||||
|
CB -> P
|
||||||
|
PN -> S
|
||||||
|
BK -> K
|
||||||
|
PF -> N
|
||||||
|
SO -> P
|
||||||
|
CF -> B
|
||||||
|
VO -> C
|
||||||
|
OO -> K
|
||||||
|
FC -> F
|
||||||
|
NV -> F
|
||||||
|
OK -> K
|
||||||
|
NN -> O
|
||||||
|
NO -> O
|
||||||
|
BP -> O
|
||||||
|
KB -> O
|
||||||
|
KF -> O
|
|
@ -69,10 +69,8 @@ fn do_flash(mut hm: &mut FlashMap, mut flashing: &mut Vec<(i32, i32)>, mut flash
|
||||||
for yn in (y - 1)..=(y + 1) {
|
for yn in (y - 1)..=(y + 1) {
|
||||||
if let Some(e) = hm.get_mut(&(xn, yn)) {
|
if let Some(e) = hm.get_mut(&(xn, yn)) {
|
||||||
*e += 1;
|
*e += 1;
|
||||||
if *e > 9 {
|
if *e > 9 && !flashed.contains(&(xn, yn)) && !flashing.contains(&(xn, yn)) {
|
||||||
if !flashed.contains(&(xn, yn)) && !flashing.contains(&(xn, yn)) {
|
flashing.push((xn, yn))
|
||||||
flashing.push((xn, yn))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
src/day12.rs
15
src/day12.rs
|
@ -13,11 +13,11 @@ impl Day for Day12 {
|
||||||
let second = z[1];
|
let second = z[1];
|
||||||
|
|
||||||
{
|
{
|
||||||
let first_cave = caves.entry(first.to_string()).or_insert(Cave::new(first.into()));
|
let first_cave = caves.entry(first.to_string()).or_insert_with(|| Cave::new(first.into()));
|
||||||
first_cave.add_connection(second);
|
first_cave.add_connection(second);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let second_cave = caves.entry(second.to_string()).or_insert(Cave::new(second.into()));
|
let second_cave = caves.entry(second.to_string()).or_insert_with(|| Cave::new(second.into()));
|
||||||
second_cave.add_connection(first);
|
second_cave.add_connection(first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ impl Day for Day12 {
|
||||||
Ok(format!("{}", self.search("start", &m, false)))
|
Ok(format!("{}", self.search("start", &m, false)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Ord, PartialOrd, Eq, PartialEq, Copy, Clone)]
|
#[derive(Ord, PartialOrd, Eq, PartialEq, Copy, Clone)]
|
||||||
enum CaveType {
|
enum CaveType {
|
||||||
Large,
|
Large,
|
||||||
|
@ -55,7 +56,7 @@ impl Cave {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(cave_name: String) -> Self {
|
fn new(cave_name: String) -> Self {
|
||||||
let cave_type = if cave_name.chars().nth(0).unwrap().is_uppercase() {
|
let cave_type = if cave_name.chars().next().unwrap().is_uppercase() {
|
||||||
CaveType::Large
|
CaveType::Large
|
||||||
} else {
|
} else {
|
||||||
CaveType::Small
|
CaveType::Small
|
||||||
|
@ -70,10 +71,8 @@ impl Cave {
|
||||||
impl Day12 {
|
impl Day12 {
|
||||||
fn search(&self, cur: &str, had: &HashMap<String, i32>, part1: bool) -> i32 {
|
fn search(&self, cur: &str, had: &HashMap<String, i32>, part1: bool) -> i32 {
|
||||||
let mut had = had.clone();
|
let mut had = had.clone();
|
||||||
if had.values().any(|&i| i > 1) || part1 {
|
if (had.values().any(|&i| i > 1) || part1) && had.contains_key(cur) {
|
||||||
if had.contains_key(cur) {
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if cur == "start" && had.contains_key("start") {
|
if cur == "start" && had.contains_key("start") {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -86,7 +85,7 @@ impl Day12 {
|
||||||
let e = had.entry(cur.into()).or_insert(0);
|
let e = had.entry(cur.into()).or_insert(0);
|
||||||
*e += 1;
|
*e += 1;
|
||||||
}
|
}
|
||||||
return n.connections.iter().map(|c| self.search(c, &mut had, part1)).sum::<i32>();
|
return n.connections.iter().map(|c| self.search(c, &had, part1)).sum::<i32>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ impl FromStr for Fold {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
let r = s.rsplit(' ').nth(0).ok_or_else(|| ())?;
|
let r = s.rsplit(' ').next().ok_or(())?;
|
||||||
let z = r.split('=').collect::<Vec<_>>();
|
let z = r.split('=').collect::<Vec<_>>();
|
||||||
match z[0] {
|
match z[0] {
|
||||||
"x" => Ok(Fold::X(z[1].parse().map_err(|_| ())?)),
|
"x" => Ok(Fold::X(z[1].parse().map_err(|_| ())?)),
|
||||||
|
@ -31,7 +31,7 @@ impl FromStr for Fold {
|
||||||
impl Day for Day13 {
|
impl Day for Day13 {
|
||||||
fn init(content: String) -> anyhow::Result<Self> {
|
fn init(content: String) -> anyhow::Result<Self> {
|
||||||
let l = content.lines();
|
let l = content.lines();
|
||||||
let points = l.clone().take_while(|&x| x != "").map(|st| st.split(',')
|
let points = l.clone().take_while(|&x| !x.is_empty()).map(|st| st.split(',')
|
||||||
.map(str::parse).flatten().collect::<Vec<i32>>()).map(|v| (v[0], v[1])).collect::<HashSet<_>>();
|
.map(str::parse).flatten().collect::<Vec<i32>>()).map(|v| (v[0], v[1])).collect::<HashSet<_>>();
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
|
149
src/day14.rs
Normal file
149
src/day14.rs
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use crate::Day;
|
||||||
|
|
||||||
|
type ReplacementMap = HashMap<String, Vec<String>>;
|
||||||
|
|
||||||
|
pub struct Day14 {
|
||||||
|
start: HashMap<String, u64>,
|
||||||
|
end: char,
|
||||||
|
replacements: ReplacementMap,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Day for Day14 {
|
||||||
|
fn init(content: String) -> anyhow::Result<Self> {
|
||||||
|
let mut line_iter = content.lines().peekable();
|
||||||
|
let input: Vec<char> = line_iter.next().unwrap().chars().collect();
|
||||||
|
let mut start = HashMap::new();
|
||||||
|
for i in 0..input.len() - 1 {
|
||||||
|
let pair = format!("{}{}", input[i], input[i + 1]);
|
||||||
|
let count = start.entry(pair).or_insert(0);
|
||||||
|
*count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
line_iter.next();
|
||||||
|
|
||||||
|
let mut replacements = HashMap::new();
|
||||||
|
for line in line_iter {
|
||||||
|
let cap = line.split(" -> ").collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let pair = cap[0].to_string();
|
||||||
|
let output = cap[1].to_string().chars().next().unwrap();
|
||||||
|
replacements.insert(
|
||||||
|
pair.clone(),
|
||||||
|
vec![
|
||||||
|
format!("{}{}", pair.chars().next().unwrap(), output),
|
||||||
|
format!("{}{}", output, pair.chars().nth(1).unwrap()),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
start,
|
||||||
|
replacements,
|
||||||
|
end: *input.last().unwrap(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(&self) -> anyhow::Result<String> {
|
||||||
|
Ok(format!("{}", self.iterate(10)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(&self) -> anyhow::Result<String> {
|
||||||
|
Ok(format!("{}", self.iterate(40)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Day14 {
|
||||||
|
fn iterate(&self, amount: u64) -> u64 {
|
||||||
|
let mut s = self.start.clone();
|
||||||
|
for _ in 0..amount {
|
||||||
|
s = do_pain(&s, &self.replacements);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut counts: HashMap<char, u64> = HashMap::new();
|
||||||
|
for (st, b) in s {
|
||||||
|
{
|
||||||
|
let e = counts.entry(st.chars().next().unwrap()).or_insert(0);
|
||||||
|
*e += b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let e = counts.entry(self.end).or_insert(0);
|
||||||
|
*e += 1;
|
||||||
|
}
|
||||||
|
let mut min = u64::MAX;
|
||||||
|
let mut max = 0;
|
||||||
|
for &count in counts.values() {
|
||||||
|
min = min.min(count);
|
||||||
|
max = max.max(count);
|
||||||
|
}
|
||||||
|
max - min
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_pain(input: &HashMap<String, u64>, map: &ReplacementMap) -> HashMap<String, u64> {
|
||||||
|
let mut output_map = HashMap::new();
|
||||||
|
for (pair, &count) in input {
|
||||||
|
let new_pairs = map.get(pair).unwrap();
|
||||||
|
|
||||||
|
for new_pair in new_pairs {
|
||||||
|
let output_count = output_map.entry(new_pair.to_string()).or_insert(0);
|
||||||
|
*output_count += count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output_map
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::day14::Day14;
|
||||||
|
use crate::day::Day;
|
||||||
|
|
||||||
|
const INPUT: &str = r"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_test() -> anyhow::Result<()> {
|
||||||
|
let d = Day14::init(INPUT.to_string())?;
|
||||||
|
assert_eq!("1588", d.part1()?);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_test() -> anyhow::Result<()> {
|
||||||
|
let d = Day14::init(INPUT.to_string())?;
|
||||||
|
assert_eq!("2188189693529", d.part2()?);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_real() -> anyhow::Result<()> {
|
||||||
|
let d = Day14::init(crate::load_input("14")?)?;
|
||||||
|
assert_eq!("2590", d.part1()?);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_real() -> anyhow::Result<()> {
|
||||||
|
let d = Day14::init(crate::load_input("14")?)?;
|
||||||
|
assert_eq!("2875665202438", d.part2()?);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ use crate::day10::Day10;
|
||||||
use crate::day11::Day11;
|
use crate::day11::Day11;
|
||||||
use crate::day12::Day12;
|
use crate::day12::Day12;
|
||||||
use crate::day13::Day13;
|
use crate::day13::Day13;
|
||||||
|
use crate::day14::Day14;
|
||||||
|
|
||||||
mod day;
|
mod day;
|
||||||
mod day01;
|
mod day01;
|
||||||
|
@ -31,6 +32,7 @@ mod day10;
|
||||||
mod day11;
|
mod day11;
|
||||||
mod day12;
|
mod day12;
|
||||||
mod day13;
|
mod day13;
|
||||||
|
mod day14;
|
||||||
|
|
||||||
fn load_input(day: &str) -> Result<String> {
|
fn load_input(day: &str) -> Result<String> {
|
||||||
read_to_string(format!("./input/day{}", day)).map_err(|x| x.into())
|
read_to_string(format!("./input/day{}", day)).map_err(|x| x.into())
|
||||||
|
@ -78,7 +80,8 @@ fn main() -> anyhow::Result<()> {
|
||||||
Box::new(Day10::init(load_input("10")?)?),
|
Box::new(Day10::init(load_input("10")?)?),
|
||||||
Box::new(Day11::init(load_input("11")?)?),
|
Box::new(Day11::init(load_input("11")?)?),
|
||||||
Box::new(Day12::init(load_input("12")?)?),
|
Box::new(Day12::init(load_input("12")?)?),
|
||||||
Box::new(Day13::init(load_input("13")?)?),];
|
Box::new(Day13::init(load_input("13")?)?),
|
||||||
|
Box::new(Day14::init(load_input("14")?)?),];
|
||||||
|
|
||||||
let _verbosity = matches.occurrences_of("v");
|
let _verbosity = matches.occurrences_of("v");
|
||||||
if matches.is_present("all") {
|
if matches.is_present("all") {
|
||||||
|
|
Loading…
Reference in a new issue