use aoc_runner_derive::{aoc, aoc_generator}; use itertools::Itertools; const PREAMBLE_LEN: usize = 25; #[aoc_generator(day9)] fn parse(input: &str) -> Vec { input.lines().map(str::parse).map(Result::unwrap).collect_vec() } #[aoc(day9, part1)] fn part1(input: &Vec) -> u64 { for i in PREAMBLE_LEN..input.len() { if let None = input[i - PREAMBLE_LEN..i] .iter() .combinations(2) .find(|x| x.iter().cloned().sum::() == input[i]) { return input[i]; } } unreachable!() } #[aoc(day9, part2)] fn part2(input: &Vec) -> u64 { let to_find = part1(input); for len in 2..input.len() { if let Some(nums) = input .windows(len) .find(|x| x.iter().cloned().sum::() == to_find) { return nums.iter().min().unwrap() + nums.iter().max().unwrap(); } } unreachable!() } #[cfg(test)] mod tests { use super::*; const EX: &str = r"35 20 15 25 47 40 62 55 65 95 102 117 150 182 127 219 299 277 309 576"; #[test] fn part1_example() { assert_eq!(part1(&parse(EX)), 127); } #[test] fn part2_example() { assert_eq!(part2(&parse(EX)), 62); } }