Completed day 9

This commit is contained in:
Tyler Hallada 2020-12-09 00:35:32 -05:00
parent 7ae27e5470
commit c2960e8ee1
5 changed files with 1142 additions and 0 deletions

14
day09/Cargo.lock generated Normal file
View File

@ -0,0 +1,14 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "anyhow"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c0df63cb2955042487fad3aefd2c6e3ae7389ac5dc1beb28921de0b69f779d4"
[[package]]
name = "day09"
version = "0.1.0"
dependencies = [
"anyhow",
]

10
day09/Cargo.toml Normal file
View File

@ -0,0 +1,10 @@
[package]
name = "day09"
version = "0.1.0"
authors = ["Tyler Hallada <tyler@hallada.net>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0"

1000
day09/input/input.txt Executable file

File diff suppressed because it is too large Load Diff

20
day09/input/test.txt Normal file
View File

@ -0,0 +1,20 @@
35
20
15
25
47
40
62
55
65
95
102
117
150
182
127
219
299
277
309
576

98
day09/src/main.rs Normal file
View File

@ -0,0 +1,98 @@
use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::time::Instant;
use anyhow::Result;
const INPUT: &str = "input/input.txt";
fn find_invalid_num(nums: &[usize], preamble: usize) -> Option<usize> {
if let Some(num) = nums.windows(preamble + 1).find(|chunk| {
for num in &chunk[0..preamble] {
for other_num in &chunk[0..preamble] {
if num != other_num && num + other_num == chunk[preamble] {
return false;
}
}
}
true
}) {
return Some(num[preamble]);
}
None
}
fn find_encryption_weakness(nums: &[usize], invalid_num: usize) -> Option<usize> {
let mut window_size = 2;
while window_size < 1000 {
if let Some(weakness) = nums
.windows(window_size)
.find(|chunk| chunk.iter().sum::<usize>() == invalid_num)
{
return Some(
weakness.iter().min().expect("non-empty slice")
+ weakness.iter().max().expect("non-empty slice"),
);
} else {
window_size += 1;
}
}
None
}
fn solve_part1(input_path: &str, preamble: usize) -> Result<usize> {
let file = File::open(input_path)?;
let reader = BufReader::new(file);
let nums = reader
.lines()
.map(|line| Ok(line?.parse()?))
.collect::<Result<Vec<usize>>>()?;
Ok(find_invalid_num(&nums, preamble).unwrap())
}
fn solve_part2(input_path: &str, invalid_num: usize) -> Result<usize> {
let file = File::open(input_path)?;
let reader = BufReader::new(file);
let nums = reader
.lines()
.map(|line| Ok(line?.parse()?))
.collect::<Result<Vec<usize>>>()?;
Ok(find_encryption_weakness(&nums, invalid_num).unwrap())
}
fn main() {
let mut now = Instant::now();
let part1 = solve_part1(INPUT, 25).unwrap();
println!("Part 1: {}", part1);
println!(
"(elapsed: {} ms)",
now.elapsed().as_micros() as f32 / 1000_f32
);
now = Instant::now();
println!("");
println!("Part 2: {}", solve_part2(INPUT, part1).unwrap());
println!(
"(elapsed: {} ms)",
now.elapsed().as_micros() as f32 / 1000_f32
);
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_INPUT: &str = "input/test.txt";
#[test]
fn solves_part1() {
assert_eq!(solve_part1(TEST_INPUT, 5).unwrap(), 127);
}
#[test]
fn solves_part2() {
assert_eq!(solve_part2(TEST_INPUT, 127).unwrap(), 62);
}
}