22//! https://adventofcode.com/2024/day/11
33
44use std:: { fs, io} ;
5+ use std:: collections:: BTreeMap ;
56use std:: path:: Path ;
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:?}" ) ;
10+ //let input = Input::from_file(format!("{}/example2 .txt", env!("CARGO_MANIFEST_DIR"))).expect("failed to read input");
11+ // println!("{input:?}");
1112
1213 // Part 1
1314 println ! ( "Part 1: {}" , part1( & input) ) ;
@@ -16,23 +17,90 @@ fn main() {
1617 println ! ( "Part 2: {}" , part2( & input) ) ;
1718}
1819
20+ fn digits ( n : usize ) -> usize {
21+ if n == 0 {
22+ return 1 ;
23+ }
24+
25+ ( n. ilog10 ( ) + 1 ) as usize
26+ }
27+
1928fn part1 ( input : & Input ) -> usize {
20- 0
29+ // `slow` and `fast` give identical results.
30+ slow ( & input. values , 25 )
2131}
2232
2333fn part2 ( input : & Input ) -> usize {
24- 0
34+ // `slow` and `fast` give identical results, but `slow` will never complete.
35+ fast ( & input. values , 75 )
36+ }
37+
38+ fn slow ( stones : & [ usize ] , n : usize ) -> usize {
39+ let mut stones = stones. iter ( ) . copied ( ) . collect ( ) ;
40+
41+ for _ in 0 ..n {
42+ let mut new_stones = Vec :: new ( ) ;
43+
44+ for stone in stones {
45+ let digits = digits ( stone) ;
46+ match stone {
47+ 0 => { new_stones. push ( 1 ) ; } ,
48+ x if digits % 2 == 0 => {
49+ let factor = 10usize . pow ( digits as u32 / 2 ) ;
50+ new_stones. push ( x / factor) ;
51+ new_stones. push ( x % factor) ;
52+ } ,
53+ x => { new_stones. push ( x * 2024 ) ; }
54+ }
55+ }
56+
57+ stones = new_stones;
58+ }
59+
60+ stones. len ( )
61+ }
62+
63+ fn fast ( stones : & [ usize ] , n : usize ) -> usize {
64+ let mut counts: BTreeMap < usize , usize > = BTreeMap :: new ( ) ;
65+ for value in stones. iter ( ) . copied ( ) {
66+ * counts. entry ( value) . or_default ( ) += 1 ;
67+ }
68+
69+ for _ in 0 ..n {
70+ let mut new_counts = BTreeMap :: new ( ) ;
71+
72+ for ( stone, n) in counts {
73+ let digits = digits ( stone) ;
74+ match stone {
75+ 0 => {
76+ * new_counts. entry ( 1 ) . or_default ( ) += n;
77+ } ,
78+ x if digits % 2 == 0 => {
79+ let factor = 10usize . pow ( digits as u32 / 2 ) ;
80+ * new_counts. entry ( x / factor) . or_default ( ) += n;
81+ * new_counts. entry ( x % factor) . or_default ( ) += n;
82+ } ,
83+ x => {
84+ * new_counts. entry ( x * 2024 ) . or_default ( ) += n;
85+ }
86+ }
87+ }
88+
89+ counts = new_counts
90+ }
91+
92+ counts. values ( ) . sum ( )
2593}
2694
2795#[ derive( Debug , Clone ) ]
2896struct Input {
29- values : Vec < String > ,
97+ values : Vec < usize > ,
3098}
3199
32100impl Input {
33101 fn from_file ( path : impl AsRef < Path > ) -> io:: Result < Self > {
34102 let input = fs:: read_to_string ( path) ?;
35- let values = input. lines ( ) . map ( str :: to_string ) . collect ( ) ;
103+ let values = input. trim ( ) . split_ascii_whitespace ( ) . map ( |s| s . parse ( ) . unwrap ( ) ) . collect ( ) ;
36104
37105 Ok ( Self { values } )
38106 }
@@ -44,29 +112,22 @@ mod test {
44112
45113 #[ test]
46114 fn test_part1 ( ) {
47- let input = Input :: from_file ( "example1 .txt" ) . unwrap ( ) ;
115+ let input = Input :: from_file ( "example2 .txt" ) . unwrap ( ) ;
48116
49- assert_eq ! ( part1( & input) , 0 ) ;
117+ assert_eq ! ( part1( & input) , 55312 ) ;
50118 }
51119
52120 #[ test]
53121 fn test_part1_solution ( ) {
54122 let input = Input :: from_file ( "input.txt" ) . unwrap ( ) ;
55123
56- assert_eq ! ( part1( & input) , 0 ) ;
57- }
58-
59- #[ test]
60- fn test_part2 ( ) {
61- let input = Input :: from_file ( "example1.txt" ) . unwrap ( ) ;
62-
63- assert_eq ! ( part2( & input) , 0 ) ;
124+ assert_eq ! ( part1( & input) , 222461 ) ;
64125 }
65126
66127 #[ test]
67128 fn test_part2_solution ( ) {
68129 let input = Input :: from_file ( "input.txt" ) . unwrap ( ) ;
69130
70- assert_eq ! ( part2( & input) , 0 ) ;
131+ assert_eq ! ( part2( & input) , 264350935776416 ) ;
71132 }
72133}
0 commit comments