Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby Pascal's triangle generator with memoization

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?

like image 487
Aniket Schneider Avatar asked Dec 01 '25 18:12

Aniket Schneider


2 Answers

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.

like image 102
Boris Stitnicky Avatar answered Dec 03 '25 17:12

Boris Stitnicky


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
like image 36
pje Avatar answered Dec 03 '25 15:12

pje



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!