I am attempting to memoize my implementation of a Pascal's triangle generator, as a Ruby learning experiment. I have the following working code:
module PascalMemo
@cache = {}
def PascalMemo::get(r,c)
if @cache[[r,c]].nil? then
if c == 0 || c == r then
@cache[[r,c]] = 1
else
@cache[[r,c]] = PascalMemo::get(r - 1, c) + PascalMemo::get(r - 1, c - 1)
end
end
@cache[[r,c]]
end
end
def pascal_memo (r,c)
PascalMemo::get(r,c)
end
Can this be made more concise? Specifically, can I create a globally-scoped function with a local closure more simply than this?
def pascal_memo
cache = [[1]]
get = lambda { |r, c|
( cache[r] or cache[r] = [1] + [nil] * (r - 1) + [1] )[c] or
cache[r][c] = get.(r - 1, c) + get.(r - 1, c - 1)
}
end
p = pascal_memo
p.( 10, 7 ) #=> 120
Please note that the above construct does achieve memoization, it is not just a simple recursive method.
Can this be made more concise?
It seems pretty clear, IMO, and moduleing is usually a good instinct.
can I create a globally-scoped function with a local closure more simply than this?
Another option would be a recursive lambda:
memo = {}
pascal_memo = lambda do |r, c|
if memo[[r,c]].nil?
if c == 0 || c == r
memo[[r,c]] = 1
else
memo[[r,c]] = pascal_memo[r - 1, c] + pascal_memo[r - 1, c - 1]
end
end
memo[[r,c]]
end
pascal_memo[10, 2]
# => 45
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With