@@ -3,75 +3,60 @@ use common::{Answer, solution};
33solution ! ( "Gift Shop" , 2 ) ;
44
55fn part_a ( input : & str ) -> Answer {
6- let mut count = 0 ;
6+ count_invalid ( input, |id| {
7+ let digits = id. ilog10 ( ) . div_ceil ( 2 ) ;
8+ let mask = u64:: pow ( 10 , digits) ;
9+ id % mask == id / mask
10+ } )
11+ . into ( )
12+ }
713
8- for range in input. trim ( ) . split ( ',' ) {
9- let ( start, end) = range. split_once ( '-' ) . unwrap ( ) ;
10- let start = start. parse :: < u64 > ( ) . unwrap ( ) ;
11- let end = end. parse :: < u64 > ( ) . unwrap ( ) ;
14+ fn part_b ( input : & str ) -> Answer {
15+ count_invalid ( input, |id| {
16+ let digits = id. ilog10 ( ) + 1 ;
17+ ' outer: for size in 1 ..=( digits / 2 ) {
18+ let mask = u64:: pow ( 10 , size) ;
19+ let repeated = id % mask;
20+ if !digits. is_multiple_of ( size) {
21+ continue ;
22+ }
1223
13- for id in start..=end {
14- count += is_invalid ( id) as u64 * id;
24+ let mut id = id;
25+ for _ in 0 ..( digits / size) {
26+ if id % mask != repeated {
27+ continue ' outer;
28+ }
29+
30+ id /= mask;
31+ }
32+
33+ return true ;
1534 }
16- }
1735
18- count. into ( )
36+ false
37+ } )
38+ . into ( )
1939}
2040
21- fn part_b ( input : & str ) -> Answer {
41+ fn count_invalid ( input : & str , is_invalid : fn ( u64 ) -> bool ) -> u64 {
2242 let mut count = 0 ;
2343
24- for range in input. trim ( ) . split ( ',' ) {
44+ for range in input. split ( ',' ) {
2545 let ( start, end) = range. split_once ( '-' ) . unwrap ( ) ;
2646 let start = start. parse :: < u64 > ( ) . unwrap ( ) ;
2747 let end = end. parse :: < u64 > ( ) . unwrap ( ) ;
2848
2949 for id in start..=end {
30- count += is_invalid2 ( id) as u64 * id;
31- }
32- }
33-
34- count. into ( )
35- }
36-
37- fn is_invalid ( id : u64 ) -> bool {
38- let digits = ( id. ilog10 ( ) + 1 ) / 2 ;
39- let mask = 10_u64 . pow ( digits) ;
40- id % mask == id / mask
41- }
42-
43- fn is_invalid2 ( id : u64 ) -> bool {
44- let digits = id. ilog10 ( ) + 1 ;
45-
46- ' outer: for size in 1 ..=( digits / 2 ) {
47- let mask = 10_u64 . pow ( size) ;
48- let repeated = id % mask;
49- if ( digits / size) * size != digits || repeated == 0 || repeated. ilog10 ( ) + 1 != size {
50- continue ;
51- }
52-
53- let mut id = id;
54- for _ in 0 ..( digits / size) {
55- if id % mask != repeated {
56- continue ' outer;
57- }
58-
59- id /= mask;
50+ count += is_invalid ( id) as u64 * id;
6051 }
61-
62- return true ;
6352 }
6453
65- false
54+ count
6655}
6756
6857#[ cfg( test) ]
6958mod test {
70- use indoc:: indoc;
71-
72- const CASE : & str = indoc ! { "
73- 11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124
74- " } ;
59+ const CASE : & str = "11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124" ;
7560
7661 #[ test]
7762 fn part_a ( ) {
0 commit comments