1- use std:: fs;
2-
3- pub fn day03 ( input_path : String ) {
4- let content = fs:: read_to_string ( input_path) . unwrap ( ) ;
5-
6- println ! (
7- "{:?}" ,
8- parse_muls( & content) . iter( ) . map( |( a, b) | a * b) . sum:: <u32 >( )
9- ) ;
1+ pub fn day03 ( input : & str ) -> ( usize , usize ) {
2+ (
3+ parse_muls ( & input, drop_until_part1)
4+ . iter ( )
5+ . map ( |( a, b) | a * b)
6+ . sum :: < u32 > ( ) as usize ,
7+ parse_muls ( & input, drop_until_part2)
8+ . iter ( )
9+ . map ( |( a, b) | a * b)
10+ . sum :: < u32 > ( ) as usize ,
11+ )
1012}
1113
1214type ParseState < ' a > = ( & ' a str , bool ) ;
1315
14- fn parse_muls ( data : & str ) -> Vec < ( u32 , u32 ) > {
16+ fn parse_muls < F > ( data : & str , drop_until_start : F ) -> Vec < ( u32 , u32 ) >
17+ where
18+ F : for < ' a > Fn ( ParseState < ' a > , & str ) -> ParseState < ' a > ,
19+ {
1520 let mut results = Vec :: new ( ) ;
1621 let mut todo: ParseState = ( data, true ) ;
1722 while !todo. 0 . is_empty ( ) {
18- match parse_next ( todo) {
23+ let after_drop = drop_until_start ( todo, "mul(" ) ;
24+ match parse_next ( after_drop) {
1925 Ok ( ( remaining, pair) ) => {
2026 results. push ( pair) ;
2127 todo = remaining;
@@ -29,12 +35,11 @@ fn parse_muls(data: &str) -> Vec<(u32, u32)> {
2935}
3036
3137fn parse_next ( data : ParseState ) -> Result < ( ParseState , ( u32 , u32 ) ) , ParseState > {
32- let r1 = drop_until_part2 ( data, "mul(" ) ;
33- let ( r2, num1) = parse_int ( r1) ?;
34- let r3 = parse_prefix ( r2, ',' ) ?;
35- let ( r4, num2) = parse_int ( r3) ?;
36- let r5 = parse_prefix ( r4, ')' ) ?;
37- Ok ( ( r5, if r5. 1 { ( num1, num2) } else { ( 0 , 0 ) } ) )
38+ let ( r1, num1) = parse_int ( data) ?;
39+ let r2 = parse_prefix ( r1, ',' ) ?;
40+ let ( r3, num2) = parse_int ( r2) ?;
41+ let r4 = parse_prefix ( r3, ')' ) ?;
42+ Ok ( ( r4, if r4. 1 { ( num1, num2) } else { ( 0 , 0 ) } ) )
3843}
3944
4045#[ allow( dead_code) ]
0 commit comments