Begin forwarded message:

> From: Matthew Smillie <M.B.Smillie / sms.ed.ac.uk>
> Date: June 23, 2006 11:45:38 AM CDT
> To: submission / rubyquiz.com
> Subject: Re: Please Forward: Ruby Quiz Submission
>
> # Ruby quiz #84, Pascal's Triangle
>
> class PascTri
>   # You can consider the triangle to be a set of diagonals
>   # in a 2-dimensional array.  This recursively calculates
>   # the value of any cell in that array.  If speed was a
>   # concern, you could make the array explicit, and cache
>   # calculated values in it.
>   def val(a, b)
>     (a == 0 or b == 0) ? 1 : val(a-1, b) + val(a, b-1)
>   end
>
>   # return the values for a given row in the triangle,
>   # i.e., a particular diagonal in the implicit array.
>   def row(n)
>     (0...n).map { |i| val(i, n-1-i) }
>   end
>
>   def print(row_total)
>     # print using rows * 2 - 1 columns with a width
>     # matching width of the largest number, which will
>     # always be in the middle of the array section.
>     cols = row_total * 2 - 1
>     row_str = "%#{val(row_total/2, row_total/2).to_s.length}s" *  
> cols + "\n"
>
>     # we're going to use nil as a spacer where the data
>     # shouldn't be.  We'll put spacers on each side of the
>     # data portion, and intersperce the data array with nils,
>     # simultaneously converting the data to strings to match
>     # the print format.  A splat converts the array to a list
>     # of args for printf.
>     (1..row_total).each { |row|
>       # the spacer is the number of columns, less the amount
>       # taken up by the data portion, split into two sections
>       # (the number is always even) for the left and right.
>       spacer = [nil] * ((cols - (row * 2 - 1)) / 2)
>       printf(row_str, *(spacer + row(row).map { |x| [x.to_s,  
> nil]}.flatten[0...-1] + spacer))
>     }
>   end
> end
>
> PascTri.new.print(ARGV[0].to_i)
>