@@ -37,11 +37,33 @@ impl Day11 {
3737
3838 #[ must_use]
3939 pub fn part2 ( & self ) -> String {
40- let ( size, ( _, x, y) ) = ( 1 ..=300 )
41- . map ( |s| ( s, self . largest_total_power ( s) ) )
42- . max_by_key ( |& ( _, ( total, _, _) ) | total)
43- . unwrap ( ) ;
44- format ! ( "{x},{y},{size}" )
40+ let ( mut max_size, mut max_total, mut max_x, mut max_y) = ( 0 , i32:: MIN , 0 , 0 ) ;
41+ let mut sizes: Vec < i32 > = Vec :: with_capacity ( 300 ) ;
42+
43+ for size in 1 ..=300 {
44+ // Try to split the N*N square into Y X*X squares to calculate an upper bound.
45+ // For example, if the best 5x5 is 100, then the best 10x10 must be <= 400.
46+ if let Some ( divisor) = ( 2 ..=size / 2 ) . rev ( ) . find ( |& d| size % d == 0 ) {
47+ let copies = ( size / divisor) * ( size / divisor) ;
48+ let upper_bound = sizes[ divisor - 1 ] . saturating_mul ( copies as i32 ) ;
49+ if upper_bound < max_total {
50+ sizes. push ( upper_bound) ;
51+ continue ;
52+ }
53+ } ;
54+
55+ let ( total, x, y) = self . largest_total_power ( size) ;
56+ sizes. push ( total) ;
57+
58+ if total > max_total {
59+ max_size = size;
60+ max_total = total;
61+ max_x = x;
62+ max_y = y;
63+ }
64+ }
65+
66+ format ! ( "{max_x},{max_y},{max_size}" )
4567 }
4668
4769 fn largest_total_power ( & self , size : usize ) -> ( i32 , u32 , u32 ) {
0 commit comments