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