http://projecteuler.net/index.php?section=problems&id=5
I’ll be honest, I solved this one on paper first and then figured out how to do it programatically. I don’t mean that I brainstormed a solution for a simpler case and then came up with an algorithm to get a solution for this problem… I mean I did the whole thing on paper and then once I had an answer I figured out how to write the program. Is that cheating? lol
Anyway, my first thought was that I may be able to find a subset of numbers from 1 to 20 whose product will be the solution. For example, for the simpler solution of 1 to 10, 1*5*7*8*9 yields the solution. (The 1 is included for completeness… you’ll see.) Eventually I realized that it wasn’t those actual values that caused their product to be the solution… it was the prime factorization of those values. Take the prime factorization for each number from 1 to 10:
1 = 1^1
2 = 1^1 * 2^1
3 = 1^1 * 3^1
4 = 1^1 * 2^2
5 = 1^1 * 5^1
6 = 1^1 * 2^1 * 3^1
7 = 1^1 * 7^1
8 = 1^1 * 2^3
9 = 1^1 * 3^3
10 = 1^1 * 2^1 * 5^1
The special thing about the values 5, 7, 8 and 9 is that the degrees for each prime number in their factorization are maximums of all other degrees for that prime. The highest degree of 1 is 1, the highest degree of 2 is 3, of 3 is 3, of 5 is 1, and of 7 is 1.
I then went through and figured out the prime factorization for 11 to 20:
11 = 1^1 * 11^1
12 = 1^1 * 2^2 * 3^1
13 = 1^1 * 13^1
14 = 1^1 * 2^1 * 7^1
15 = 1^1 * 3^1 * 5^1
16 = 1^1 * 2^4
17 = 1^1 * 17^1
18 = 1^1 * 2^1 * 9^1
19 = 1^1 * 19^1
20 = 1^1 * 2^2 * 5^1
Following the logic from before, my new set of highest degrees is:
1 – 1
2 – 4
3 – 2
5 – 1
7 – 1
11 – 1
13 – 1
17 – 1
19 – 1
So, this means that 1, 16, 9, 5, 7, 11, 13, 17 and 19 are the numbers that yield the maximum degree for each prime. Multiply them together, and you get the answer.
After I wrote a program to do what I’d done manually, I realized that it would be a lot cleaner to just loop through each number, check the factorization and see if one of the degrees produced is more than a previous degree.
I was a little concerned about the correctness because I need to make sure that if 1 is the highest degree for 5, the 5^1 from 5 is used… not, say, from 20. If I do somehow use the 5^1 from the 20, I want to make sure I don’t also use the 2^2 from 20, since another number had a higher degree for 2. I did a few test causes and I’m fairly confident that this won’t happen since I’m checking each prime individually.
/* Project Euler - Problem 5 (http://projecteuler.net/index.php?section=problems&id=5)
*
* Finds the highest degree for each prime number in the prime factorization of
* all numbers from 1 to 20. Each prime is then raised to it's highest degree and
* multiplied.
*/
public static void p5(){
/* All primes from 1 to 20 */
int degrees[][] = {{2,0}, {3,0}, {5,0}, {7,0}, {11,0}, {13,0}, {17,0}, {19,0}};
int n=1;
/* For each number, get the prime factorization. If the degree is
* greater than the current degree for any given prime, replace it.
*/
for(int i=1; i<=20; i++)
for(int j=0; j<degrees.length; j++)
if(getDegree(i, degrees[j][0]) > degrees[j][1])
degrees[j][1] = getDegree(i,degrees[j][0]);
/* Get the product of each prime raised to it's highest degree */
for(int i=0; i<degrees.length; i++)
n = n * (int)Math.pow(degrees[i][0], degrees[i][1]);
System.out.println(n);
}
public static int getDegree(int num, int prime){
int count = 0;
while(num % prime == 0){
count++;
num = num/prime;
}
return count;
}
Note: After I wrote this I checked the forum on http://projecteuler.net and it looks like others solved it similarly, but without quite as much running around in circles
) Oops!