solution: day 10 (ugly)
This commit is contained in:
parent
27501c65ee
commit
d3c1c39a68
@ -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
124
src/days/d10.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user