diff --git a/src/days.rs b/src/days.rs index a44c1c7..fa88115 100644 --- a/src/days.rs +++ b/src/days.rs @@ -4,7 +4,7 @@ pub mod d3; pub mod d4; pub mod d5; pub mod d6; -// pub mod d7; +pub mod d7; // pub mod d8; // pub mod d9; // pub mod d10; diff --git a/src/days/d7.rs b/src/days/d7.rs new file mode 100644 index 0000000..fa48989 --- /dev/null +++ b/src/days/d7.rs @@ -0,0 +1,81 @@ +use crate::prelude::*; + +pub type I = Vec<(SS, Vec, Vec)>; +pub type O = usize; + +fn _parse (data: &'static str) -> I { + data.lines().map(|line| { + let line = line.trim(); + let mut out = vec![]; + let mut _in = vec![]; + let mut pos = false; + + let mut l = 0; + let mut r = 0; + + for (idx, c) in line.char_indices() { + + match c { + '[' | ']' => { + let v = if pos { &mut _in } else { &mut out }; + v.push(&line[l..r]); + pos = !pos; + l = idx + 1; + r = l; + continue; + }, + _ => { + r += 1; + } + } + } + + let v = if pos { &mut _in } else { &mut out }; + v.push(&line[l..r]); + + (line, _in, out) + }).collect() +} + +fn _silver (data: &I) -> O { + let abba = |(a, b, c, d)| a == d && b == c && b != a; + data.into_iter().filter(|(_, _in, out)| { + !_in.into_iter().any(|part| part.chars().tuple_windows().any(abba)) && + out.into_iter().any(|part| part.chars().tuple_windows().any(abba)) + }).count() +} + +fn _gold (data: &I) -> O { + let aba = |(a, b, c)| a == c && b != a; + data.into_iter().filter(|(_, _in, out)| { + let mut abas = S::new(); + out.into_iter().for_each(|part| part.chars().tuple_windows().for_each(|x| if aba(x) { abas.insert(x); })); + _in.into_iter().any(|part| part.chars().tuple_windows().any(|x @ (a, b, _)| aba(x) && abas.contains(&(b, a, b)))) + }).count() +} + +#[cfg(test)] +mod test { + use super::*; + + fn read () -> I { + let data = inc!(7); + _parse(data) + } + + #[test] + fn silver () { + let data = read(); + let ans = _silver(&data); + + assert_eq!(ans, 105) + } + + #[test] + fn gold () { + let data = read(); + let ans = _gold(&data); + + assert_eq!(ans, 258) + } +}