2023-12-02 10:14:10 +01:00
#![ feature(test) ]
extern crate test ;
use aoc2023 ::{ boilerplate , common ::* } ;
const DAY : usize = 2 ;
type Parsed = Vec < Vec < Pull > > ;
#[ derive(Debug) ]
struct Pull {
red : usize ,
green : usize ,
blue : usize ,
}
fn parse_input ( raw : & str ) -> Parsed {
raw . lines ( )
. map ( | l | {
l . after ( " : " )
. split ( " ; " )
. map ( | p | p . split ( " , " ) . map ( | b | b . split_once ( ' ' ) . unwrap ( ) ) . collect ( ) )
. map ( | ps : Vec < _ > | Pull { red : find_color ( & ps , " red " ) , green : find_color ( & ps , " green " ) , blue : find_color ( & ps , " blue " ) } )
. collect ( )
} )
. collect ( )
}
fn find_color ( ps : & [ ( & str , & str ) ] , color : & str ) -> usize {
ps . iter ( ) . find_map ( | ( n , c ) | ( * c = = color ) . then ( | | parse_num ( n ) ) ) . unwrap_or ( 0 )
}
fn part1 ( parsed : & Parsed ) -> usize {
parsed . iter ( ) . zip ( 1 .. ) . filter_map ( | ( ps , n ) | ps . iter ( ) . all ( | p | p . red < = 12 & & p . green < = 13 & & p . blue < = 14 ) . then_some ( n ) ) . sum ( )
}
fn part2 ( parsed : & Parsed ) -> usize {
parsed
. iter ( )
. map ( | ps | {
ps . iter ( ) . max_by_key ( | p | p . red ) . unwrap ( ) . red
* ps . iter ( ) . max_by_key ( | p | p . green ) . unwrap ( ) . green
* ps . iter ( ) . max_by_key ( | p | p . blue ) . unwrap ( ) . blue
} )
. sum ( )
}
boilerplate! {
TEST_INPUT = = " \
Game 1 : 3 blue , 4 red ; 1 red , 2 green , 6 blue ; 2 green
Game 2 : 1 blue , 2 green ; 3 green , 4 blue , 1 red ; 1 green , 1 blue
Game 3 : 8 green , 6 blue , 20 red ; 5 blue , 4 red , 13 green ; 5 green , 1 red
Game 4 : 1 green , 3 red , 6 blue ; 3 green , 6 red ; 3 green , 15 blue , 14 red
2023-12-13 09:30:03 +01:00
Game 5 : 6 red , 1 blue , 3 green ; 2 blue , 1 red , 2 green "
for tests : {
2023-12-02 10:14:10 +01:00
part1 : { TEST_INPUT = > 8 } ,
part2 : { TEST_INPUT = > 2286 } ,
} ,
bench1 = = 2207 ,
bench2 = = 62241 ,
bench_parse : Vec ::len = > 100 ,
}