project euler 58

Problem 58


Spiral primes

Starting with 1 and spiralling anticlockwise in the following way, a square spiral with side length 7 is formed.

37 36 35 34 33 32  31
38  17 16 15 14  13 30
39 18   5  4   3 12 29
40 19  6  1  2 11 28
41 20   7  8  9 10 27
42 21 22 23 24 25 26
43 44 45 46 47 48 49

It is interesting to note that the odd squares lie along the bottom right diagonal, but what is more interesting is that 8 out of the 13 numbers lying along both diagonals are prime; that is, a ratio of 8/13 ≈ 62%.

If one complete new layer is wrapped around the spiral above, a square spiral with side length 9 will be formed. If this process is continued, what is the side length of the square spiral for which the ratio of primes along both diagonals first falls below 10%?


螺旋素数
从1开始逆时针螺旋着摆放自然数,我们可以构造出一个边长为7的螺旋数阵。

37 36 35 34 33 32  31
38  17 16 15 14  13 30
39 18   5  4   3 12 29
40 19  6  1  2 11 28
41 20   7  8  9 10 27
42 21 22 23 24 25 26
43 44 45 46 47 48 49

可以发现,所有的奇数平方都在这个螺旋方针的右下对角线上,更有趣的是,在所有对角线上一共有8个素数,比例达到8/13 ≈ 62%。

在这个方阵外面完整地再加上一层,就能构造出一个边长为9的螺旋方阵。如果不断重复这个过程,当对角线上素数的比例第一次低于10%时,螺旋数阵的边长是多少?

import java.util.Arrays;

import junit.framework.TestCase;

public class Prj58 extends TestCase {


	public void testSpiralPrimes() {

		iterOverFourCorner();
	}

	public void iterOverFourCorner() {

		int total = 5;
		int numOfPrims = 3;
		int[] start = new int[] { 3, 5, 7, 9 };
		int step = 0;
		for (int i = 5;; i = i + 2) {

			step = i - 1;
			start = Arrays.copyOf(getNext(start[3] + step, step), 4);

			total += 4;
			if (isPrime(start[0])) {
				numOfPrims += 1;
			}
			if (isPrime(start[1])) {
				numOfPrims += 1;
			}
			if (isPrime(start[2])) {
				numOfPrims += 1;
			}
			if (isPrime(start[3])) {
				numOfPrims += 1;
			}

			if (10 * numOfPrims < total) {
				System.out.println("len=" + i + ",num=" + numOfPrims + "total=" + total);
				break;
			}
		}

	}

	public boolean isPrime(int val) {
		if (val <= 10) {
			if (val == 2 || val == 3 || val == 5 || val == 7) {
				return true;
			}
			return false;
		}

		for (int i = 2; i * i <= val; i++) {
			if (val % i == 0) {
				return false;
			}
		}
		return true;
	}

	private int[] getNext(int start, int step) {
		return new int[] { start, start + step, start + 2 * step,
				start + 3 * step };
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值