--dTy3Mrz/UPE2dbVg
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Hi,

I just had to do this on myself. And because I can't rest until it
looks perfect, I couldn't submit my first version and had to polish it
this whole night, so here it is.

~/ruby/% time ./pascal.rb 666 >/dev/null
./pascal.rb 666 > /dev/null  34,36s user 0,82s system 99% cpu 35,508 total

... which isn't too shabby for a very limited P2-350.


#!/usr/bin/ruby

# Pascal Triangle for Ruby Quiz #84
# (C) 2006 Jgen Strobel <juergen / strobel.info>
#
# This program is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation;
# either version 2 of the License, or (at your option) any
# later version.

# This solution keeps only one row in memory over every (row)
# iteration, and hands created rows to a pretty printer one by one. A
# custom pretty printer may be given as a block.

# The provided pretty printer does not strive for a maximally
# condensed triangle in all cases. It precalculate the width of the
# largest number and forces an odd field width so String#center always
# just looks nice.

module Pascal

  def triangle(lines, &pretty_printer)
    !block_given? && pretty_printer = std_pretty_printer(lines)
    line = [ ]
    lines.times do
      prev = 0
      line = line.map { |v| r, prev = prev + v, v; r } + [ 1 ]
      pretty_printer.call(line)
    end
  end

  def std_pretty_printer(lines)
    width = cell_width(lines)
    linewidth = lines * width
    proc do |l|
      puts l.map { |n| n.to_s.center(width) }.join.center(linewidth) 
    end
  end

  def sierpinski_pretty_printer(lines, odd="  ", even="**")
    w = lines*odd.length
    proc do |l|
      puts l.map { |n| if (n%2).zero? then even else odd end }.join.center(w)
    end
  end

  private
  def factorial(n)
    (2..n).inject(1) { |a,b| a*b }
  end
  def cell_width(l)
    a = l - 1
    b = a/2.floor
    c = (factorial(a) / (factorial(b) * factorial(a-b))).to_s.length
    c + 2 - (c % 2)
  end

  module_function :triangle, :std_pretty_printer, :sierpinski_pretty_printer
  module_function :factorial, :cell_width
end

if __FILE__ == $0
  lines = ARGV[0] ? ARGV[0].to_i : 10
  Pascal::triangle(lines)    
  #Pascal::triangle(lines) { |l| puts l.join(" ") }
  #Pascal::triangle(lines, &Pascal::sierpinski_pretty_printer(lines, "/\\","))
end

##########snip

~/ruby/% ./pascal.rb 12
                       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

-Jgen

-- 
 The box said it requires Windows 95 or better so I installed Linux

--dTy3Mrz/UPE2dbVg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: Digital signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (GNU/Linux)

iQEVAwUBRKNpi/y64gyiEfXtAQKmsggAuZP7CE0TLEiQ6sC2HZNvbdUErjL1hxCQ
gbIKEfl0El2QsFlNTKZHo4zQdktLm8qxEXHpTKAkUP/UqCjRt10W+2lFyZwI1ciT
F+FQ3nnv7WpcLM27QqgFNg87pqgt/gKqlEsJf5HpTVB8YiOB+Q+hQw5cZp1B/x96
OUCigkuwvHXwz2sAM2XJTsS4MRdJJFrIv3Md2AkUbQNuc6vlu/WjC0+asVs0cSRu
xqjl3gxcJ5Ugyh4OVw+OnjVjHc94j50SlXrGLgI+Nvm8csqeWKlZtijPqiGrEDxZ
/p9CygR/5cMUqO9vM+sdqhRjvRdUwG2axgjcAoMAi/HRkEd7dOMaZQnH
-----END PGP SIGNATURE-----

--dTy3Mrz/UPE2dbVg--