```Hi,

here is my solution and a unit test. The triangle is calculated and
stored as an array  of
arrays first. Then it's converted to a string.

I couldn't resist to add a pair iterator to class Array...

Regards,
Boris

# pascal.rb
class Array
# iterate through pairs of consecutive elements
def each_pair
(0..size-2).each do |i|
yield(self[i], self[i+1])
end
end
end

class Pascal
def initialize(n)
@triangle = [[1]]
2.upto(n) do
@triangle << calc_row(lastrow)
end
end

def lastrow; @triangle[-1]; end

# calculate row given the previous row
def calc_row(previous)
thisrow = [1]
previous.each_pair do |x, y|
thisrow << x + y
end
thisrow << 1
end

def to_s
cellwidth   = lastrow.max.to_s.size
indentation = lastrow.size - 1
emptycell   = ' ' * cellwidth
s = ''
@triangle.each do |row|
s << emptycell * indentation
s << row.map{|cell| cell.to_s.center(cellwidth)}.join(emptycell)
s << "\n"
indentation -= 1
end
s
end
end

if \$0 == __FILE__
puts Pascal.new(ARGV[0].to_i).to_s
end

# pascal_test.rb
require 'pascal'
require 'test/unit'

class PascalTest < Test::Unit::TestCase
def test_1
expected = "1\n"
assert_equal expected, Pascal.new(1).to_s
end

def test_2
assert_equal <<EXPECTED, Pascal.new(2).to_s
1
1 1
EXPECTED
end

def test_3
assert_equal <<EXPECTED, Pascal.new(3).to_s
1
1 1
1 2 1
EXPECTED
end

def test_10
assert_equal <<EXPECTED, Pascal.new(10).to_s
1
1     1
1     2     1
1     3     3     1
1     4     6     4     1
1     5    10    10     5     1
1     6    15    20    15     6     1
1     7    21    35    35    21     7     1
1     8    28    56    70    56    28     8     1
1     9    36    84    126   126   84    36     9     1
EXPECTED
end
end

```