mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 12:50:32 +01:00
Implementation day 9.
This commit is contained in:
@@ -6,7 +6,6 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
clap = "3.0.0-beta.2"
|
||||
lazy_static = "*" # Pinned by regex
|
||||
regex = "1"
|
||||
|
||||
[profile.release]
|
||||
|
||||
1000
2020/inputs/09.txt
Normal file
1000
2020/inputs/09.txt
Normal file
File diff suppressed because it is too large
Load Diff
101
2020/src/day09.rs
Normal file
101
2020/src/day09.rs
Normal file
@@ -0,0 +1,101 @@
|
||||
use std::cmp::Ordering;
|
||||
use std::io::Read;
|
||||
|
||||
use crate::common::from_lines;
|
||||
use crate::Solution;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Day09;
|
||||
|
||||
fn is_possible(numbers: &[u64], number: u64) -> bool {
|
||||
for (i, &n) in numbers.iter().enumerate() {
|
||||
for m in &numbers[(i + 1)..] {
|
||||
if number == n + m {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn find_missing(numbers: &[u64], size: usize) -> Option<u64> {
|
||||
for window in numbers.windows(size + 1) {
|
||||
if !is_possible(&window[..size], window[size]) {
|
||||
return Some(window[size]);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn find_range(numbers: &[u64], target: u64) -> Option<(usize, usize)> {
|
||||
let mut sums = Vec::with_capacity(numbers.len() + 1);
|
||||
sums.push(0);
|
||||
sums.extend_from_slice(numbers);
|
||||
|
||||
// Compute cumulative sums
|
||||
for i in 1..numbers.len() {
|
||||
sums[i] += sums[i - 1];
|
||||
}
|
||||
|
||||
let mut i = 0;
|
||||
let mut j = 1;
|
||||
|
||||
while i < sums.len() && j < sums.len() && numbers[j] < target {
|
||||
let current = sums[j] - sums[i];
|
||||
|
||||
match current.cmp(&target) {
|
||||
Ordering::Less => j += 1,
|
||||
Ordering::Equal => return Some((i, j - 1)),
|
||||
Ordering::Greater => i += 1,
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
impl Solution for Day09 {
|
||||
fn part1(&mut self, input: &mut dyn Read) -> String {
|
||||
let numbers: Vec<u64> = from_lines(input);
|
||||
|
||||
find_missing(&numbers, 25).unwrap().to_string()
|
||||
}
|
||||
|
||||
fn part2(&mut self, input: &mut dyn Read) -> String {
|
||||
let numbers: Vec<u64> = from_lines(input);
|
||||
|
||||
let target = find_missing(&numbers, 25).unwrap();
|
||||
|
||||
let (first, last) = find_range(&numbers, target).unwrap();
|
||||
|
||||
let range = &numbers[first..=last];
|
||||
|
||||
let min = range.iter().min().unwrap();
|
||||
let max = range.iter().max().unwrap();
|
||||
|
||||
(min + max).to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const NUMBERS: &[u64] = &[
|
||||
35, 20, 15, 25, 47, 40, 62, 55, 65, 95, 102, 117, 150, 182, 127, 219, 299, 277, 309, 576,
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(Some(127), find_missing(NUMBERS, 5));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
let (first, last) = find_range(NUMBERS, 127).unwrap();
|
||||
|
||||
assert_eq!(NUMBERS[first], 15);
|
||||
assert_eq!(NUMBERS[last], 40);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ mod day05;
|
||||
mod day06;
|
||||
mod day07;
|
||||
mod day08;
|
||||
mod day09;
|
||||
|
||||
pub trait Solution {
|
||||
fn part1(&mut self, input: &mut dyn Read) -> String;
|
||||
@@ -28,6 +29,7 @@ pub fn get_implementation(day: usize) -> Box<dyn Solution> {
|
||||
6 => Box::new(day06::Day06::default()),
|
||||
7 => Box::new(day07::Day07::default()),
|
||||
8 => Box::new(day08::Day08::default()),
|
||||
9 => Box::new(day09::Day09::default()),
|
||||
_ => panic!("Unsupported day {}", day),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user