From d3c1c39a68cdc15e5fc21a98e00826a544647c82 Mon Sep 17 00:00:00 2001 From: YK Date: Wed, 20 Nov 2024 13:13:46 +0300 Subject: [PATCH] solution: day 10 (ugly) --- src/days.rs | 2 +- src/days/d10.rs | 124 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 src/days/d10.rs diff --git a/src/days.rs b/src/days.rs index 18c513c..7f0258a 100644 --- a/src/days.rs +++ b/src/days.rs @@ -7,7 +7,7 @@ pub mod d6; pub mod d7; pub mod d8; pub mod d9; -// pub mod d10; +pub mod d10; // pub mod d11; // pub mod d12; // pub mod d13; diff --git a/src/days/d10.rs b/src/days/d10.rs new file mode 100644 index 0000000..c79cc16 --- /dev/null +++ b/src/days/d10.rs @@ -0,0 +1,124 @@ +use crate::prelude::*; + +pub type I = (M>, M); +pub type O = SS; + +fn _parse (data: &'static str) -> I { + let mut initial: M> = M::new(); + let mut maps = M::new(); + + for line in data.lines() { + if let Some(sfx) = line.strip_prefix("value ") { + let (val, out) = sfx.split_once(" goes to bot ").map(|(v, b)| (v.parse().unwrap(), b)).unwrap(); + initial.entry(out).or_default().push(val); + } else { + let line = line.trim_start_matches("bot "); + let (source, dests) = line.split_once(" gives low to ").unwrap(); + let (l, h) = dests.split_once(" and high to ").unwrap(); + + let l = l.strip_prefix("bot ").unwrap_or(l); + let h = h.strip_prefix("bot ").unwrap_or(h); + + maps.insert(source, (l, h)); + } + } + + (initial, maps) +} + +#[allow(suspicious_double_ref_op)] +fn _silver ((mut state, map): I) -> O { + let mut cur = state.iter().find(|e| e.1.len() == 2).unwrap().0.clone(); + + loop { + let chips = state.entry(cur).or_default(); + + let a = chips[0]; + let b = chips[1]; + + chips.clear(); + + if (a == 17 && b == 61) || (b == 17 && a == 61) { return cur; } + + let (low, high) = map.get(cur).unwrap(); + + let l_entry = state.entry(low).or_default(); + l_entry.push(if a > b { b } else { a }); + let l_len = l_entry.len(); + + let h_entry = state.entry(high).or_default(); + h_entry.push(if a > b { a } else { b }); + let h_len = h_entry.len(); + + + cur = if l_len == 2 { + low + } else if h_len == 2 { + high + } else { + state.iter().find(|e| e.1.len() == 2).unwrap().0 + } + } +} + +#[allow(suspicious_double_ref_op)] +fn _gold ((mut state, map): I) -> u32 { + let mut cur = state.iter().find(|e| e.1.len() == 2).unwrap().0.clone(); + + loop { + let chips = state.entry(cur).or_default(); + + let a = chips[0]; + let b = chips[1]; + + chips.clear(); + + let (low, high) = map.get(cur).unwrap(); + + let l_entry = state.entry(low).or_default(); + l_entry.push(if a > b { b } else { a }); + let l_len = l_entry.len(); + + let h_entry = state.entry(high).or_default(); + h_entry.push(if a > b { a } else { b }); + let h_len = h_entry.len(); + + if let Some(a) = state.get("output 0") && let Some(b) = state.get("output 1") && let Some(c) = state.get("output 2") { + return a[0] * b[0] * c[0] + } + + cur = if l_len == 2 { + low + } else if h_len == 2 { + high + } else { + state.iter().find(|e| e.1.len() == 2).unwrap().0 + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + fn read () -> I { + let data = inc!(10); + _parse(data) + } + + #[test] + fn silver () { + let data = read(); + let ans = _silver(data); + + assert_eq!(ans, s!(116)) + } + + #[test] + fn gold () { + let data = read(); + let ans = _gold(data); + + assert_eq!(ans, 23903) + } +}