88 let mut total: u64 = 0 ;
99
1010 for split in input. split ( ',' ) {
11- let numbers : Vec < & str > = split. split ( '-' ) . collect ( ) ;
12- total += op ( numbers [ 0 ] , numbers [ 1 ] )
11+ let ( start , end ) = split. split_once ( '-' ) . unwrap ( ) ;
12+ total += op ( start , end )
1313 }
1414
1515 total
@@ -143,11 +143,11 @@ struct Range {
143143pub fn part_two ( input : & str ) -> Option < u64 > {
144144 let all_ranges: Vec < Range > = input
145145 . split ( ',' )
146- . map ( |range | {
147- let nums : Vec < & str > = range . split ( '-' ) . collect ( ) ;
146+ . map ( |split | {
147+ let ( start , end ) = split. split_once ( '-' ) . unwrap ( ) ;
148148 Range {
149- min_number : nums [ 0 ] . parse ( ) . unwrap ( ) ,
150- max_number : nums [ 1 ] . parse ( ) . unwrap ( ) ,
149+ min_number : start . parse ( ) . unwrap ( ) ,
150+ max_number : end . parse ( ) . unwrap ( ) ,
151151 }
152152 } )
153153 . collect ( ) ;
@@ -191,6 +191,76 @@ pub fn part_two(input: &str) -> Option<u64> {
191191 Some ( total)
192192}
193193
194+ pub fn part_two_online ( input : & str ) -> Option < u64 > {
195+ let part2: u64 = input
196+ . split ( "," )
197+ . map ( |s| {
198+ let ( start, end) = s. split_once ( "-" ) . unwrap ( ) ;
199+ let [ start, end] = [ start, end] . map ( |s| s. parse :: < u64 > ( ) . unwrap ( ) ) ;
200+ sum_in_range ( start, end, 2 ) + sum_in_range ( start, end, 3 ) + sum_in_range ( start, end, 5 )
201+ - sum_in_range ( start, end, 6 )
202+ + sum_in_range ( start, end, 7 )
203+ - sum_in_range ( start, end, 10 )
204+ } )
205+ . sum ( ) ;
206+
207+ Some ( part2)
208+ }
209+
210+ fn sums_up_to ( n : u64 , div : u32 ) -> u64 {
211+ if n == 0 {
212+ return 0 ;
213+ } ;
214+ let log = n. ilog10 ( ) ;
215+ let grouped_sum = groupedsum ( log, div) ;
216+ grouped_sum
217+ + if ( log + 1 ) % div == 0 {
218+ let rep = rep ( log + 1 , div) ;
219+ offset_sum ( n / rep - 10u64 . pow ( log) / rep, log / div) * rep
220+ } else {
221+ 0
222+ }
223+ }
224+
225+ const fn offset_sum ( count : u64 , log : u32 ) -> u64 {
226+ sum ( count + ( 10u64 . pow ( log) - 1 ) ) - sum ( 10u64 . pow ( log) - 1 )
227+ }
228+
229+ const fn sum ( n : u64 ) -> u64 {
230+ let n = n as u128 ;
231+ ( ( n * ( n + 1 ) ) / 2 ) as u64
232+ }
233+
234+ fn rep ( digits : u32 , div : u32 ) -> u64 {
235+ let mut out = 1 ;
236+ let mult = 10u64 . pow ( digits / div) ;
237+ let mut c = 1 ;
238+ while c < div {
239+ out *= mult;
240+ out += 1 ;
241+ c += 1
242+ }
243+ out
244+ }
245+ fn groupedsum ( n : u32 , div : u32 ) -> u64 {
246+ ( 0 ..=n)
247+ . step_by ( div as usize )
248+ . skip ( 1 )
249+ . map ( |i| {
250+ let log = i as u32 - 1 ;
251+ let rep = rep ( log + 1 , div) ;
252+ let n = 10u64 . pow ( log + 1 ) - 1 ;
253+ offset_sum ( n / rep - 10u64 . pow ( log) / rep, log / div) * rep
254+ } )
255+ . sum ( )
256+ }
257+
258+ fn sum_in_range ( start : u64 , end_inclusive : u64 , div : u32 ) -> u64 {
259+ match start. checked_sub ( 1 ) {
260+ Some ( prev) => sums_up_to ( end_inclusive, div) - sums_up_to ( prev, div) ,
261+ None => sums_up_to ( end_inclusive, div) ,
262+ }
263+ }
194264
195265#[ cfg( test) ]
196266mod tests {
@@ -232,7 +302,7 @@ mod tests {
232302 assert_eq ! ( result, Some ( 79183223243u64 ) ) ;
233303 }
234304
235- #[ test]
305+ #[ test]
236306 fn test_execute_part_two_v2_example ( ) {
237307 let result = part_two ( & advent_of_code:: template:: read_file ( "examples" , DAY ) ) ;
238308 assert_eq ! ( result, Some ( 4174379265u64 ) ) ;
@@ -243,4 +313,22 @@ mod tests {
243313 let result = part_two ( & advent_of_code:: template:: read_file ( "inputs" , DAY ) ) ;
244314 assert_eq ! ( result, Some ( 79183223243u64 ) ) ;
245315 }
316+
317+ #[ test]
318+ fn test_execute_part_two_online_example ( ) {
319+ let result = part_two_online ( & advent_of_code:: template:: read_file ( "examples" , DAY ) ) ;
320+ assert_eq ! ( result, Some ( 4174379265u64 ) ) ;
321+ }
322+
323+ #[ test]
324+ fn test_stuff ( ) {
325+ let result = sums_up_to ( 115 , 2 ) ;
326+ assert_eq ! ( result, 101 ) ;
327+ }
328+
329+ #[ test]
330+ fn test_stuff2 ( ) {
331+ let result = offset_sum ( 9 , 0 ) ;
332+ assert_eq ! ( result, 45 ) ;
333+ }
246334}
0 commit comments