#Why does my Cache struct not work as intended?

8 messages · Page 1 of 1 (latest)

proper shard
#

I created a cache struct that has a hashmap that stores the digits of the fibonacci sequence, i thought it would help me to speed up the recursive algo, but it seems like i didn't implement is properly? Thanks in advance.

#
#![allow(unused_imports,unused_variables)]

use std::collections::hash_map::HashMap;
use malachite::Integer;
use malachite::integer::conversion::primitive_int_from_integer::SignedFromIntegerError;

struct Cache<T>
where 
    T: Fn(Integer) -> Integer,
{
    calc_fn: T ,
    hashmap: HashMap<i32,Integer>, 
}

impl<T> Cache<T>
where 
    T: Fn(Integer) -> Integer,
{
    fn new(calc_fn: T) -> Cache<T> {
        Cache {
            calc_fn,
            hashmap: HashMap::new(),
        }
    }

    fn get_value(&mut self, digit: i32) -> Integer {
        match self.hashmap.get(&digit) {
            Some(v) => v.clone(),
            None => {
                let big_int_digit = Integer::from(digit.clone());
                let v = (self.calc_fn)(big_int_digit);
                
                self.hashmap.insert(
                    digit , v.clone()
                );
                return v
            }
        }
    }
}

fn fib(n: Integer) -> Integer {
    if n < 2 {return n}
    
    let one: Integer = Integer::from(1);
    let two: Integer = Integer::from(2);

    return fib(n.clone() - one) + fib(n - two)
}

fn main() {
    let mut s = String::new();
    println!("N: ");
    std::io::stdin()
        .read_line(&mut s)
        .expect("failed to read line");

    let n: i32 = s
        .trim()
        .parse()
        .expect("failed to parse n");

    let mut cache_object = Cache::new(fib);

    println!("\n");

    for i in 1..=n {    
        let r = cache_object.get_value(i);
        println!("Digit n{i}: {r}")
    }
}
glacial trail
#

fib is a recursive function, that directly calls itself. Wrapping fib with Cache cannot make fib check the cache when it recurses.

proper shard
#

i see... So i have to give the fib function a way to access the hashmap?

#

maybe pass it as &mut ?

glacial trail
#

that will work

#

it is often the case that if you want to cache things you also want interior mutability (i.e. not needing &mut) so that it still looks like a "pure function" from the outside

#

but there is no need to reach for that until you need it