Skip to content

Instantly share code, notes, and snippets.

@radarek
Created January 11, 2009 14:37
Show Gist options
  • Save radarek/45711 to your computer and use it in GitHub Desktop.
Save radarek/45711 to your computer and use it in GitHub Desktop.
$ time ruby1.8.6 pidigits.rb 10000
real 0m33.041s
user 0m30.546s
sys 0m2.076s
$ time jruby --server pidigits.rb 10000 > /dev/null
real 1m25.524s
user 1m23.693s
sys 0m0.924s
$ time ruby1.9.1 pidigits.rb 10000 > /dev/null
real 0m42.396s
user 0m40.655s
sys 0m1.652s
class PiDigitSpigot
def initialize()
@z = Transformation.new 1,0,0,1
@x = Transformation.new 0,0,0,0
@inverse = Transformation.new 0,0,0,0
end
def next!
@y = @z.extract(3)
if safe? @y
@z = produce(@y)
@y
else
@z = consume @x.next!()
next!()
end
end
def safe?(digit)
digit == @z.extract(4)
end
def produce(i)
@inverse.qrst(10,-10*i,0,1).compose(@z)
end
def consume(a)
@z.compose(a)
end
end
class Transformation
attr_reader :q, :r, :s, :t
def initialize (q, r, s, t)
@q,@r,@s,@t,@k = q,r,s,t,0
end
def next!()
@q = @k = @k + 1
@r = 4 * @k + 2
@s = 0
@t = 2 * @k + 1
self
end
def extract(j)
(@q * j + @r) / (@s * j + @t)
end
def compose(a)
self.class.new( @q * a.q,
@q * a.r + r * a.t,
@s * a.q + t * a.s,
@s * a.r + t * a.t
)
end
def qrst *args
initialize *args
self
end
end
WIDTH = 10
n = Integer(ARGV[0])
j = 0
digits = PiDigitSpigot.new
while n > 0
if n >= WIDTH
WIDTH.times {digits.next!}
j += WIDTH
else
n.times {digits.next!}
#(WIDTH-n).times {print " "}
j += n
end
#puts "\t:"+j.to_s
n -= WIDTH
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment