项目Euler#49 Java

时间:2017-01-20 19:01:27

标签: java permutation primes

问题是 -

  

算术序列,1487,4817,8147,其中每个术语   增加3330,在两个方面是不寻常的:(i)三个术语中的每一个   是主要的,并且,(ii)每个4位数字是排列的   彼此。

     

没有由三位,二位或三位数组成的算术序列   素数,展示这个属性,但还有另外一个4位数   增加序列。

     

通过连接三个术语,您形成了什么12位数字?   这个序列?

我已经写了这段代码 -

package Problems;

import java.util.ArrayList;
import java.util.LinkedList;

public class Pro49 {

    private static boolean isPrime(int n){
        if(n%2 == 0) return false;

        for(int i = 3; i<= Math.sqrt(n); i++){
            if(n%i == 0) return false;
        }

        return true;
    }

    private static boolean isPerm(int m, int n){
        ArrayList<Integer> mArr = new ArrayList<>();
        ArrayList<Integer> nArr = new ArrayList<>();

        for(int i = 0; i<4; i++){
            mArr.add(m%10);
            m /= 10;
        }

        for(int i = 0; i<4; i++){
            nArr.add(n%10);
            n /= 10;
        }

        return mArr.containsAll(nArr);
    }

    public static void main(String[] args) {

        LinkedList<Integer> primes = new LinkedList<>();

        for(int i = 1001; i<10000; i++){
            if(isPrime(i)) primes.add(i);
        }


        int k = 0;
        boolean breaker = false;
        for(int i = 0; i<primes.size() - 2; i++){
            for(int j = i + 1; j<primes.size() - 1; j++){
                if(isPerm(primes.get(i), primes.get(j))) {
                    k = primes.get(j) + (primes.get(j) - primes.get(i));

                    if(k<10000 && primes.contains(k) && isPerm(primes.get(i), k)) {
                        System.out.println(primes.get(i) + "\n" + primes.get(j) + "\n" + k);
                        breaker = true;
                        break;
                    }

                }
                if(breaker) break;
            }
            if(breaker) break;
        }


    }

}

我添加了打印行System.out.println(primes.get(i) + "\n" + primes.get(j) + "\n" + k);来检查数字。我得到了1049,1499,1949这是错的。 (我猜至少1049是错的。)

任何人都可以指出我的代码/逻辑错误吗? 任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:1)

我认为你的逻辑出错的地方是你的isPerm方法。您正在使用AbstractCollection#containsAll,其中,AFAIK,仅检查参数是否至少在集合中

即。它基本上是

for(E e : collection)
    if(!this.contains(e)) return false;
return true;

因此,例如,4999将是49的排列,因为49包含4和9(虽然它显然不是基于您的示例)。

您的方法似乎适用于这些值的原因是您循环了一段固定的时间 - 即4.对于像49这样的数字,您最终会得到{9, 4, 0, 0}而不是{{1 }}。做这样的事情:

{9, 4}

您将获得正确的数字while(n != 0) { nArr.add(n%10); n /= 10; } (并看到List不起作用。)

在其他位置添加4位数限制(例如在循环中)。

也许你可以检查每个数字的出现次数。 例如:

containsAll

答案 1 :(得分:0)

我找到了isPerm

的替代方法
private static boolean isPerm(int m, int n){
        ArrayList<Integer> mArr = new ArrayList<>();
        ArrayList<Integer> nArr = new ArrayList<>();

        final String mS = Integer.toString(m);
        final String nS = Integer.toString(n);

        if(mS.length() != nS.length()) return false;

        for(int i = 0; i<mS.length(); i++){
            mArr.add(m%10);
            m /= 10;
        }

        for(int i = 0; i<nS.length(); i++){
            nArr.add(n%10);
            n /= 10;
        }

        return (mArr.containsAll(nArr) && nArr.containsAll(mArr));
    }

这给了我正确的答案。另一个替代方案是由下面的其他人发布的。

相关问题