use aoc_runner_derive::aoc; use itertools::Itertools; use std::io::BufRead; // PROBLEM 1 solution #[aoc(day6, part1)] fn part1(input: &[u8]) -> u64 { let s = input.lines().next().unwrap().unwrap(); s.as_bytes() .windows(4) .enumerate() .find_map(|(i, window)| { if window[1..4].iter().all(|c| *c != window[0]) && window[2..4].iter().all(|c| *c != window[1]) && window[2] != window[3] { println!( "Unique window: {:?} at {}", window.iter().map(|c| *c as char).collect_vec(), i ); Some(i + 4) } else { None } }) .unwrap() as u64 } // PROBLEM 2 solution #[aoc(day6, part2)] fn part2(input: &[u8]) -> u64 { let s = input.lines().next().unwrap().unwrap(); let size = 14; s.as_bytes() .windows(size) .enumerate() .find_map(|(i, window)| { for i in 1..size { let shifted = &window[i..]; if shifted.iter().enumerate().any(|(j, c)| *c == window[j]) { return None; } } return Some(i + 14); }) .unwrap() as u64 } #[cfg(test)] mod tests { use crate::day6::*; const EXAMPLE1: &[u8] = b"bvwbjplbgvbhsrlpgdmjqwftvncz"; const EXAMPLE2: &[u8] = b"nppdvjthqldpwncqszvftbrmjlhg"; const EXAMPLE3: &[u8] = b"nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg"; const EXAMPLE4: &[u8] = b"zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw"; #[test] fn problem1_example() { assert_eq!(part1(EXAMPLE1), 5); assert_eq!(part1(EXAMPLE2), 6); assert_eq!(part1(EXAMPLE3), 10); assert_eq!(part1(EXAMPLE4), 11); } #[test] fn problem2_example() { assert_eq!(part2(EXAMPLE1), 23); assert_eq!(part2(EXAMPLE2), 23); assert_eq!(part2(EXAMPLE3), 29); assert_eq!(part2(EXAMPLE4), 26); } }