Rust : codewars的Product of consecutive Fib numbers

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); },
        }
    }
}

你可能感兴趣的:(rust,算法)