I have this school problem about a person name Dorel which for his birthday receives a number n
.
He thought to color all natural numbers from 1 to n with one color so that all of his own divisors of a number have the same color as the number.
The problem asks to find out what is the maximum number of colors that can be used.
As an example, with n = 5
you have:
- 1 red
- 2 green
- 3 blue
- 4 green
- 5 yellow
So in this example, we need 4 colors.
The exercise can be found here but it's in romanian.
The problem arise with prime numbers, so I was thinking of a way to calculate how many prime numbers there are from 1
to n
and then add that to the amount of colors needed.
I tried complicated solutions like implementing Miller-Rabin primality test, and Eratosthenes but for the automated tests on the website it's still too slow.
Am I missing something or the only way to solve this problem is to find every prime between 1 and n?
My implementation of Eratosthenes following Wikipedia example:
/* https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Overview */
void prime(uint n) {
if (n < 1) return;
/* Create a list of consecutive integers from 2 through n: (2, 3, 4, ..., n). */
uint size = n - 1;
uint *list = (uint *)malloc(sizeof(uint) * size);
for (uint i = 0; i < size; i++) {
list[i] = i + 2;
}
/* Initially, let p equal 2, the smallest prime number. */
uint p = 2;
uint c = 1;
while (c < n) {
/*
* Enumerate the multiples of p by counting in increments of p from 2p to n,
* and mark them in the list (these will be 2p, 3p, 4p, ...; the p itself should not be marked).
*/
for (uint i = c; i < size; i++) {
if (list[i] % p == 0) {
list[i] = 0;
}
}
/*
* Find the first number greater than p in the list that is not marked.
* If there was no such number, stop.
* Otherwise, let p now equal this new number (which is the next prime).
*/
while (c < n) {
if (list[c] > p) {
p = list[c++];
break;
}
c++;
}
}
/* the numbers remaining not marked in the list are all the primes below n */
for (uint i = 0; i < size; i++) {
if (list[i] != 0) {
printf("%d ", list[i]);
}
}
printf("\n\n");
}