数学之谜 - 如何在Java中用数字解决?

时间:2013-09-19 07:48:09

标签: java algorithm math

所以这个谜语是:

John写下k个连续的奇数:n{1}, n{2}, ..., n{k-1}, n{k}(其中n{2} = n{1} + 2等等)。我们知道:

  • 前四个数字的总和是某个素数的四次幂(所以n{1} + n{2} + n{3} + n{4} = p{1} p{1}^4是素数。
  • 最后五个数字的总和是某个素数的四次幂(所以n{k} + n{k-1} + n{k-2} + n{k-3} + n{k-4}= p{2}^4 p{1}是素数。

问题是 - 已写下了多少个数字(k=?)。

以下是我尝试用Java解决它:

import java.math.BigInteger;
import java.util.Set;

//precalculate prime numbers
public class PrimeSieve {


 public static boolean[] calculateIntegers(int N) { 


    // initially assume all integers are prime
    boolean[] isPrime = new boolean[N + 1];
    for (int i = 2; i <= N; i++) {
        isPrime[i] = true;
    }

    // mark non-primes <= N using Sieve of Eratosthenes
    for (int i = 2; i*i <= N; i++) {

        // if i is prime, then mark multiples of i as nonprime
        // suffices to consider mutiples i, i+1, ..., N/i
        if (isPrime[i]) {
            for (int j = i; i*j <= N; j++) {
                isPrime[i*j] = false;
            }
        }
    }

    return isPrime;
  }
}

解决课程:

public class Solver {
    static boolean[] isPrime = PrimeSieve.calculateIntegers(100000);

    public static void main(String[] args) {

        int minNumberCount = 5;
        int maxNumberCount = 2000;
        int startInt = 2;
        int endInt = 1000000;

        for (int numberCount = minNumberCount; numberCount < maxNumberCount+1; numberCount++) {
            System.out.println("Analyzing for " + numberCount + " numbers");

            int[] numbers = new int[numberCount];

            //loop through number sets
            for (int firstNum = startInt; firstNum < endInt; firstNum+=2) {

               //populate numbers array
                for(int j=0; j<numberCount; j++){
                    numbers[j] = firstNum + j*2;
                }

                long bottomSum=0;
                long topSum=0;

                //calculate bottom sum
                for(int iter=0; iter<4; iter++){
                    bottomSum+=numbers[iter];
                }

                //calculate top sum
                for(int iter=numberCount-1; iter>numberCount-6; iter--){
                    topSum+=numbers[iter];
                }

                //check if the sums match the sulution criteria
                if(checkPrime(quadRoot(bottomSum)) && checkPrime(quadRoot(topSum))){
                    System.out.println("SOLUTION!");

                    for (int i = 0; i < numbers.length; i++) {
                        System.out.print(numbers[i] + " ");
                    }
                    System.exit(0);
                }
            }       
        }
    }

    private static boolean checkPrime(int i){
        return isPrime[i];
    }

    private static boolean checkPrime(double i){
        return ((i % 1) == 0) && checkPrime((int) i);
    }

    private static double quadRoot(long n){
        return Math.sqrt(Math.sqrt(n));
    }

 }

将此算法与假设参数(max k=2000,max n{1}=100000)一起使用 - 我找不到任何解决方案。我的问题是:参数假设是错误的(在此范围内没有解决方案),或者我是否有一些算法/数字错误,这就是我找不到解决方案的原因?

编辑:抱歉 - 我的错误 - 应该是ODD而不是偶然。

3 个答案:

答案 0 :(得分:4)

直接解决这个问题比编写程序更容易。

第一个总和是,所以它必须是16(因为2是唯一的偶数素数)。因此,前四个数字为1,3,5,7。

五个连续奇数的总和是中间数的5倍,因此必须可以被5整除。因为它是素数的四次幂,它必须是625,因此最后五个数是121,123,125,127,129

现在确定k = 65

是一项简单的任务

答案 1 :(得分:0)

正如评论中所说,你的谜语没有解决方案。

我们假设有一个解决方案,然后n1 + n2 + n3 + n4 == p1^4。我们知道n1,n2,n3,n4甚至来自谜语的定义,因此作为偶数的总和,n1 + n2 + n3 + n4也是如此。这导致我们p1^4是偶数的事实。我们知道两个奇数的乘法只得到一个奇数,因此p1^4 = p1 * p1 * p1 * p1表示p1必须是偶数。但是,p1是素数。唯一的素数也是2.很容易看出,没有四个连续的偶数总和达到16,因此p1不是素数。这与p1是素数的假设相矛盾,因此没有解决方案。

答案 2 :(得分:0)

如果只有偶数,那么它们的总和是偶数。如果我理解正确,你的总和必须是素数的四次幂的结果。考虑到总和是偶数,唯一满足条件的数字是16(2 * 2 * 2 * 2),其中2是素数,所以你的4偶数之和必须是16.现在,如果你确定有一个序列,然后通过在序列中加上第一个和最后一个数字,然后将结果乘以序列中的元素数,并将乘法的结果除以2来计算总和。例如, 2 + 4 + 6 + 8 =(2 + 8)* 4/2 = 10 * 4/2 = 20。同样,对于您的示例,n {1} + n {2} + ... + n {k} =(n {1} + n {k})* k / 2 在旁注中,我使用的示例中最小的4个偶数(20)的总和已经高于素数(16)的唯一4次幂,所以是的,序列中没有有效的例子。

我希望这有点道理