Implementation day 9.

This commit is contained in:
2020-12-09 09:08:42 +01:00
parent e5edecba46
commit 033a3ef512
4 changed files with 1103 additions and 1 deletions

View File

@@ -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

File diff suppressed because it is too large Load Diff

101
2020/src/day09.rs Normal file
View 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);
}
}

View File

@@ -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),
}
}