Friday, March 16, 2007

pascal's triangle

While reading SICP recently, I came across a exercise which asks reader to generate Pascal's Triangle using recursion.

There are many interesting observations about values that get generated in this triangle. One thing I noticed is, sum all the values generated at each level = 2^(level-1) if you start counting levels from 1.

So I thought, lets give it a try .. and it was not difficult to come up with this version.

# Pascal's triangle

# store to avoid recomputation of the same values
$val_store = {}

def getval(row, position)
val = 0
if position <= 0 or row <= 0 or position > row
val = 0
end
if position == 1 or row == 1 or row == position
val = 1
else
# first check in the store
if $val_store["#{row}:#{position}"]
val = $val_store["#{row}:#{position}"]
else
val = getval(row - 1, position - 1) + getval(row - 1 , position)
$val_store["#{row}:#{position}"] = val
end
end
return val
end

def get_row_vals(row)
row_vals = []
i = 0
row.times {
i = i + 1
row_vals << getval(row, i)
}
return row_vals
end

rows = ARGV[0].to_i || 20
i = 1
rows.times {
sum = 0

row_vals = get_row_vals i
row_vals.each { |val|
sum += val
}
puts "Sum: #{sum} Row #{i}: #{row_vals.inspect}"
i = i + 1
}
puts "Store size: #{$val_store.length}"


Next thing ... try to implement using lisp?

1 comment:

Abhijit said...

The idea here is to write pascal's triangle in a slightly modified way and then the solution comes in a jiffie

Write it as follows -

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1

Try it if it works - (written really long time back!)

Basically the solution below provides all the elements of a row can be easily extended for generating entire triangle.

(define (pascal-triangle-elem column row)
(cond ((< row column) 0)
((= column 1) 1)
((= row column) 1)
((> row column) (+ (pascal-triangle-elem (- column 1) (- row 1)) (pascal-triangle-elem column (- row 1)) ))
))


(define (pascal-triangle-iter column row)
(cond ((< column row) (pascal-triangle-elem column row))
(pascal-triangle-iter (+ 1 column) row))
)

(define (pascal-row row)
(cond ((< row 0) 0)
((= row 0) 0)
(else (pascal-triangle-iter 1 row))
))