@@ -180,13 +180,84 @@ fn matrix_multiply(multiplier: &[Vec<u128>], multiplicand: &[Vec<u128>]) -> Vec<
180
180
result
181
181
}
182
182
183
+ /// nth_fibonacci_number_modulo_m(n, m) returns the nth fibonacci number modulo the specified m
184
+ /// i.e. F(n) % m
185
+ pub fn nth_fibonacci_number_modulo_m ( n : i64 , m : i64 ) -> i128 {
186
+ let ( length, pisano_sequence) = get_pisano_sequence_and_period ( m) ;
187
+
188
+ let remainder = n % length as i64 ;
189
+ pisano_sequence. get ( remainder as usize ) . unwrap ( ) . to_owned ( )
190
+ }
191
+
192
+ /// get_pisano_sequence_and_period(m) returns the Pisano Sequence and period for the specified integer m.
193
+ /// The pisano period is the period with which the sequence of Fibonacci numbers taken modulo m repeats.
194
+ /// The pisano sequence is the numbers in pisano period.
195
+ fn get_pisano_sequence_and_period ( m : i64 ) -> ( i128 , Vec < i128 > ) {
196
+ let mut a = 0 ;
197
+ let mut b = 1 ;
198
+ let mut lenght: i128 = 0 ;
199
+ let mut pisano_sequence: Vec < i128 > = vec ! [ a, b] ;
200
+
201
+ // Iterating through all the fib numbers to get the sequence
202
+ for _i in 0 ..( m * m) + 1 {
203
+ let c = ( a + b) % m as i128 ;
204
+
205
+ // adding number into the sequence
206
+ pisano_sequence. push ( c) ;
207
+
208
+ a = b;
209
+ b = c;
210
+
211
+ if a == 0 && b == 1 {
212
+ // Remove the last two elements from the sequence
213
+ // This is a less elegant way to do it.
214
+ pisano_sequence. pop ( ) ;
215
+ pisano_sequence. pop ( ) ;
216
+ lenght = pisano_sequence. len ( ) as i128 ;
217
+ break ;
218
+ }
219
+ }
220
+
221
+ ( lenght, pisano_sequence)
222
+ }
223
+
224
+ /// last_digit_of_the_sum_of_nth_fibonacci_number(n) returns the last digit of the sum of n fibonacci numbers.
225
+ /// The function uses the definition of Fibonacci where:
226
+ /// F(0) = 0, F(1) = 1 and F(n+1) = F(n) + F(n-1) for n > 2
227
+ ///
228
+ /// The sum of the Fibonacci numbers are:
229
+ /// F(0) + F(1) + F(2) + ... + F(n)
230
+ pub fn last_digit_of_the_sum_of_nth_fibonacci_number ( n : i64 ) -> i64 {
231
+ if n < 2 {
232
+ return n;
233
+ }
234
+
235
+ // the pisano period of mod 10 is 60
236
+ let n = ( ( n + 2 ) % 60 ) as usize ;
237
+ let mut fib = vec ! [ 0 ; n + 1 ] ;
238
+ fib[ 0 ] = 0 ;
239
+ fib[ 1 ] = 1 ;
240
+
241
+ for i in 2 ..=n {
242
+ fib[ i] = ( fib[ i - 1 ] % 10 + fib[ i - 2 ] % 10 ) % 10 ;
243
+ }
244
+
245
+ if fib[ n] == 0 {
246
+ return 9 ;
247
+ }
248
+
249
+ fib[ n] % 10 - 1
250
+ }
251
+
183
252
#[ cfg( test) ]
184
253
mod tests {
185
254
use super :: classical_fibonacci;
186
255
use super :: fibonacci;
256
+ use super :: last_digit_of_the_sum_of_nth_fibonacci_number;
187
257
use super :: logarithmic_fibonacci;
188
258
use super :: matrix_fibonacci;
189
259
use super :: memoized_fibonacci;
260
+ use super :: nth_fibonacci_number_modulo_m;
190
261
use super :: recursive_fibonacci;
191
262
192
263
#[ test]
@@ -326,4 +397,32 @@ mod tests {
326
397
127127879743834334146972278486287885163
327
398
) ;
328
399
}
400
+
401
+ #[ test]
402
+ fn test_nth_fibonacci_number_modulo_m ( ) {
403
+ assert_eq ! ( nth_fibonacci_number_modulo_m( 5 , 10 ) , 5 ) ;
404
+ assert_eq ! ( nth_fibonacci_number_modulo_m( 10 , 7 ) , 6 ) ;
405
+ assert_eq ! ( nth_fibonacci_number_modulo_m( 20 , 100 ) , 65 ) ;
406
+ assert_eq ! ( nth_fibonacci_number_modulo_m( 1 , 5 ) , 1 ) ;
407
+ assert_eq ! ( nth_fibonacci_number_modulo_m( 0 , 15 ) , 0 ) ;
408
+ assert_eq ! ( nth_fibonacci_number_modulo_m( 50 , 1000 ) , 25 ) ;
409
+ assert_eq ! ( nth_fibonacci_number_modulo_m( 100 , 37 ) , 7 ) ;
410
+ assert_eq ! ( nth_fibonacci_number_modulo_m( 15 , 2 ) , 0 ) ;
411
+ assert_eq ! ( nth_fibonacci_number_modulo_m( 8 , 1_000_000 ) , 21 ) ;
412
+ assert_eq ! ( nth_fibonacci_number_modulo_m( 1000 , 997 ) , 996 ) ;
413
+ assert_eq ! ( nth_fibonacci_number_modulo_m( 200 , 123 ) , 0 ) ;
414
+ }
415
+
416
+ #[ test]
417
+ fn test_last_digit_of_the_sum_of_nth_fibonacci_number ( ) {
418
+ assert_eq ! ( last_digit_of_the_sum_of_nth_fibonacci_number( 0 ) , 0 ) ;
419
+ assert_eq ! ( last_digit_of_the_sum_of_nth_fibonacci_number( 1 ) , 1 ) ;
420
+ assert_eq ! ( last_digit_of_the_sum_of_nth_fibonacci_number( 2 ) , 2 ) ;
421
+ assert_eq ! ( last_digit_of_the_sum_of_nth_fibonacci_number( 3 ) , 4 ) ;
422
+ assert_eq ! ( last_digit_of_the_sum_of_nth_fibonacci_number( 4 ) , 7 ) ;
423
+ assert_eq ! ( last_digit_of_the_sum_of_nth_fibonacci_number( 5 ) , 2 ) ;
424
+ assert_eq ! ( last_digit_of_the_sum_of_nth_fibonacci_number( 25 ) , 7 ) ;
425
+ assert_eq ! ( last_digit_of_the_sum_of_nth_fibonacci_number( 50 ) , 8 ) ;
426
+ assert_eq ! ( last_digit_of_the_sum_of_nth_fibonacci_number( 100 ) , 5 ) ;
427
+ }
329
428
}
0 commit comments