@@ -180,13 +180,84 @@ fn matrix_multiply(multiplier: &[Vec<u128>], multiplicand: &[Vec<u128>]) -> Vec<
180180 result
181181}
182182
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+
183252#[ cfg( test) ]
184253mod tests {
185254 use super :: classical_fibonacci;
186255 use super :: fibonacci;
256+ use super :: last_digit_of_the_sum_of_nth_fibonacci_number;
187257 use super :: logarithmic_fibonacci;
188258 use super :: matrix_fibonacci;
189259 use super :: memoized_fibonacci;
260+ use super :: nth_fibonacci_number_modulo_m;
190261 use super :: recursive_fibonacci;
191262
192263 #[ test]
@@ -326,4 +397,32 @@ mod tests {
326397 127127879743834334146972278486287885163
327398 ) ;
328399 }
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+ }
329428}
0 commit comments