您的位置:首页 > 其它

project euler 57

2015-12-04 21:44 274 查看


Problem
57

Square root convergents

It is possible to show that the square root of two can be expressed as an infinite continued fraction.

√ 2 = 1 + 1/(2 + 1/(2 + 1/(2 + … ))) = 1.414213…

By expanding this for the first four iterations, we get:

1 + 1/2 = 3/2 = 1.5

1 + 1/(2 + 1/2) = 7/5 = 1.4

1 + 1/(2 + 1/(2 + 1/2)) = 17/12 = 1.41666…

1 + 1/(2 + 1/(2 + 1/(2 + 1/2))) = 41/29 = 1.41379…

The next three expansions are 99/70, 239/169, and 577/408, but the eighth expansion, 1393/985, is the first example where the number of digits in the numerator exceeds the number of digits in the denominator.

In the first one-thousand expansions, how many fractions contain a numerator with more digits than denominator?

平方根逼近

2的平方根可以用一个无限连分数表示:

√ 2 = 1 + 1/(2 + 1/(2 + 1/(2 + … ))) = 1.414213…

将连分数计算取前四次迭代展开式分别是:

1 + 1/2 = 3/2 = 1.5

1 + 1/(2 + 1/2) = 7/5 = 1.4

1 + 1/(2 + 1/(2 + 1/2)) = 17/12 = 1.41666…

1 + 1/(2 + 1/(2 + 1/(2 + 1/2))) = 41/29 = 1.41379…

接下来的三个迭代展开式分别是99/70、239/169和577/408,但是直到第八个迭代展开式1393/985,分子的位数第一次超过分母的位数。

在前一千个迭代展开式中,有多少个分数分子的位数多于分母的位数?

import java.util.Arrays;

import junit.framework.TestCase;

public class Prj57 extends TestCase {

public void testSquareRootConvergents() {
System.out.println("count=" + iterN_Arr(1000));
}

public int getBits() {
return 1000 + 5;
}

public int[] power(int[] arr, int multiplier, int b) {

int[] ret = Arrays.copyOf(arr, arr.length);
int count = b;
while (count > 1) {

ret = multiply(ret, multiplier);
count--;
}

return ret;
}

public int[] multiply(int[] arr, int b) {

int[] ret = Arrays.copyOf(arr, arr.length);

for (int i = 0; i < arr.length; i++) {
ret[i] *= b;
}

for (int i = arr.length - 1; i > 0; i--) {

ret[i - 1] = ret[i - 1] + ret[i] / 10;
ret[i] = ret[i] % 10;
}

return ret;
}

public 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 i = a.length - 1; i > 0; i--) {
ret[i - 1] = ret[i - 1] + ret[i] / 10;
ret[i] %= 10;
}

return ret;
}

public 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;
}

public 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;

}

/**
*
*
* @param n
* @return
*/
public int iterN_Arr(int n) {

int bits = getBits();

int a0 = 1;
int a1 = 2;
int an = 2;
int p0 = 1;
int p1 = a1 * a0 + 1;
int q0 = 1;
int q1 = a1;

int[] pn_1 = enLarge(int2Arr(p1), bits);
int[] pn_2 = enLarge(int2Arr(p0), bits);
int[] qn_1 = enLarge(int2Arr(q1), bits);
int[] qn_2 = enLarge(int2Arr(q0), bits);

if (n == 1) {
return 0;
}

assert (n >= 2);

int count = 0;

int[] pn = enLarge(int2Arr(0), bits);
int[] qn = enLarge(int2Arr(0), bits);;
for (int i = 2; i <= n; i++) {

pn = add(multiply(pn_1, an) ,pn_2);
qn = add(multiply(qn_1, an) ,qn_2);

pn_2 = Arrays.copyOf( pn_1, bits);
pn_1 = Arrays.copyOf( pn, bits);
qn_2 = Arrays.copyOf( qn_1, bits);
qn_1 = Arrays.copyOf( qn, bits);
if( getBitCount(pn) > getBitCount(qn) ){
count += 1;
System.out.println(i);
}
}
return count;
}

private int getBitCount(int[] pn) {

int count = 0;
for( int i = 0  ; i < pn.length; i ++){
if( pn[i] != 0){
break;
}
count ++;
}
return pn.length - count;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: