Rust : codewars的Product of consecutive Fib numbers

来源:互联网 发布:造价大数据 编辑:程序博客网 时间:2024/06/05 15:13

The Fibonacci numbers :Fn:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, …
其中关系式有:
F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.

给定一个数,请试图找出其是否可以由其中的连续相邻The Fibonacci numbers相乘而得;
如果不能相乘而得,请找出其上边界值。写出productFib函数。举例:

productFib(714) # should return (21, 34, true),
# since F(8) = 21, F(9) = 34 and 714 = 21 * 34

productFib(800) # should return (34, 55, false), =>上边界值
# since F(8) = 21, F(9) = 34, F(10) = 55 and 21 * 34 < 800 < 34 * 55

一、我的解法

fn product_fib(prod: u64) -> (u64, u64, bool) {    // your code    let mut hp: HashMap<u64, u64> = HashMap::new();    hp.insert(1u64, 0u64);    hp.insert(2u64, 1u64);    hp.insert(3u64, 1u64);    let mut vec: Vec<u64> = Vec::new();    vec.push(0u64);    vec.push(1u64);    vec.push(1u64);    let mut result: Vec<u64> = Vec::new();    for i in 3u64.. {        let i_1 = hp.get(&(i - 1)).unwrap().clone();        let i_2 = hp.get(&(i - 2)).unwrap().clone();        let val = i_2 + i_1;        hp.insert(i, val);        vec.push(val);        let val_i_2 = &vec[(i - 2) as usize];        let val_i_1 = &vec[(i - 1) as usize];        let val_i = &vec[i as usize];        if val_i_1 * val_i == prod||        (val_i_2 * val_i_1 < prod, val_i_1 * val_i > prod) == (true, true) {            result.push(*val_i);            result.push(*val_i_1);            break;        }    }    (*result.get(0).unwrap(),     *result.get(1).unwrap(),     prod == *result.get(0).unwrap() * *result.get(1).unwrap())}

二、精彩的解法

1、

fn product_fib(prod: u64) -> (u64, u64, bool) {    let mut a = 0; let mut b = 1;    while a * b < prod {        let tmp = a;        a = b;        b = tmp + b;    }     let bl = if a * b == prod {true} else {false};    (a, b, bl)}

2、

use std::cmp::Ordering::{Greater, Equal};fn product_fib(prod: u64) -> (u64, u64, bool) {  let mut p0 = 0;  let mut p1 = 1;  loop {    let p = p0 * p1;    match p.cmp(&prod) {      Greater => return (p0, p1, false),      Equal => return (p0, p1, true),      _ => ()    };    let p2 = p0 + p1;    p0 = p1;    p1 = p2;  }}

3、

fn product_fib(prod: u64) -> (u64, u64, bool) {    let mut f = (0, 1);    loop {        f = (f.1, f.0 + f.1);        if f.0 * f.1 >= prod {            return (f.0, f.1, f.0 * f.1 == prod);        }    }}

4、

use std::cmp::Ordering;fn product_fib(prod: u64) -> (u64, u64, bool) {    let mut fib_vec: Vec<u64> = vec![0,1];    let mut v_len = fib_vec.len();    loop {        let (n, n_1) = (fib_vec[v_len-1], fib_vec[v_len-2]);        match (n*n_1).cmp(&prod) {            Ordering::Less => {                let next_fib = n + n_1;                fib_vec.push(next_fib);                v_len = fib_vec.len();            },            Ordering::Equal => { return (n_1, n, true); },            Ordering::Greater => { return (n_1, n, false); },        }    }}