Search code examples
memoizationrustcollatz

Keeping a variable alive across multiple function calls in rust


I am trying to memoize a recursive collatz sequence function in rust, however I need the hashmap of memoized values to keep its contents across separate function calls. Is there an elegant way to do this in rust, or do I have to declare the hashmap in main and pass it to the function each time? I believe the hashmap is being redeclared as an empty map each time I call the function. Here is my code:

fn collatz(n: int) -> int {
    let mut map = HashMap::<int, int>::new();
    if map.contains_key(&n) {return *map.get(&n);}
    if n == 1 { return 0; }
    map.insert(n, 
        match n % 2 {
            0 => { 1 + collatz(n/2) }
            _ => { 1 + collatz(n*3+1) }
        }
    );
    return *map.get(&n);
}

On a side note, why do I need to add all of the &'s and *'s when I am inserting and pulling items out of the HashMap? I just did it because the compiler was complaining and adding them fixed it but I'm not sure why. Can't I just pass by value? Thanks.


Solution

  • You can use thread_local for thread-local statics.

    thread_local! (static COLLATZ_MEM: HashMap<i32, i32> = HashMap::new());
    fn collatz(n: i32) -> i32 {
        COLLATZ_MEM.with (|collatz_mem| {
            0  // Your code here.
        })
    }
    

    P.S. There's also an excellent lazy-static macro which can be used for the truly global static caches. Here's an example.