solution: day 10 (ugly)

This commit is contained in:
YK 2024-11-20 13:13:46 +03:00
parent 27501c65ee
commit d3c1c39a68
2 changed files with 125 additions and 1 deletions

View File

@ -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;

124
src/days/d10.rs Normal file
View File

@ -0,0 +1,124 @@
use crate::prelude::*;
pub type I = (M<SS, Vec<u32>>, M<SS, (SS, SS)>);
pub type O = SS;
fn _parse (data: &'static str) -> I {
let mut initial: M<SS, Vec<u32>> = 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)
}
}