use std::collections::HashMap;
use std::io::{self, Read};
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
fn main() -> Result<()> {
let mut input = String::new();
io::stdin().read_to_string(&mut input)?;
part1(&input)?;
part2(&input)?;
Ok(())
}
fn part1(input: &str) -> Result<()> {
let mut hashmap: HashMap<i32, bool> = HashMap::new();
for line in input.lines() {
let num = line.parse::<i32>()?;
if hashmap.contains_key(&(2020 - num)) {
println!("{}", num * (2020 - num));
return Ok(());
} else {
hashmap.insert(num, true);
}
}
println!("No pairs found");
Ok(())
}
fn part2(input: &str) -> Result<()> {
let mut vec: Vec<i32> = Vec::new();
input
.lines()
.for_each(|line| vec.push(line.parse::<i32>().expect("should be able to parse")));
vec.sort();
for left_ptr in 0..vec.len() {
let mut mid_ptr = left_ptr + 1;
let mut right_ptr = vec.len() - 1;
loop {
let value_at_left = vec[left_ptr];
let value_at_mid = vec[mid_ptr];
let value_at_right = vec[right_ptr];
let sum = value_at_left + value_at_mid + value_at_right;
if sum == 2020 {
println!("{}", value_at_left * value_at_mid * value_at_right);
return Ok(());
}
if sum < 2020 {
mid_ptr += 1;
} else {
right_ptr -= 1;
}
}
}
Ok(())
}