Problem Statement: http://projecteuler.net/problem=72 Implementation Language(s): C, Java, Python Before we begin we must understand what a reduced proper fraction is. By denition we know that for a fraction N D such that N < D to be reduced GCF(N, D) must be 1. In other words, a fraction is reduced when N is a totative of D (0 < N < D N D). Since we only need to calculate the number of elements in the set of reduced fractions for D 1 000 000 we can simply count the number of totatives each D has. We can use
nx (n) to achieve this where x = [2, 1 000 000] and (n) (Eulers totient function) is dened below. (n) = n
p prime p|n
1 1 p
The above function is dened as:
The number of totatives of n is equal to n times the product of 1 1 p over the prime factors of n. Since we need to nd the prime factorization of each number n [2, 1 000 000] it would take us forever to solve this problem using a traditional approach. Therefore we will need to look back at a past problem for help. Like in problem 10 we will be using a Sieve of Eratosthenes to generate prime numbers up to a given number. We will be using a modied algorithm for the Sieve where for each prime number p we will multiply each multiple of p by 1 1 P . This way we can multiply each n by 1 1 p for all prime factors p of n. Using this method we can determine whether a number is prime or not by looking at its current value in the array. For example: Let A = [1, 2, 3, 4, 5]. If we were to use our modied sieving algorithm on A the value of A[4] would remain unchanged. This is because no multiple of 2, 3, or 4 equals 5. There- fore we can determine that 5 is a prime number. Conversely the value of A[3] would change because 4 is a multiple of 2. 1 The algorithm we will be using is as goes: 1. Fill an array A with 1 000 000 values such that A = [1, 2, 3, 4, 5...] 2. Let T = 0 represent the number of reduced fractions found 3. Let n = 1 represent the current index of A 4. If A[n] is unchanged then k N.c = k(n+1) 1.c < 1 000 000.A[c] = A[c] (1 1 n+1 ) 5. T = T +A[n] 6. n = n + 1 7. If n < 1 000 000 go back to 4 Translated into pseudocode: function Count(limit): table = [limit] for each index n of table: table[n] = n + 1 total = 0 for each index n of table: if table[n] = n + 1: for each index z of table step n + 1: table[z] = table[z] * (1 - 1 / (n + 1)) total = total + table[n] return total ////////////////// output Count(1000000) 2 C Implementation: #include <stdio.h> #include <stdlib.h> /* * Basic function to fill an array by index. */ void enumerate(int* table, int size){ int n; for(n = 0; n < size; n++){ table[n] = n + 1; } } /* * Compute the number of reduced fractions for D < lim. * Returns a double in case a large limit is used. */ double compute(int lim){ //Memory is manually allocated here to account for //limits that exceed the size of the stack. int* table = malloc(sizeof(int) * lim); enumerate(table, lim); int n, k; double total = 0; for(n = 1; n < lim; n++){ if(table[n] == n + 1){ for(k = n; k < lim; k += n + 1){ table[k] *= 1 - (double) 1 / (n + 1); } } total += table[n]; } free(table); return total; } int main(){ 3 double fractions = compute(1000000); //Print <fractions> using a precision //of 0 after the decimal. printf("%.0lf fractions", fractions); return 0; } Java Implementation: public class Problem72{ /* * Basic function to fill an array by index. */ private static void enumerate(int[] table){ for(int n = 0; n < table.length; n++){ table[n] = n + 1; } } /* * Compute the number of reduced fractions for D < lim. * Returns a double in case a large limit is used. */ private static double compute(int lim){ int[] table = new int[lim]; enumerate(table); double total = 0; for(int n = 1; n < lim; n++){ if(table[n] == n + 1){ for(int k = n; k < lim; k += n + 1){ table[k] *= 1 - (double) 1 / (n + 1); } } total += table[n]; } return total; } public static void main(String... args){ 4 double fractions = compute(1000000); //Print <fractions> using a precision //of 0 after the decimal. System.out.printf("%.0f fractions", fractions); } } Python Implementation: lim = 1000000 table = [x + 1 for x in range(lim)] total = 0 for n in range(1, lim): if table[n] == n + 1: for k in range(n, lim, n + 1): table[k] *= 1 - float(1) / (n + 1) total += table[n] print str(int(total)) + fractions 5