project euler 80

Problem 80


Square root digital expansion

It is well known that if the square root of a natural number is not an integer, then it is irrational. The decimal expansion of such square roots is infinite without any repeating pattern at all.

The square root of two is 1.41421356237309504880…, and the digital sum of the first one hundred decimal digits is 475.

For the first one hundred natural numbers, find the total of the digital sums of the first one hundred decimal digits for all the irrational square roots.


平方根数字展开

众所周知,如果一个自然数的平方根不是整数,那么就一定是无理数。这样的平方根的小数部分是无限不循环的。

2的平方根为1.41421356237309504880…,它的小数点后一百位数字的和是475。

对于前一百个自然数,求所有无理数平方根小数点后一百位数字的总和。

package projecteuler;

import java.math.BigInteger;

import junit.framework.TestCase;

public class Prj80 extends TestCase {

	public static final int LIMIT_NUM = 100;
	public static final int LIMIT_DIGIT = 100;

	public void testSquareRootDigitalExpansion() {

		int sum = 0;
		for (int i = 2; i <= LIMIT_NUM; i++) {
			if (!isSquare(i)) {
				String str = calSquareRootUseBigInteger(2, LIMIT_DIGIT + 5);
				int dotId = str.indexOf(".") + 1;
				str = str.substring(dotId, dotId + LIMIT_DIGIT);
				//System.out.println(str);
				for (int j = 0; j < LIMIT_DIGIT; j++) {
					sum += Integer.parseInt(String.valueOf(str.charAt(j)));
					//System.out.print(str.charAt(j));
				}
			}
		}
		System.out.println("sum=" + sum);
	}

	/**
	 * https://en.wikipedia.org/wiki/Methods_of_computing_square_roots;
	 * http://www.numberworld.org/digits/Sqrt(2)/
	 * 
	 * @param val
	 * @return
	 */
	public String calSquareRootUseBigInteger(int val, int digit) {
		StringBuilder sb = new StringBuilder();

		BigInteger p = BigInteger.ZERO;
		BigInteger const20 = new BigInteger("20");
		BigInteger const_1 = new BigInteger("-1");
		int[] arr = int2Arr(val);
		assert (arr.length >= 2);

		BigInteger c = BigInteger
				.valueOf(arr2Int(new int[] { arr[0], arr[1] }));
		int cid = 2;

		int count = 0;
		boolean flag = true;
		while (true) {

			BigInteger x = BigInteger.ZERO;

			BigInteger tp = const20;
			tp = tp.multiply(p).add(x).multiply(x);
			while (tp.compareTo(c) <= 0) {

				BigInteger _val = x.add(BigInteger.ONE).multiply(
						p.multiply(const20).add(x).add(BigInteger.ONE));
				if (_val.compareTo(c) > 0) {
					assert (x.intValue() >= 0 && x.intValue() <= 9);
					break;
				} else {
					x = x.add(BigInteger.ONE);
				}
				tp = const20;
				tp = tp.multiply(p).add(x).multiply(x);

			}

			c = p.multiply(const20).add(x).multiply(const_1).multiply(x).add(c);
			p = p.multiply(BigInteger.TEN).add(x);

			// System.out.println("p[" + count + "]=" + p);
			sb.append(x);
			if (cid >= arr.length) {
				c = c.multiply(BigInteger.TEN).multiply(BigInteger.TEN);
				if (flag) {
					sb.append(".");
					flag = false;
				}
			} else {
				cid += 2;
				c = c.multiply(BigInteger.TEN)
						.multiply(BigInteger.TEN)
						.add(new BigInteger(Integer
								.toString(10 * arr[cid - 1 - 1])))
						.add(new BigInteger(Integer.toString(arr[cid - 1])));
			}

			count++;
			if (count > digit) {
				break;
			}

		}

		return sb.toString();
	}

	public boolean isSquare(int val) {
		int _val = (int) Math.sqrt(val);
		return _val * _val == val;
	}

	/**
	 * 1.41421356237309504880
	 * 
	 * @param val
	 * @return
	 */
	public String calSquareRoot(int val, int digit) {
		StringBuilder sb = new StringBuilder();

		int p = 0;
		int[] arr = int2Arr(val);
		assert (arr.length >= 2);

		int c = arr2Int(new int[] { arr[0], arr[1] });
		int cid = 2;

		int count = 0;
		boolean flag = true;
		while (true) {

			int x = 0;
			while (x * (20 * p + x) <= c) {
				int _val = (x + 1) * (20 * p + x + 1);
				if (_val > c) {
					assert (x >= 0 && x <= 9);

					break;
				} else {
					x++;
				}

			}
			c = c - x * (20 * p + x);
			p = 10 * p + x;

			System.out.println("p[" + count + "]=" + p);
			System.out.println("c[" + count + "]=" + c);
			sb.append(x);
			if (cid >= arr.length) {
				c = 100 * c;
				if (flag) {
					sb.append(".");
					flag = false;
				}
			} else {
				c = 100 * c + 10 * arr[cid - 1 - 1] + arr[cid - 1];
			}

			count++;
			if (count > digit) {
				break;
			}

		}

		return sb.toString();
	}

	int[] int2Arr(int val) {
		String str = Integer.toString(val);
		int count = str.length() % 2 == 0 ? str.length() : str.length() + 1;
		if (str.length() % 2 != 0) {
			str = "0" + str;
		}
		int[] ret = new int[count];

		for (int i = 0; i < ret.length; i++) {
			ret[i] = Integer.parseInt(String.valueOf(str.charAt(i)));
		}
		return ret;
	}

	int arr2Int(int[] arr) {
		int ret = 0;

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

		return ret;
	}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值