# Pascal's Triangle (Ruby Quiz #84)
# by Mustafa Yilmaz
#
# This is the second Ruby program I've ever written and it's not
optimized (and probably not
# leveraging the power of Ruby), so don't expect to much ;-) The code
should be self-explanatory,
# if you have any questions though don't hesitate to ask me.
#
# My approach is to create a PDF file using the PDF::Writer libraries in
order to get the
# centering right. Furthermore, I'm computing the binomial coefficent as
discussed before to
# approximate the width of the largest number in the triangle.
#
# One could improve the program by dynamically adjusting the used text
size to scale the text
# depending on the size of the triangle to make use of the whole page size.
#
# You can download an example pdf file from
http://www.mustafayilmaz.net/pascal.pdf
#
begin
require 'pdf/writer'
rescue LoadError => le
if le.message =~ %r{pdf/writer$}
$LOAD_PATH.unshift("../lib")
require 'pdf/writer'
else
raise
end
end
class Integer
def factorial
self <= 1 ? 1 : self * (self-1).factorial
end
end
class Binomial_Coefficient
def self.compute(n, r)
n.factorial / (r.factorial * (n-r).factorial)
end
end
class Pascal
def self.create_pdf(lines, font_size, filename)
max_width = Binomial_Coefficient.compute(lines, lines /
2).to_s.length + 2
pdf = PDF::Writer.new(:paper => "A4", :orientation => :landscape)
pdf.select_font "Courier"
pdf.text "Pascal's Triangle (Ruby Quiz #84)\n\n\n", :font_size =>
10, :justification => :center
previous_result = Array.[](0, 1, 0)
s = "1".center(max_width)
while lines > 0 do
pdf.text "#{s}\n\n", :font_size => font_size, :justification =>
:center
current_result = Array.new
previous_result[0..-2].each_index do |i|
current_result << previous_result[i] + previous_result[i+1]
end
s = String.new
current_result.each_index do |i|
s << current_result[i].to_s.center(max_width)
end
current_result = Array.[](0).concat(current_result) << 0
previous_result = current_result
lines -= 1
end
pdf.save_as(filename)
end
end
Pascal.create_pdf(20, 8, "pascal.pdf")