My (hacky) solution to 2020 Advent of Code Challenge in Rust
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(())
}