33
44use std:: { fs, io} ;
55use std:: path:: Path ;
6+ use regex:: Regex ;
67
78fn main ( ) {
89 let input = Input :: from_file ( format ! ( "{}/input.txt" , env!( "CARGO_MANIFEST_DIR" ) ) ) . expect ( "failed to read input" ) ;
9- //let input = Input::from_file(format!("{}/example1.txt", env!("CARGO_MANIFEST_DIR"))).expect("failed to read input");
10- println ! ( "{input:?}" ) ;
1110
1211 // Part 1
1312 println ! ( "Part 1: {}" , part1( & input) ) ;
@@ -17,24 +16,52 @@ fn main() {
1716}
1817
1918fn part1 ( input : & Input ) -> usize {
20- 0
19+ let mul_re = Regex :: new ( r"mul\((\d{1,3}),(\d{1,3})\)" ) . unwrap ( ) ;
20+
21+ mul_re. captures_iter ( & input. input )
22+ . map ( |m| {
23+ let a: usize = m. get ( 1 ) . and_then ( |m| m. as_str ( ) . parse ( ) . ok ( ) ) . unwrap ( ) ;
24+ let b: usize = m. get ( 2 ) . and_then ( |m| m. as_str ( ) . parse ( ) . ok ( ) ) . unwrap ( ) ;
25+
26+ a * b
27+ } )
28+ . sum ( )
2129}
2230
2331fn part2 ( input : & Input ) -> usize {
24- 0
32+ let instr_re = Regex :: new ( r"(?x) (?<instr>mul|do(n't)?) \( (?:(?<a>\d{1,3}) , (?<b>\d{1,3}))? \)" ) . unwrap ( ) ;
33+
34+ let mut is_do = true ;
35+ instr_re. captures_iter ( & input. input )
36+ . filter_map ( |m| {
37+ match m. name ( "instr" ) . unwrap ( ) . as_str ( ) {
38+ "mul" => {
39+ let a: usize = m. name ( "a" ) . and_then ( |m| m. as_str ( ) . parse ( ) . ok ( ) ) . unwrap ( ) ;
40+ let b: usize = m. name ( "b" ) . and_then ( |m| m. as_str ( ) . parse ( ) . ok ( ) ) . unwrap ( ) ;
41+
42+ if is_do {
43+ return Some ( a * b)
44+ } ;
45+ } ,
46+ "do" => is_do = true ,
47+ "don't" => is_do = false ,
48+ instr => panic ! ( "unknown instruction {instr:?}" ) ,
49+ }
50+
51+ None
52+ } ) . sum ( )
2553}
2654
2755#[ derive( Debug , Clone ) ]
2856struct Input {
29- values : Vec < String > ,
57+ input : String ,
3058}
3159
3260impl Input {
3361 fn from_file ( path : impl AsRef < Path > ) -> io:: Result < Self > {
3462 let input = fs:: read_to_string ( path) ?;
35- let values = input. lines ( ) . map ( str:: to_string) . collect ( ) ;
3663
37- Ok ( Self { values } )
64+ Ok ( Self { input } )
3865 }
3966}
4067
@@ -46,27 +73,27 @@ mod test {
4673 fn test_part1 ( ) {
4774 let input = Input :: from_file ( "example1.txt" ) . unwrap ( ) ;
4875
49- assert_eq ! ( part1( & input) , 0 ) ;
76+ assert_eq ! ( part1( & input) , 161 ) ;
5077 }
5178
5279 #[ test]
5380 fn test_part1_solution ( ) {
5481 let input = Input :: from_file ( "input.txt" ) . unwrap ( ) ;
5582
56- assert_eq ! ( part1( & input) , 0 ) ;
83+ assert_eq ! ( part1( & input) , 175615763 ) ;
5784 }
5885
5986 #[ test]
6087 fn test_part2 ( ) {
61- let input = Input :: from_file ( "example1 .txt" ) . unwrap ( ) ;
88+ let input = Input :: from_file ( "example2 .txt" ) . unwrap ( ) ;
6289
63- assert_eq ! ( part2( & input) , 0 ) ;
90+ assert_eq ! ( part2( & input) , 48 ) ;
6491 }
6592
6693 #[ test]
6794 fn test_part2_solution ( ) {
6895 let input = Input :: from_file ( "input.txt" ) . unwrap ( ) ;
6996
70- assert_eq ! ( part2( & input) , 0 ) ;
97+ assert_eq ! ( part2( & input) , 74361272 ) ;
7198 }
7299}
0 commit comments