Skip to content

Instantly share code, notes, and snippets.

@danlucraft
Created December 6, 2010 09:22
Show Gist options
  • Save danlucraft/730049 to your computer and use it in GitHub Desktop.
Save danlucraft/730049 to your computer and use it in GitHub Desktop.
# The Great Computer Language Shootout
# http://shootout.alioth.debian.org/
#
# contributed by Gabriele Renzi
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
def compute_pidigits(count)
n = count
j = 0
digits = PiDigitSpigot.new
while n > 0
if n >= WIDTH
WIDTH.times { print digits.next! }
j += WIDTH
else
n.times {print digits.next!}
(WIDTH-n).times { " "}
j += n
end
n -= WIDTH
end
puts
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment