项目欧拉45

时间:2011-01-01 20:54:14

标签: java algorithm

我还不是一个熟练的程序员,但我认为这是一个有趣的问题,我想我会试一试。

  

三角形,五边形和六边形   数字由以下生成   公式:

     
      
  • 三角形T_(n)= n(n + 1)/ 2   1,3,6,10,15,......
  •   
  • 五角形P_(n)= n(3n-1)/ 2 1,5,12,22,35,   ...
  •   
  • 六角形H_(n)= n(2n-1)1,   6,15,28,45,......
  •   
     

可以验证T_(285)=   P_(165)= H_(143)= 40755。

     

找到下一个三角形数字   也是五边形和六边形。

是任务说明。

我知道六角形数字是三角形数字的子集,这意味着您只需要找到一个Hn = Pn的数字。 但我似乎无法让我的代码工作。我只知道java语言,这就是为什么我在网络上找不到解决方案的原因。无论如何希望有人可以帮忙。这是我的代码

public class NextNumber {

    public NextNumber() {
    next();
    }

    public void next() {


int n = 144;
int i = 165;
int p = i * (3 * i - 1) / 2;
int h = n * (2 * n - 1);
        while(p!=h) {
            n++;
           h = n * (2 * n - 1);

            if (h == p) {
                System.out.println("the next triangular number is" + h);
            } else {
                while (h > p) {
                    i++;
                    p = i * (3 * i - 1) / 2;
                }
                if (h == p) {
                    System.out.println("the next triangular number is" + h); break;
                    }
                 else if (p > h) {
                    System.out.println("bummer");
                }
            }

            }

    }
}

我意识到它可能是一个非常缓慢且无效的代码,但这并不关心我此时我只关心找到下一个数字,即使这会占用我的计算机数年。

3 个答案:

答案 0 :(得分:7)

我们知道T 285 = P 165 = H 143 = 40755.我们从nt=286开始,{{1 }和np=166并计算出相应的三角形,五边形和六边形数字。无论哪个结果数最小,我们都会提高其nh=144值。继续这样做,直到所有数字相等并且你有答案。

此算法的Python实现在我的计算机上运行0.1秒。

您的代码存在问题。虽然答案适合32位n,但临时值int在到达答案之前会溢出。使用64位i * (3 * i - 1)值可修复代码。

答案 1 :(得分:1)

您的代码看起来会很快产生正确的答案。如果您只是在循环终止后打印结果,则可以简化while循环:

while (p != h) {
    n++;
    h = n * (2 * n - 1);
    while (h > p) {
        i++;
        p = i * ((3 * i - 1) / 2);
    }
}
System.out.println("the next triangular number is" + h);

注意:你的内部循环看起来非常像我的C ++解决方案的内部循环。它在我的机器上以大约0.002秒的速度产生了所需的答案。

答案 2 :(得分:1)

2 ms 的另一种解决方案:

public class P45 {

    public static void main(String[] args) {
        long H = 0;
        long i = 144;
        while(true) {
            H = i*((i<<1)-1);
            if ( isPentagonal(H) && isTriangle(H) ) {
                break;
            }
            i++;
        }
        System.out.println(H);
    }

    private static boolean isPentagonal(long x) {
        double n = (1 + Math.sqrt(24*x+1)) / 6;
        return n == (long)n;
    }

    private static boolean isTriangle(long x) {
        double n = (-1 + Math.sqrt((x<<3)+1)) / 2;
        return n == (long)n;
    }

}

<强>提高

  • 您已经指定:六边形数字是三角形数字,但我添加了一个简短的证明:如果k*(2*k-1)i*(i+1)/2可以使用以下格式i = 2*k-1编写。
  • 在这种情况下,isTriangle可以删除。
  • 性能类似,因为该功能很少被调用(仅在数字为五角形时才被调用)。