2020-12-02 00:19:43 +00:00
|
|
|
use anyhow::{anyhow, Result};
|
|
|
|
|
2020-12-02 04:19:30 +00:00
|
|
|
use std::collections::HashSet;
|
2020-12-02 00:19:43 +00:00
|
|
|
use std::fs::File;
|
|
|
|
use std::io::prelude::*;
|
|
|
|
use std::io::BufReader;
|
|
|
|
|
|
|
|
const INPUT: &str = "input/input.txt";
|
|
|
|
|
2020-12-02 04:19:30 +00:00
|
|
|
fn solve_part1(input_path: &str) -> Result<i32> {
|
2020-12-02 00:19:43 +00:00
|
|
|
let file = File::open(input_path)?;
|
|
|
|
let reader = BufReader::new(file);
|
|
|
|
|
2020-12-02 04:19:30 +00:00
|
|
|
let mut prev_numbers = HashSet::new();
|
2020-12-02 00:19:43 +00:00
|
|
|
for line in reader.lines() {
|
2020-12-02 04:19:30 +00:00
|
|
|
let number: i32 = line?.parse()?;
|
|
|
|
let other_half = 2020 - number;
|
|
|
|
if prev_numbers.contains(&other_half) {
|
|
|
|
return Ok(number * other_half);
|
2020-12-02 00:19:43 +00:00
|
|
|
}
|
2020-12-02 04:19:30 +00:00
|
|
|
prev_numbers.insert(number);
|
2020-12-02 00:19:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Err(anyhow!("Found no pair of numbers that sums to 2020"))
|
|
|
|
}
|
|
|
|
|
2020-12-02 04:19:30 +00:00
|
|
|
fn solve_part2(input_path: &str) -> Result<i32> {
|
2020-12-02 00:19:43 +00:00
|
|
|
let file = File::open(input_path)?;
|
|
|
|
let reader = BufReader::new(file);
|
|
|
|
|
2020-12-02 04:19:30 +00:00
|
|
|
let mut prev_numbers = HashSet::new();
|
2020-12-02 00:19:43 +00:00
|
|
|
for line in reader.lines() {
|
2020-12-02 04:19:30 +00:00
|
|
|
let number: i32 = line?.parse()?;
|
|
|
|
for prev_number in prev_numbers.iter() {
|
|
|
|
let other_third = 2020 - prev_number - number;
|
|
|
|
if prev_numbers.contains(&other_third) {
|
|
|
|
return Ok(number * prev_number * other_third);
|
2020-12-02 00:19:43 +00:00
|
|
|
}
|
|
|
|
}
|
2020-12-02 04:19:30 +00:00
|
|
|
prev_numbers.insert(number);
|
2020-12-02 00:19:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Err(anyhow!("Found no three numbers that sum to 2020"))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
println!("Part 1: {}", solve_part1(INPUT).unwrap());
|
|
|
|
println!("Part 2: {}", solve_part2(INPUT).unwrap());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
const TEST_INPUT: &str = "input/test.txt";
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn solves_part1() {
|
|
|
|
assert_eq!(solve_part1(TEST_INPUT).unwrap(), 514579);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn solves_part2() {
|
|
|
|
assert_eq!(solve_part2(TEST_INPUT).unwrap(), 241861950);
|
|
|
|
}
|
|
|
|
}
|