import java.math.BigInteger;

public class Factorial_11_Caching {
   public static final int MAX = 30; 
   static int count = 0;  // How many values have we cached so far?
   static BigInteger [] vals = new BigInteger[MAX+1];  // the cache
   static { vals[0] = BigInteger.ONE; }       // Static initializer
   
   /* Return the factorial of n */
   public static BigInteger factorial(int n) {
      if (n < 0 || n > MAX)
         throw new IllegalArgumentException();
      if (n <= count)  // If we have already computed it �
         return vals[n];
      BigInteger val = 
         new BigInteger(n+ "").multiply(factorial(n-1));
      vals[n] = val;  // Cache the computed value before returning it
      return val;
    }
   
   public static void main(String[] args) {
      for (int i=0; i <= MAX; i++) 
         System.out.println(i + "! = " + factorial(i) );
   }
}