2020-12-08 11:32:59 +01:00
#![ feature(test, bool_to_option) ]
2020-12-02 00:50:00 +01:00
extern crate test ;
2020-12-10 14:44:42 +01:00
use aoc2020 ::common ::* ;
2020-12-01 08:02:29 +01:00
use itertools ::Itertools ;
2020-12-01 07:16:56 +01:00
2020-12-10 14:01:25 +01:00
fn read_input ( ) -> String {
2020-12-10 14:44:42 +01:00
read_file ( 1 )
2020-12-10 14:01:25 +01:00
}
fn parse_input ( input : & str ) -> Vec < usize > {
input . lines ( ) . filter_map ( | l | l . parse ( ) . ok ( ) ) . collect ( )
2020-12-02 00:50:00 +01:00
}
2020-12-04 18:36:43 +01:00
fn part1 ( input : & [ usize ] ) -> usize {
2020-12-02 00:50:00 +01:00
input
2020-12-01 08:02:29 +01:00
. iter ( )
. tuple_combinations ( )
2020-12-01 23:54:58 +01:00
. find_map ( | ( & a , & b ) | ( a + b = = 2020 ) . then_some ( a * b ) )
2020-12-02 00:50:00 +01:00
. unwrap ( )
}
2020-12-01 23:54:58 +01:00
2020-12-04 18:36:43 +01:00
fn part2 ( input : & [ usize ] ) -> usize {
2020-12-02 00:50:00 +01:00
let mut p2_table = [ None ; 2020 ] ;
2020-12-01 08:02:29 +01:00
for ( & a , & b ) in input . iter ( ) . tuple_combinations ( ) {
2020-12-01 07:16:56 +01:00
if a + b < 2020 {
p2_table [ a + b ] = Some ( ( a , b ) )
}
}
2020-12-01 23:54:58 +01:00
let ( a , b ) = input . iter ( ) . find_map ( | x | p2_table [ 2020 - x ] ) . unwrap ( ) ;
2020-12-04 18:36:43 +01:00
a * b * ( 2020 - a - b )
2020-12-02 00:50:00 +01:00
}
fn main ( ) {
2020-12-10 14:01:25 +01:00
let input = parse_input ( & read_input ( ) ) ;
2020-12-02 00:50:00 +01:00
println! ( " Part 1: {} " , part1 ( & input ) ) ;
println! ( " Part 2: {} " , part2 ( & input ) ) ;
}
#[ cfg(test) ]
mod tests {
use super ::* ;
2020-12-10 14:01:25 +01:00
use aoc2020 ::* ;
use paste ::paste ;
use test ::black_box ;
2020-12-02 00:50:00 +01:00
2020-12-10 16:41:54 +01:00
bench! ( part1 ( ) = = 731731 ) ;
bench! ( part2 ( ) = = 116115990 ) ;
2020-12-01 07:16:56 +01:00
}