Pandigital Fibonacci ends
The Fibonacci sequence is defined by the recurrence relation:
It turns out that F541, which contains 113 digits, is the first Fibonacci number for which the last nine digits are 1-9 pandigital (contain all the digits 1 to 9, but not necessarily in order). And F2749, which contains 575 digits, is the first Fibonacci number for which the first nine digits are 1-9 pandigital.
Given that Fk is the first Fibonacci number for which the first nine digits AND the last nine digits are 1-9 pandigital, find k.
两端为全数字的斐波那契数
斐波那契数列由如下递归关系生成:
可以发现,包含有113位数字的F541是第一个后9位数字是1至9全数字(包含1至9所有的数字,但不一定按照从小到大的顺序)的斐波那契数,而包含有575位数字的F2749是第一个前9位数字是1至9全数字的斐波那契数。
若Fk是第一个前9位数字和后9位数字都是1至9全数字的斐波那契数,求k。
package projecteuler;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import junit.framework.TestCase;
public class Prj104 extends TestCase {
public static final int TAIL_BITS = 9;
public void testPandigitalFibonacciEnds() {
int[] a = enLarge(int2Arr(1), TAIL_BITS);
int[] b = enLarge(int2Arr(1), TAIL_BITS);
int n = 2;
while (true) {
int[] c = add(a, b);
a = Arrays.copyOf(b, TAIL_BITS);
b = Arrays.copyOf(c, TAIL_BITS);
n++;
if (isHeadPandigital(getHead(n)) && isTailPandigital(c)) {
System.out.println("num=" + n);
break;
}
}
}
private boolean isTailPandigital(int[] c) {
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < c.length; i++) {
if (set.contains(c[i])) {
return false;
}
set.add(c[i]);
}
return true;
}
String getHead(int n) {
double v = fibonacci(n);
v -= Math.floor(v);
v = Math.pow(10.0, v);
while (v < 100000000) {
v *= 10;
}
return Integer.toString((int) v);
}
double fibonacci(int n) {
return -0.5 * Math.log(5.0) / Math.log(10.0) + ((double) n)
* Math.log((Math.sqrt(5.0) + 1) / 2) / Math.log(10.0);
}
boolean isHeadPandigital(String str) {
if (str.length() < 9) {
return false;
}
String head = str.substring(0, 9);
assert (head.length() == 9);
return head.length() == 9 && head.indexOf('1') != -1
&& head.indexOf('2') != -1 && head.indexOf('3') != -1
&& head.indexOf('4') != -1 && head.indexOf('5') != -1
&& head.indexOf('6') != -1 && head.indexOf('7') != -1
&& head.indexOf('8') != -1 && head.indexOf('9') != -1;
}
int[] add(int[] a, int[] b) {
assert (a.length == b.length);
int[] ret = new int[a.length];
for( int i = 0 ; i < a.length; i ++){
ret[i] = a[i] + b[i];
}
for( int j = a.length - 1; j > 0; j --){
ret[j - 1] += ret[j] / 10;
ret[j ] %= 10;
}
ret[0] %= 10;
return ret;
}
int[] int2Arr(int val) {
String str = Integer.toString(val, 10);
int[] ret = new int[str.length()];
for (int i = 0; i < ret.length; i++) {
ret[i] = Integer.parseInt(String.valueOf(str.charAt(i)));
}
return ret;
}
int[] enLarge(int[] val, int bits) {
assert (val.length <= bits);
int[] ret = new int[bits];
for (int i = bits - val.length, j = 0; i < bits; i++, j++) {
ret[i] = val[j];
}
return ret;
}
}