@@ -2,57 +2,52 @@ use aoc::common;
22use aoc:: io;
33use itertools:: Itertools ;
44
5- fn is_num ( s : & str ) -> bool {
6- s. chars ( ) . all ( |x| x. is_ascii_digit ( ) )
7- }
8-
95// the ....mul(X,Y)...... part
10- fn solve_muls ( input : & str ) -> usize {
6+ fn compute ( input : & str ) -> usize {
117 let mut ans = 0 ;
12- for pattern in io:: tokenize ( input, "mul(" ) {
13- let tokens1 = io:: tokenize ( pattern, "," ) ;
14- let num1 = tokens1. first ( ) . unwrap ( ) ;
15- // check if num1 has all digits
16- if is_num ( num1) {
17- let n1: usize = io:: parse_num ( num1) ;
18- let tokens2 = io:: tokenize ( tokens1[ 1 ] , ")" ) ;
19- let num2 = tokens2. first ( ) . unwrap ( ) ;
20- if is_num ( num2) {
21- let n2: usize = io:: parse_num ( num2) ;
22- ans += n1 * n2;
8+ for pattern in io:: tokenize ( input, "mul(" ) . iter ( ) . skip ( 1 ) {
9+ if let Some ( ( num1_str, num2_str_plus) ) = pattern. split_once ( ',' ) {
10+ if let Some ( n1) = io:: try_parse_num :: < usize > ( num1_str) {
11+ if let Some ( ( num2_str, _) ) = num2_str_plus. split_once ( ')' ) {
12+ if let Some ( n2) = io:: try_parse_num :: < usize > ( num2_str) {
13+ ans += n1 * n2;
14+ }
15+ }
2316 }
2417 }
2518 }
2619 ans
2720}
2821
2922fn solve < const PART : usize > ( input : & str ) -> usize {
30- let mut ans = 0 ;
31-
3223 if PART == 1 {
33- ans = solve_muls ( input) ;
24+ compute ( input)
3425 } else {
35- let indices = input
26+ let do_dont_indices = input
3627 . match_indices ( "do()" )
3728 . chain ( input. match_indices ( "don't()" ) )
38- . sorted_by_key ( |x| x. 0 ) ;
29+ . sorted_by_key ( |( idx, _) | * idx)
30+ . map ( |( idx, do_or_dont) | {
31+ if do_or_dont == "do()" {
32+ ( idx, true )
33+ } else {
34+ ( idx, false )
35+ }
36+ } ) ;
3937
40- let mut last_idx = 0 ;
41- let mut yes: bool = true ;
42- for ( idx, ins) in indices {
43- if yes {
44- ans += solve_muls ( & input[ last_idx..idx] ) ;
45- }
46- last_idx = idx;
47- yes = ins == "do()" ;
38+ let mut checkpoints = vec ! [ ( 0 , true ) ] ;
39+ for idx in do_dont_indices {
40+ checkpoints. push ( idx) ;
4841 }
42+ checkpoints. push ( ( input. len ( ) , false ) ) ;
4943
50- if yes {
51- ans += solve_muls ( & input[ last_idx..] ) ;
52- }
44+ checkpoints. windows ( 2 ) . fold ( 0 , |mut acc, interval| {
45+ if interval[ 0 ] . 1 {
46+ acc += compute ( & input[ interval[ 0 ] . 0 ..interval[ 1 ] . 0 ] ) ;
47+ }
48+ acc
49+ } )
5350 }
54-
55- ans
5651}
5752
5853fn main ( ) {
0 commit comments