72 lines
1.6 KiB
Rust
72 lines
1.6 KiB
Rust
|
use std::fs;
|
||
|
|
||
|
use itertools::Itertools;
|
||
|
|
||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||
|
let input = fs::read_to_string("input")?;
|
||
|
let input = parse_number_list(input)?;
|
||
|
let numbers = find_2020_numbers(input, 3)?;
|
||
|
println!("{}", numbers.iter().product::<u32>());
|
||
|
Ok(())
|
||
|
}
|
||
|
|
||
|
fn parse_number_list(input: String) -> Result<Vec<u32>, std::num::ParseIntError> {
|
||
|
input.lines().map(|line| line.parse::<u32>()).collect()
|
||
|
}
|
||
|
|
||
|
fn find_2020_numbers(input: Vec<u32>, sum_number: usize) -> Result<Vec<u32>, String> {
|
||
|
input
|
||
|
.into_iter()
|
||
|
.combinations(sum_number)
|
||
|
.find(|i| i.iter().sum::<u32>() == 2020)
|
||
|
.ok_or("Could not find 2020.".to_string())
|
||
|
}
|
||
|
|
||
|
#[cfg(test)]
|
||
|
mod tests {
|
||
|
use super::*;
|
||
|
use indoc::indoc;
|
||
|
|
||
|
#[test]
|
||
|
fn test_first_example() -> Result<(), Box<dyn std::error::Error>> {
|
||
|
let example = indoc!(
|
||
|
"
|
||
|
1721
|
||
|
979
|
||
|
366
|
||
|
299
|
||
|
675
|
||
|
1456
|
||
|
"
|
||
|
);
|
||
|
|
||
|
let example = parse_number_list(example.to_string())?;
|
||
|
let numbers = find_2020_numbers(example, 2)?;
|
||
|
|
||
|
assert_eq!(numbers.iter().product::<u32>(), 514579);
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_second_example() -> Result<(), Box<dyn std::error::Error>> {
|
||
|
let example = indoc!(
|
||
|
"
|
||
|
1721
|
||
|
979
|
||
|
366
|
||
|
299
|
||
|
675
|
||
|
1456
|
||
|
"
|
||
|
);
|
||
|
|
||
|
let example = parse_number_list(example.to_string())?;
|
||
|
let numbers = find_2020_numbers(example, 3)?;
|
||
|
|
||
|
assert_eq!(numbers.iter().to_owned().product::<u32>(), 241861950);
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
}
|