Problem with Euler 27
Euler published the remarkable quadratic formula: n² + n + 41 It turns out that the formula will produce 40 primes for the consecutive
values n = 0 to 39. However, when n = 40, 40^(2) + 40 + 41 = 40(40 + 1) + 41 is divisible by 41, and certainly when n = 41, 41² + 41 + 41 is clearly divisible by 41.
Using computers, the incredible formula n² − 79n + 1601 was
discovered, which produces 80 primes for the consecutive values n = 0 to 79. The product of the coefficients, −79 and 1601, is −126479.
Considering quadratics of the form: n² + an + b, where |a| < 1000 and |b| < 1000 where |n| is the modulus/absolute value of n e.g. |11| = 11 and |−4| = 4 Find the product of the coefficients, a and b, for the
quadratic expression that produces the maximum number of primes for consecutive values of n, starting with n = 0.
This is the problem for Euler 27.
I have attempted a solution for trying to find the equation n^2 + n + 41 to see if my logic is correct then I will attempt to see if it works on the actual problem. Here is my code (I will place comments explaining the whole program also, I would start reading from the int main function first) just make sure to read the comments so you can understand my logic:
#include <iostream>
using namespace std;
bool isPrime(int c) {
int test;
//Eliminate with some simple primes to start off with to increase speed...
if (c == 2) {
return true;
}
if (c == 3) {
return true;
}
if (c == 5) {
return true;
}
//Actual elimination starts here.
if (c <= 1 || c % 2 == 0 || c % 3 == 0 || c % 5 == 0) {
return false;
}
//Then using brute 开发者_如何学Pythonforce test if c is divisible by anything lower than it except 1
//only if it gets past the first round of elimination, and if it doesn't
//pass this round return false.
for (test = c; test > 1; test--) {
if (c % test == 0) {
return false;
}
}
//If the c pasts all these tests it should be prime, therefore return true.
return true;
}
int main (int argc, char * const argv[]) {
//a as in n^2 + "a"n + b
int a = 0;
//b as in n^2 + an + "b"
int b = 0;
//n as in "n"^2 + a"n" + b
int n = 0;
//this will hold the result of n^2 + an + b so if n = 1 a = 1
//and b = 1 then c = 1^2 + 1(1) + 1 = 3
int c = 0;
//bestChain: This is to keep track for the longest chain of primes
//in a row found.
int bestChain = 0;
//chain: the current amount of primes in a row.
int chain = 0;
//bestAB: Will hold the value for the two numbers a and b that
// give the most consecutive primes.
int bestAB[2] = { 0 };
//Check every value of a in this loop
for (a = 0; a < 40; a++) {
//Check every value of b in this loop.
for (b = 0; b < 42; b++) {
//Give c a starting value
c = n*n + a*n + b;
//(1)Check if it is prime. And keep checking until it is not
//and keep incrementing n and the chain. (2)If it not prime then che
//ck if chain is the highest chain and assign the bestChain
// to the current chain. (3)Either way reset the values
// of n and chain.
//(1)
while (isPrime(c) == true) {
n++;
c = n*n + a*n + b;
chain++;
}
//(2)
if (bestChain < chain) {
bestChain = chain;
bestAB[0] = a;
bestAB[1] = b;
chain = 0;
n = 0;
}
//(3)
else {
n = 0;
chain = 0;
}
}
}
//Lastly print out the best values of a and b.
cout << bestAB[0] << " " << bestAB[1];
return 0;
}
But, I get the results 0 and 2 for a and b respectively, why is this so? Where am I going wrong? If it is still unclear just ask for more clarification on a specific area.
Your isprime method is inefficient -- but also wrong:
for (test = c; test > 1; test--) {
if (c % test == 0) {
return false;
}
}
in the first iteration of the for loop, test
= c
, so c % test
is just c % c
, which will always be 0. So your isprime method claims everything is non-prime (other than 2, 3, 5)
for (test = c; test > 1; test--) {
if (c % test == 0) {
return false;
}
}
Do you see the problem with that? If not, try working out some small sample values by hand.
As pointed out by others, your problem is in the isPrime method (test = c
, so test % c = c % c == 0
is always true).
You can make your isPrime
function run in O(sqrt(n)) instead of O(n) by initializing test
to sqrt(c) (and only checking odd numbers). It is easy to see that if a number A is divisible by B < sqrt(A), then C = A/B must be > sqrt(A). Thus if there are no divisors < sqrt(A), there will be no divisors > sqrt(A).
Of course, you can run it a whole lot faster even, by using a probabilistic primality test, e.g. Miller-Rabin's primality test.
Also, I'm not sure, but I suspect you might reach the limit of int
fairly quickly. It's probably a better idea to use unsigned long long
from the start, before you start getting strange errors due to overflow & wrapping.
精彩评论