Sei sulla pagina 1di 5

Counting Fractions

Written by Andrew Lee (http://wildandrewlee.com)


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