73 lines
1.2 KiB
Rust
73 lines
1.2 KiB
Rust
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||
|
use itertools::Itertools;
|
||
|
|
||
|
const PREAMBLE_LEN: usize = 25;
|
||
|
|
||
|
#[aoc_generator(day9)]
|
||
|
fn parse(input: &str) -> Vec<u64> {
|
||
|
input.lines().map(str::parse).map(Result::unwrap).collect_vec()
|
||
|
}
|
||
|
|
||
|
#[aoc(day9, part1)]
|
||
|
fn part1(input: &Vec<u64>) -> 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::<u64>() == input[i]) {
|
||
|
return input[i];
|
||
|
}
|
||
|
}
|
||
|
unreachable!()
|
||
|
}
|
||
|
|
||
|
#[aoc(day9, part2)]
|
||
|
fn part2(input: &Vec<u64>) -> 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::<u64>() == 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);
|
||
|
}
|
||
|
}
|