From: Juergen Strobel Date: 2006-06-29T14:48:00+09:00 Subject: [Solution] [QUIZ] pp Pascal (#84) --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 =2E/pascal.rb 666 > /dev/null 34,36s user 0,82s system 99% cpu 35,508 total =2E.. which isn't too shabby for a very limited P2-350. #!/usr/bin/ruby # Pascal Triangle for Ruby Quiz #84 # (C) 2006 J=FCrgen Strobel # # 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 =3D std_pretty_printer(lines) line =3D [ ] lines.times do prev =3D 0 line =3D line.map { |v| r, prev =3D prev + v, v; r } + [ 1 ] pretty_printer.call(line) end end def std_pretty_printer(lines) width =3D cell_width(lines) linewidth =3D lines * width proc do |l| puts l.map { |n| n.to_s.center(width) }.join.center(linewidth)=20 end end def sierpinski_pretty_printer(lines, odd=3D" ", even=3D"**") w =3D 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 =3D l - 1 b =3D a/2.floor c =3D (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__ =3D=3D $0 lines =3D ARGV[0] ? ARGV[0].to_i : 10 Pascal::triangle(lines) =20 #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 -J=FCrgen --=20 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/HRkEd7dOMaZQ== =G/nH -----END PGP SIGNATURE----- --dTy3Mrz/UPE2dbVg--