memoization

Project Euler 14: performance compared to C and memoization

谁都会走 提交于 2019-12-01 03:11:31
I'm currently working on project euler problem 14 . I solved it using a poorly coded program, without memoization, that took 386 5 seconds to run (see edit). Here it is: step :: (Integer, Int) -> Integer -> (Integer, Int) step (i, m) n | nextValue > m = (n, nextValue) | otherwise = (i, m) where nextValue = syr n 1 syr :: Integer -> Int -> Int syr 1 acc = acc syr x acc | even x = syr (x `div` 2) (acc + 1) | otherwise = syr (3 * x + 1) (acc + 1) p14 = foldl step (0, 0) [500000..999999] My question is about several comments in the thread related to this problem, where were mentionned execution

Two argument Memoization

允我心安 提交于 2019-11-30 22:48:57
In C# how do I memoize a function with two arguments? Do I have to curry before memoization? Wes Dyer wrote the Memoization code I typically use, but now I need two arguments You just make an overloaded version of the Memoize method that has three generic types and takes a function with two parameters, and the two arguments. It still returns a parameterless function: public static Func<R> Memoize<A1,A2,R>(this Func<A1,A2,R> f, A1 a1, A2 a2) { R value = default(R); bool hasValue = false; return () => { if (!hasValue) { hasValue = true; value = f(a1,a2); } return value; }; } Edit: Alternatively,

Memoization in OCaml?

风格不统一 提交于 2019-11-30 15:22:50
It is possible to improve "raw" Fibonacci recursive procedure Fib[n_] := If[n < 2, n, Fib[n - 1] + Fib[n - 2]] with Fib[n_] := Fib[n] = If[n < 2, n, Fib[n - 1] + Fib[n - 2]] in Wolfram Mathematica. First version will suffer from exponential explosion while second one will not since Mathematica will see repeating function calls in expression and memoize (reuse) them. Is it possible to do the same in OCaml? How to improve let rec fib n = if n<2 then n else fib (n-1) + fib (n-2);; in the same manner? You pretty much do what the mathematica version does but manually: let rec fib = let cache =

How to memoize recursive functions?

一笑奈何 提交于 2019-11-30 13:48:53
Consider a recursive function, say the Euclid algorithm defined by: let rec gcd a b = let (q, r) = (a / b, a mod b) in if r = 0 then b else gcd b r (This is a simplified, very brittle definition.) How to memoize such a function? The classical approach of defining a high-order function memoize : ('a -> 'b) -> ('a -> 'b) adding memoization to the function is here useless, because it will only save time on the first call. I have found details on how to memoize such function in Lisp or Haskell: How do I memoize a recursive function in Lisp? Memoization with recursion These suggestions rely on the

Memoization Handler

白昼怎懂夜的黑 提交于 2019-11-30 12:52:26
Is it "good practice" to create a class like the one below that can handle the memoization process for you? The benefits of memoization are so great (in some cases, like this one, where it drops from 501003 to 1507 function calls and from 1.409 to 0.006 seconds of CPU time on my computer) that it seems a class like this would be useful. However, I've read only negative comments on the usage of eval() . Is this usage of it excusable, given the flexibility this approach offers? This can save any returned value automatically at the cost of losing side effects. Thanks. import cProfile class

Ruby Conditional-Assignment and Private Methods

为君一笑 提交于 2019-11-30 11:51:50
From the code below, it appears the ||= operator is being evaluated from outside of the class. class Foo attr_reader :bar def baz self.bar ||= 'baz' end private attr_writer :bar end puts Foo.new.baz # => in `baz': private method `bar=' called for #<Foo:0x007fd9720829a8> (NoMethodError) Quoting from the accepted answer on Official expansion of ||= conditional assignment operator : In other words, the expansion c = c || 3 is (excluding bugs like in pre-1.9) correct. Rewriting the baz method as self.bar = self.bar || 'baz' does not raise the error. I am looking for a definitive answer on how and

How do I generate memoized recursive functions in Clojure?

孤者浪人 提交于 2019-11-30 11:48:10
问题 I'm trying to write a function that returns a memoized recursive function in Clojure, but I'm having trouble making the recursive function see its own memoized bindings. Is this because there is no var created? Also, why can't I use memoize on the local binding created with let? This slightly unusual Fibonacci sequence maker that starts at a particular number is an example of what I wish I could do: (defn make-fibo [y] (memoize (fn fib [x] (if (< x 2) y (+ (fib (- x 1)) (fib (- x 2)))))))

What is the lifetime of a memoized value in a functional language like Haskell?

一笑奈何 提交于 2019-11-30 06:50:51
In a pure functional language with lazy semantics (such as Haskell), results of computations are memoized so that further evaluations of a function with the same inputs do not recompute the value but get it directly from the cache of memoized values. I am wondering if these memoized values get recycled at some point in time? If so, it means that the memoized values must be recomputed at a later time, and the benefits of memoization are not so exiting IMHO. If not, then ok, this is clever to cache everything... but does it mean that a program - if run for a sufficient long period of time - will

In Ruby, should I use ||= or if defined? for memoization?

可紊 提交于 2019-11-30 06:43:22
Should I use if defined? return @current_user_session if defined?(@current_user_session) @current_user_session = UserSession.find Or ||= @current_user_session ||= UserSession.find I noticed the if defined? method being used more and more recently. Is there any advantage to one over the other? Personally, I prefer ||= for readability. I also think Rails might have a memoize macro which provides this behavior transparently. Is this the case? Be careful: x ||= y assigns x = y if x returns false. That may mean that x is undefined, nil, or false. There are many times variables will be defined and

Thread-safe memoization

送分小仙女□ 提交于 2019-11-30 05:55:32
问题 Let's take Wes Dyer's approach to function memoization as the starting point: public static Func<A, R> Memoize<A, R>(this Func<A, R> f) { var map = new Dictionary<A, R>(); return a => { R value; if (map.TryGetValue(a, out value)) return value; value = f(a); map.Add(a, value); return value; }; } The problem is, when using it from multiple threads, we can get into trouble: Func<int, int> f = ... var f1 = f.Memoize(); ... in thread 1: var y1 = f1(1); in thread 2: var y2 = f1(1); // We may be