Advertisement
jeff1203

Fib

May 21st, 2011
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.31 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3.  
  4. using BigInt = System.Numerics.BigInteger;
  5.  
  6. namespace FibTest
  7. {
  8.     class Program
  9.     {
  10.         static void Main(string[] args)
  11.         {
  12.             for (int n = 0; n < 136; n++)
  13.             {
  14.                 var f = Fib(n);
  15.                 //var b = Fib_b(n);
  16.                 var b = Fib_x(n);
  17.                 Console.WriteLine("{0,3}: ({1,14}) {2,28} {3,28}", n, b - f, f, b);
  18.                 Console.WriteLine();
  19.             }
  20.         }
  21.  
  22.         static readonly Dictionary<int, BigInt> memo = new Dictionary<int, BigInt>();
  23.         static BigInt Fib(int n)
  24.         {
  25.             BigInt result;
  26.             if (!memo.TryGetValue(n, out result))
  27.             {
  28.                 if (n < 2)
  29.                     memo[n] = result = BigInt.Max(0, n);
  30.                 else
  31.                     memo[n] = result = Fib(n - 1) + Fib(n - 2);
  32.             }
  33.             return result;
  34.         }
  35.  
  36.         static readonly double RAD5 = Math.Sqrt(5);
  37.         static readonly double PHI = (1 + RAD5) / 2;
  38.         static BigInt Fib_b(int n)
  39.         {
  40.             double result = Math.Pow(PHI, n) / RAD5;
  41.             return (BigInt)Math.Round(result);
  42.         }
  43.  
  44.         struct Ext
  45.         {
  46.             private BigInt a;
  47.             private BigInt b;
  48.  
  49.             public Ext(BigInt a, BigInt b)
  50.             {
  51.                 this.a = a;
  52.                 this.b = b;
  53.             }
  54.             public BigInt A { get { return a; } }
  55.             public BigInt B { get { return b; } }
  56.  
  57.             // twoPhi = Ext 1 1
  58.             public static readonly Ext TWO_PHI = new Ext(1, 1);
  59.  
  60.             // fromInteger a = Ext a 0
  61.             public static implicit operator Ext(BigInt a)
  62.             {
  63.                 return new Ext(a, 0);
  64.             }
  65.  
  66.             // negate (Ext a b) = Ext (-a) (-b)
  67.             public static Ext operator -(Ext x)
  68.             {
  69.                 return new Ext(-x.a, -x.b);
  70.             }
  71.  
  72.             // (Ext a b) + (Ext c d) = Ext (a+c) (b+d)
  73.             public static Ext operator +(Ext x, Ext y)
  74.             {
  75.                 return new Ext(x.a + y.a, x.b + y.b);
  76.             }
  77.  
  78.             // just in case
  79.             public static Ext operator -(Ext x, Ext y)
  80.             {
  81.                 return x + -y;
  82.             }
  83.  
  84.             // (Ext a b) * (Ext c d) = Ext (a*c + 5*b*d) (a*d + b*c)
  85.             public static Ext operator *(Ext x, Ext y)
  86.             {
  87.                 return new Ext(x.a + y.a + 5*x.b*y.b, x.a*y.b + x.b*y.a);
  88.             }
  89.  
  90.             public static Ext operator ^(Ext x, int p) // "exponent"
  91.             {
  92.                 // just apply across both parts of Ext?
  93.                 return new Ext(BigInt.Pow(x.a, p), BigInt.Pow(x.b, p));
  94.             }
  95.         }
  96.  
  97.         static BigInt Fib_x(int n)
  98.         {
  99.             // fib n = divide $ twoPhi^n - (2-twoPhi)^n
  100.  
  101.             Ext x = (Ext.TWO_PHI ^ n) - (((BigInt)2 - Ext.TWO_PHI) ^ n);
  102.             //    subtraction needed? ^             ^
  103.  
  104.             return divide(x, n);
  105.         }
  106.  
  107.         static BigInt divide(Ext x, int n)
  108.         {
  109.             // divide (Ext 0 b) = b `div` 2^n
  110.             //             ^ divide only if 0?
  111.             //               or a "don't care" value?
  112.  
  113.             return x.B / BigInt.Pow(2, n);
  114.         }
  115.     }
  116. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement