project euler 65

Problem 65


Convergents of e

The square root of 2 can be written as an infinite continued fraction.

2=1+12+12+12+12+

The infinite continued fraction can be written, √2 = [1;(2)], (2) indicates that 2 repeats ad infinitum. In a similar way, √23 = [4;(1,3,1,8)].

It turns out that the sequence of partial values of continued fractions for square roots provide the best rational approximations. Let us consider the convergents for √2.

1+12=32

1+12+12=75

1+12+12+12=1712

1+12+12+12+12=4129

Hence the sequence of the first ten convergents for √2 are:

1, 3/2, 7/5, 17/12, 41/29, 99/70, 239/169, 577/408, 1393/985, 3363/2378, …

What is most surprising is that the important mathematical constant,
e = [2; 1,2,1, 1,4,1, 1,6,1 , … , 1,2k,1, …].

The first ten terms in the sequence of convergents for e are:

2, 3, 8/3, 11/4, 19/7, 87/32, 106/39, 193/71, 1264/465, 1457/536, …

The sum of digits in the numerator of the 10th convergent is 1+4+5+7=17.

Find the sum of digits in the numerator of the 100th convergent of the continued fraction for e.


e的有理逼近
2的算术平方根可以写成无限连分数的形式。

2=1+12+12+12+12+

这个无限连分数可以简记为√2 = [1;(2)],其中(2)表示2无限重复。同样的,我们可以记√23 = [4;(1,3,1,8)]。

可以证明,截取算术平方根连分数表示的一部分所组成的序列,给出了一系列最佳有理逼近值。让我们来考虑√2的逼近值:

1+12=32

1+12+12=75

1+12+12+12=1712

1+12+12+12+12=4129

因此√2的前十个逼近值为:

1, 3/2, 7/5, 17/12, 41/29, 99/70, 239/169, 577/408, 1393/985, 3363/2378, …

最令人惊讶的莫过于重要的数学常数e有如下连分数表示
e = [2; 1,2,1, 1,4,1, 1,6,1 , … , 1,2k,1, …]。

e的前十个逼近值为:

2, 3, 8/3, 11/4, 19/7, 87/32, 106/39, 193/71, 1264/465, 1457/536, …

第10个逼近值的分子各位数字之和为1+4+5+7=17。

求e的第100个逼近值的分子各位数字之和。

package cuppics;

import java.util.Arrays;

import junit.framework.TestCase;

public class Prj65 extends TestCase {

	public static final int NUM_OF_CHOOSE = 100;

	public void testSquareRootConvergents() {
		String str = iterArr(NUM_OF_CHOOSE);
		
		int sum = 0;
		for( int i = 0  ; i < str.length(); i ++){
			sum += Integer.parseInt( String.valueOf( str.charAt(i)));
		}
		
		String fstr = "sum=%d";
		fstr = String.format(fstr, sum);
		System.out.println(fstr);
	}

	public int getBits() {
		return NUM_OF_CHOOSE * 3 + 1;
	}

	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;

	}

	/**
	 * [a0;a1,a2....] a0/1, (a1a0 + 1)/a1,
	 * 
	 * @param n
	 * @return
	 */
	public String iterArr(int n) {

		int bits = getBits();

		// start
		int a0 = 2;
		int a1 = 1;
		//int an = 2;
		int p0 = a0;
		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 Integer.toString(a0);
		}

		assert (n >= 2);
		int[] pn = enLarge(int2Arr(0), bits);
		int[] qn = enLarge(int2Arr(0), bits);

		int k = 1;
		for (int i = 3; i <= n; i++) {

			if (i % 3 == 0) {
				pn = add(multiply(pn_1, 2 * k), pn_2);
				qn = add(multiply(qn_1, 2 * (k++)), qn_2);
			} else {
				pn = add(multiply(pn_1, 1), pn_2);
				qn = add(multiply(qn_1, 1), 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);
		}

		String str = intArr2Str(pn);
		System.out.println(str);
		return str;
	}

	private String intArr2Str(int[] pn) {
		StringBuilder sb = new StringBuilder();

		int i = 0;
		while (pn[i] == 0) {
			i++;
		}
		for (; i < pn.length; i++) {
			sb.append(pn[i]);
		}
		return sb.toString();

	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值