OSDN Git Service

ruby-1.9.1-rc1
[splhack/AndroidRuby.git] / lib / ruby-1.9.1-rc1 / benchmark / bm_so_pidigits.rb
diff --git a/lib/ruby-1.9.1-rc1/benchmark/bm_so_pidigits.rb b/lib/ruby-1.9.1-rc1/benchmark/bm_so_pidigits.rb
new file mode 100644 (file)
index 0000000..c7d6fbf
--- /dev/null
@@ -0,0 +1,92 @@
+# 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
+n = 2_500 # Integer(ARGV[0])
+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 {print " "}
+        j += n
+    end
+    puts "\t:"+j.to_s
+    n -= WIDTH
+end
+