diff options
author | Lily Lin | 2022-10-26 23:30:06 +0000 |
---|---|---|
committer | Lily Lin | 2022-10-26 23:30:06 +0000 |
commit | af03b3cd051a8a8b1442147136156f271f07ac5c (patch) | |
tree | 6239bbd269f8c682fcd2bd1aecd29cc8b2edf6b5 /entries/dewert99/big_fib.rs | |
parent | 66fdac7a5ab7040a29fdd6a49cb0123db5ea916a (diff) | |
parent | 18d17f9fb578df5f20e689481ed06f44fcf4b80c (diff) |
Merge branch 'main' into lily
Diffstat (limited to 'entries/dewert99/big_fib.rs')
-rw-r--r-- | entries/dewert99/big_fib.rs | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/entries/dewert99/big_fib.rs b/entries/dewert99/big_fib.rs new file mode 100644 index 0000000..f5cddbb --- /dev/null +++ b/entries/dewert99/big_fib.rs @@ -0,0 +1,40 @@ +use num_bigint::{BigUint, ToBigUint}; + +/// Returns (fib(n-1), fib(n), fib(n+1)) +fn fib_helper(n: u64) -> [BigUint; 3] { + let [fm1, f0, f1] = if n == 0 { + [ + 1.to_biguint().unwrap(), + 0.to_biguint().unwrap(), + 1.to_biguint().unwrap(), + ] + } else { + fib_helper2(n / 2) + }; + if n % 2 == 1 { + let [mut fm2, fm1, f0] = [fm1, f0, f1]; + fm1.clone_into(&mut fm2); + let f1 = fm2 + &f0; + [fm1, f0, f1] + } else { + [fm1, f0, f1] + } +} + +/// Returns (fib(2n-1), fib(2n), fib(2n+1)) +fn fib_helper2(n: u64) -> [BigUint; 3] { + let [fm1, fp0, fp1] = fib_helper(n); + // f2m1 = fm1^2 + fp0^2 + // f2p0 = fp1*fp0 + fp0*fm1 = fp0*(fp1+fm1) + // f2p1 = fp1^2 + fp0^2 + let f2p0 = (fp1.clone() + &fm1) * &fp0; + let fp0sqr = fp0.pow(2); + let f2m1 = fm1.pow(2) + &fp0sqr; + let f2p1 = fp1.pow(2) + fp0sqr; + [f2m1, f2p0, f2p1] +} + +pub fn fib(n: u64) -> BigUint { + let [_, res, _] = fib_helper(n); + res +} |