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) {
|
||||
if let Some(e) = hm.get_mut(&(xn, yn)) {
|
||||
*e += 1;
|
||||
if *e > 9 {
|
||||
if !flashed.contains(&(xn, yn)) && !flashing.contains(&(xn, yn)) {
|
||||
flashing.push((xn, yn))
|
||||
}
|
||||
if *e > 9 && !flashed.contains(&(xn, yn)) && !flashing.contains(&(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 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);
|
||||
}
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ impl Day for Day12 {
|
|||
Ok(format!("{}", self.search("start", &m, false)))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Ord, PartialOrd, Eq, PartialEq, Copy, Clone)]
|
||||
enum CaveType {
|
||||
Large,
|
||||
|
@ -55,7 +56,7 @@ impl Cave {
|
|||
}
|
||||
|
||||
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
|
||||
} else {
|
||||
CaveType::Small
|
||||
|
@ -70,10 +71,8 @@ impl Cave {
|
|||
impl Day12 {
|
||||
fn search(&self, cur: &str, had: &HashMap<String, i32>, part1: bool) -> i32 {
|
||||
let mut had = had.clone();
|
||||
if had.values().any(|&i| i > 1) || part1 {
|
||||
if had.contains_key(cur) {
|
||||
return 0;
|
||||
}
|
||||
if (had.values().any(|&i| i > 1) || part1) && had.contains_key(cur) {
|
||||
return 0;
|
||||
}
|
||||
if cur == "start" && had.contains_key("start") {
|
||||
return 0;
|
||||
|
@ -86,7 +85,7 @@ impl Day12 {
|
|||
let e = had.entry(cur.into()).or_insert(0);
|
||||
*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 = ();
|
||||
|
||||
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<_>>();
|
||||
match z[0] {
|
||||
"x" => Ok(Fold::X(z[1].parse().map_err(|_| ())?)),
|
||||
|
@ -31,7 +31,7 @@ impl FromStr for Fold {
|
|||
impl Day for Day13 {
|
||||
fn init(content: String) -> anyhow::Result<Self> {
|
||||
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<_>>();
|
||||
|
||||
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::day12::Day12;
|
||||
use crate::day13::Day13;
|
||||
use crate::day14::Day14;
|
||||
|
||||
mod day;
|
||||
mod day01;
|
||||
|
@ -31,6 +32,7 @@ mod day10;
|
|||
mod day11;
|
||||
mod day12;
|
||||
mod day13;
|
||||
mod day14;
|
||||
|
||||
fn load_input(day: &str) -> Result<String> {
|
||||
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(Day11::init(load_input("11")?)?),
|
||||
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");
|
||||
if matches.is_present("all") {
|
||||
|
|
Loading…
Reference in a new issue