--=-d4NHtwFFrRPFz3NU4wzt
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
Here's an explanation about how to calculate the next row,
based on the previous row. You only need the last line.
row ===> [1, 3, 3, 1]
[0]+row ===> [0, 1, 3, 3, 1]
row+[0] ===> [1, 3, 3, 1, 0]
([0]+row).zip(row+[0]) ===> [[0, 1], [1, 3], [3, 3],
[3, 1], [1, 0]]
([0]+row).zip(row+[0]).map{|a,b|a+b} ===> [1, 4, 6, 4, 1]
You can replace the last line by the next line, but this one
modifies the previous row, which might be tricky. Though it
does save you one extra byte ;]
([0]+row).zip(row<<0).map{|a,b|a+b} ===> [1, 4, 6, 4, 1]
You could build and store the complete triangle with this:
t=[r=[1]]+(2..n).map{r=([0]+r).zip(r+[0]).map{|a,b|a+b}}
(But that's not what we are going to do in this script....)
I added pretty printing as well. First of all, the width of
each cell (excluding the separator) shouldn't be even, in order
to be able to align properly.
Secondly, if we can't center the contents within a cell, we
error to the right on the left hand side of the triangle and to
the left at the right hand side.
Thirdly, because the last line could be stripped by half a cell
width at both the left and the right hand side, we simply strip
every line by half a cell width on both sides.
You can find the source in the attachment.
gegroet,
Erik V. - http://www.erikveen.dds.nl/
--=-d4NHtwFFrRPFz3NU4wzt
Content-Disposition: attachment; filename=pascaltriangle.rb
Content-Type: text/plain; name=pascaltriangle.rb; charset=utf-8
Content-Transfer-Encoding: 7bit
rows = (ARGV.shift || 10).to_i # The number of rows.
fac = lambda{|n| n <=1 ? 1 : (1..n).inject{|a, b| a*b}} # Faculty of n.
cell = lambda{|r, c| fac[r-1]/fac[c-1]/fac[r-c]} # The content of a specific cell.
biggest = cell[rows, rows/2+1] # The biggest number in the last row.
width = biggest.to_s.length # The width of each cell...
width +=1 if width % 2 == 0 # ...but it shouldn't be even.
(1..rows).inject([1]) do |row, row_nr| # Start with row=[1].
line =
(0...row_nr).map do |cell_nr| # Each cell should have the correct width.
cell = row[cell_nr].to_s # Get the contents of the cell.
rhs = !lhs = cell_nr < row_nr/2 # Are we in the right hand side or in the left hand side of the triangle?
left = (width+1 - cell.length)/2 if lhs # Number of padding characters at the left, within the cell, erroring to the right.
left = (width+0 - cell.length)/2 if rhs # Number of padding characters at the left, within the cell, erroring to the left.
right = (width - cell.length - left)
" "*left + cell + " "*right # The new contents of the cell.
end.join(" ") # Join the cells into a line.
left = (rows - row_nr) * (width/2+1) # Number of padding characters at the left, on the line.
line = " "*left + line
margin = width/2 # Half the cell width...
line = line[margin...-margin] # ...can be stripped at the left and at the right of the line.
puts line # Print it!
([0]+row).zip(row+[0]).map{|a, b| a+b} unless row_nr == rows # Build the next row. It's explained below.
end
--=-d4NHtwFFrRPFz3NU4wzt--