Package

Source Code of p104

/*
* Solution to Project Euler problem 104
* By Nayuki Minase
*
* http://nayuki.eigenstate.org/page/project-euler-solutions
* https://github.com/nayuki/Project-Euler-solutions
*/

import java.math.BigInteger;
import java.util.Arrays;


public final class p104 implements EulerSolution {
 
  public static void main(String[] args) {
    System.out.println(new p104().run());
  }
 
 
  public String run() {
    int i = 0;
    int a = 0;
    int b = 1;
    while (!isFound(i, a)) {
      int c = (a + b) % 1000000000;
      a = b;
      b = c;
      i++;
    }
    return Integer.toString(i);
  }
 
 
  private static boolean isFound(int n, int fibMod) {
    if (!isPandigital(Integer.toString(fibMod)))
      return false;
    BigInteger fib = fibonacci(n);
    if (fib.mod(BigInteger.valueOf(1000000000)).intValue() != fibMod)
      throw new AssertionError();
    return isPandigital(leading9Digits(fib));
  }
 
 
  private static String leading9Digits(BigInteger x) {
    // We know that x.bitLength() = floor(log2(x)) + 1.
    // Now compute an approximate base-10 logarithm, because log10(2) = 0.301... .
    // The computed quantity is no larger than floor(log10(x)).
    int log10 = (x.bitLength() - 1) * 3 / 10;
   
    // Chop off quite a number of rightmost base-10 digits.
    // It is guaranteed that there remains at least 9 digits.
    x = x.divide(BigInteger.TEN.pow(Math.max(log10 + 1 - 9, 0)));
   
    // Deal with the remaining smaller number.
    return x.toString().substring(0, 9);
  }
 
 
  private static boolean isPandigital(String s) {
    if (s.length() != 9)
      return false;
    char[] temp = s.toCharArray();
    Arrays.sort(temp);
    return new String(temp).equals("123456789");
  }
 
 
  private static BigInteger fibonacci(int n) {
    BigInteger a = BigInteger.ZERO;
    BigInteger b = BigInteger.ONE;
    int m = 0;
    for (int i = 31; i >= 0; i--) {
      // Loop invariant: a = f(m), b = f(m+1)
     
      // Double it
      BigInteger d = Library.multiply(a, b.shiftLeft(1).subtract(a));
      BigInteger e = Library.multiply(a, a).add(Library.multiply(b, b));
      a = d;
      b = e;
      m *= 2;
     
      // Advance by one conditionally
      if (((1 << i) & n) != 0) {
        BigInteger c = a.add(b);
        a = b;
        b = c;
        m++;
      }
    }
    return a;
  }
 
}
TOP

Related Classes of p104

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.