Hello all,

The output is almost perfect on a console, plus different fonts have
different widths for different numbers. So I guess the look of the
triangles will vary with email clients. I'd like to give credit to my
friend Fedor for coming up with much of the output equation. The
output works for any size output (notice how the spacing get smaller
toward the middle).



$ ./pp_pascal.rb 10
                     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

$ ./pp_pascal.rb 15
                                               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
                 1    10    45   120   210   252   210   120    45    10     1
              1    11    55   165   330   462   462   330   165    55
  11     1
           1    12    66   220   495   792   924   792   495   220
66    12     1
        1    13    78   286   715  1287  1716  1716  1287   715   286
  78    13     1
     1    14    91   364  1001  2002  3003  3432  3003  2002  1001
364    91    14     1


On an Athlon64 1.8 GHz
$ time ./pp_pascal.rb 666 > /dev/null

real    0m16.337s
user    0m16.147s
sys     0m0.185s

And finally the code:

#!/usr/bin/ruby
$factCache = [ 1 ]
def factorial(n)
        return $factCache[n] if n <= $factCache.length
        prod = $factCache.last
        while $factCache.length <= n
                $factCache.push(prod *= $factCache.length)
        end
        return prod
end

def pascalCombination(n, k)
        return factorial(n) / (factorial(k) * factorial(n - k))
end

max = $*[0].to_i - 1
maxDigits = Math.log10(pascalCombination(max, max/2)).floor + 1
spaces = (maxDigits + maxDigits/2).ceil
for row in 0..max
        print " " * ((max - row)*spaces/2)
        for col in 0..row
                combination = pascalCombination(row, col)
                digitSpace = Math.log10(combination).floor + 1
                digitSpace = 1 if digitSpace == 0
                print " " * (spaces - digitSpace) + combination.to_s
        end
        print "\n"
end