@@ -19,12 +19,31 @@ fn is_double(n: Id) -> bool {
1919 s[ ..mid] == s[ mid..]
2020}
2121
22+ fn is_at_least_double ( n : Id ) -> bool {
23+ let s = n. to_string ( ) ;
24+ let len = s. len ( ) ;
25+
26+ ( 1 ..len)
27+ . filter ( |& divisor| len. is_multiple_of ( divisor) && len / divisor >= 2 )
28+ . any ( |divisor| {
29+ let pattern = & s[ ..divisor] ;
30+ s. as_bytes ( )
31+ . chunks ( divisor)
32+ . all ( |chunk| chunk == pattern. as_bytes ( ) )
33+ } )
34+ }
35+
2236impl Range {
2337 pub fn get_doubles ( & self ) -> Vec < Id > {
2438 ( self . lower ..=self . upper )
2539 . filter ( |& e| is_double ( e) )
2640 . collect ( )
2741 }
42+ pub fn get_repeating ( & self ) -> Vec < Id > {
43+ ( self . lower ..=self . upper )
44+ . filter ( |& e| is_at_least_double ( e) )
45+ . collect ( )
46+ }
2847}
2948
3049#[ derive( Debug ) ]
@@ -72,11 +91,19 @@ fn solve_1(ranges: &[Range]) -> Id {
7291 . sum ( )
7392}
7493
94+ fn solve_2 ( ranges : & [ Range ] ) -> Id {
95+ ranges
96+ . iter ( )
97+ . map ( |range| range. get_repeating ( ) . iter ( ) . sum :: < Id > ( ) )
98+ . sum ( )
99+ }
100+
75101pub fn run ( ) {
76102 let input = include_str ! ( "2_input" ) ;
77103
78104 if let Some ( ranges) = parse_ranges ( input) {
79105 println ! ( "Day 2 Part 1: {}" , solve_1( & ranges) ) ;
106+ println ! ( "Day 2 Part 2: {}" , solve_2( & ranges) ) ;
80107 }
81108}
82109
@@ -236,4 +263,140 @@ mod tests {
236263 . sum ( ) ;
237264 assert_eq ! ( sum, 1227775554 ) ;
238265 }
266+
267+ // Part 2 tests - at least double (2+ repetitions)
268+ #[ test]
269+ fn test_is_at_least_double_valid ( ) {
270+ assert ! ( is_at_least_double( 11 ) ) ; // 1 twice
271+ assert ! ( is_at_least_double( 1111 ) ) ; // 1 four times
272+ assert ! ( is_at_least_double( 111 ) ) ; // 1 three times
273+ assert ! ( is_at_least_double( 12341234 ) ) ; // 1234 twice
274+ assert ! ( is_at_least_double( 123123123 ) ) ; // 123 three times
275+ assert ! ( is_at_least_double( 1212121212 ) ) ; // 12 five times
276+ assert ! ( is_at_least_double( 1111111 ) ) ; // 1 seven times
277+ assert ! ( is_at_least_double( 99 ) ) ; // 9 twice
278+ assert ! ( is_at_least_double( 999 ) ) ; // 9 three times
279+ assert ! ( is_at_least_double( 1010 ) ) ; // 10 twice
280+ assert ! ( is_at_least_double( 565656 ) ) ; // 56 three times
281+ assert ! ( is_at_least_double( 824824824 ) ) ; // 824 three times
282+ assert ! ( is_at_least_double( 2121212121 ) ) ; // 21 five times
283+ }
284+
285+ #[ test]
286+ fn test_is_at_least_double_invalid ( ) {
287+ assert ! ( !is_at_least_double( 123 ) ) ; // No repetition
288+ assert ! ( !is_at_least_double( 1234 ) ) ; // No repetition
289+ assert ! ( !is_at_least_double( 101 ) ) ; // Not a repetition
290+ }
291+
292+ #[ test]
293+ fn test_range_11_22_part2 ( ) {
294+ let range = Range {
295+ lower : 11 ,
296+ upper : 22 ,
297+ } ;
298+ assert_eq ! ( range. get_repeating( ) , vec![ 11 , 22 ] ) ;
299+ }
300+
301+ #[ test]
302+ fn test_range_95_115_part2 ( ) {
303+ let range = Range {
304+ lower : 95 ,
305+ upper : 115 ,
306+ } ;
307+ assert_eq ! ( range. get_repeating( ) , vec![ 99 , 111 ] ) ;
308+ }
309+
310+ #[ test]
311+ fn test_range_998_1012_part2 ( ) {
312+ let range = Range {
313+ lower : 998 ,
314+ upper : 1012 ,
315+ } ;
316+ assert_eq ! ( range. get_repeating( ) , vec![ 999 , 1010 ] ) ;
317+ }
318+
319+ #[ test]
320+ fn test_range_1188511880_1188511890_part2 ( ) {
321+ let range = Range {
322+ lower : 1188511880 ,
323+ upper : 1188511890 ,
324+ } ;
325+ assert_eq ! ( range. get_repeating( ) , vec![ 1188511885 ] ) ;
326+ }
327+
328+ #[ test]
329+ fn test_range_222220_222224_part2 ( ) {
330+ let range = Range {
331+ lower : 222220 ,
332+ upper : 222224 ,
333+ } ;
334+ assert_eq ! ( range. get_repeating( ) , vec![ 222222 ] ) ;
335+ }
336+
337+ #[ test]
338+ fn test_range_1698522_1698528_part2 ( ) {
339+ let range = Range {
340+ lower : 1698522 ,
341+ upper : 1698528 ,
342+ } ;
343+ assert_eq ! ( range. get_repeating( ) , Vec :: <Id >:: new( ) ) ;
344+ }
345+
346+ #[ test]
347+ fn test_range_446443_446449_part2 ( ) {
348+ let range = Range {
349+ lower : 446443 ,
350+ upper : 446449 ,
351+ } ;
352+ assert_eq ! ( range. get_repeating( ) , vec![ 446446 ] ) ;
353+ }
354+
355+ #[ test]
356+ fn test_range_38593856_38593862_part2 ( ) {
357+ let range = Range {
358+ lower : 38593856 ,
359+ upper : 38593862 ,
360+ } ;
361+ assert_eq ! ( range. get_repeating( ) , vec![ 38593859 ] ) ;
362+ }
363+
364+ #[ test]
365+ fn test_range_565653_565659_part2 ( ) {
366+ let range = Range {
367+ lower : 565653 ,
368+ upper : 565659 ,
369+ } ;
370+ assert_eq ! ( range. get_repeating( ) , vec![ 565656 ] ) ;
371+ }
372+
373+ #[ test]
374+ fn test_range_824824821_824824827_part2 ( ) {
375+ let range = Range {
376+ lower : 824824821 ,
377+ upper : 824824827 ,
378+ } ;
379+ assert_eq ! ( range. get_repeating( ) , vec![ 824824824 ] ) ;
380+ }
381+
382+ #[ test]
383+ fn test_range_2121212118_2121212124_part2 ( ) {
384+ let range = Range {
385+ lower : 2121212118 ,
386+ upper : 2121212124 ,
387+ } ;
388+ assert_eq ! ( range. get_repeating( ) , vec![ 2121212121 ] ) ;
389+ }
390+
391+ #[ test]
392+ fn test_example_sum_part2 ( ) {
393+ let input = "11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124" ;
394+ let ranges = parse_ranges ( input) . unwrap ( ) ;
395+ let sum: u64 = ranges
396+ . iter ( )
397+ . flat_map ( |r| ( r. lower ..=r. upper ) . filter ( |& n| is_at_least_double ( n) ) )
398+ . map ( |n| n as u64 )
399+ . sum ( ) ;
400+ assert_eq ! ( sum, 4174379265 ) ;
401+ }
239402}
0 commit comments