mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	 716610ae56
			
		
	
	
		716610ae56
		
	
	
	
	
		
			
			git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56937 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			92 lines
		
	
	
	
		
			1.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
	
		
			1.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # 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
 | |
| 
 |