minimal prime generator C - c

I have to create a minimal prime generator in C (we need the minimal primes that have at least two digits) and i cannot use tables.So my thought was first find all the primes,second with using masks to find all the subsequences of each number and finally check if every subsequence is not a prime number.i cannot find the minimal primes because i didnt put a condition to check if a subsequence is prime or no?(my code is not ready so it may have some mistakes but it runs)
my code
#include <stdio.h>
#define MAXNUMB 100
int main ()
{
int i,j,x,mask,max=1,mult,sub;
for (i = 11 ; i < MAXNUMB; i += 2 ) {
for (j = 3; j * j <= i; j += 2) {
if (i % j == 0) {
break;
}
}
if (j * j > i) {
int length = 0;
int tmp=i;
while (tmp != 0) {
tmp /= 10;
length++;
}
for (x=1;x<length*2;x++) {
mask=x;
mult=1;
sub=0;
int num=i;
while ( num != 0 ) {
if ( mask % 2 == 1 ) {
sub += num % 10 * mult;
mult *= 10;
}
num /= 10;
mask /= 2;
}
printf ("%d \n",sub);
}
printf ("%d is minimal prime \n",i);
}
}
}

If MAXNUMB is not too large then you can very quickly find all the primes until MAXNUMB using the Sieve_of_Eratosthenes. After you have that you can get every subsequence of an n-digit number by counting from 1 to 2^n-1 and use the bit-pattern of the current count to specify the current subsequence. Check each subsequence in the sieve.
If MAXNUMB is too big then you can build the sieve up to sqrt(MAXNUMB), so that when you test a number whether it's prime or not you just have to check whether it's divisible with any prime, instead of checking whether it's divisible any odd number.

Wikipedia has a nice pseudocode algorithm for primality. It's naive, but it works.
function is_prime(n : integer)
if n ≤ 1
return false
else if n ≤ 3
return true
else if n mod 2 = 0 or n mod 3 = 0
return false
let i ← 5
while i×i ≤ n
if n mod i = 0 or n mod (i + 2) = 0
return false
i ← i + 6
return true
I'll leave translating this into C for you. My one note is that i should be of a type larger than n's type. For the reason, consider what happens to i×i ≤ n when n is the largest integer.
When you're ready, you can look at my solution to this problem.

The concept of a minimal prime is moderately interesting. I wrote the following code to do the checking.
/* SO 33838621: Minimal Primes */
/*
** Find the minimal primes less than 100,000.
**
** A minimal prime is a prime number for which no subsequence of the digits
** that make up the number is itself prime.
** The question gives two examples:
** = 881 is prime and is a minimal prime because none of { 8, 8, 1, 88,
** 81, 81 } are prime.
** = 109 is prime but is not a minimal prime because { 1, 0, 9, 10, 9,
** 19 } includes the prime 19.
** Clearly, the single digit primes are all trivially minimal.
**
** Additional wrinkle: the code may not build up a table of primes.
**
** NB: All primes except 2 and 3 have the form 6N±1
*/
/*
** There are two problems to solve:
** (1) Check for primality without using a table of primes.
** (2) Generate all subsequences of a number.
** The latter problem is somewhat harder than the former.
** The surviving solution uses recursive string manipulation.
**
** NB: Command subsequences is derived from this, and helps check
** the validity of the minimal primes.
*/
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static bool is_prime(int n)
{
if (n < 2)
return false;
if (n == 2 || n == 3 || n == 5 || n == 7)
return true;
if (n % 2 == 0 || n % 3 == 0 || n % 5 == 0 || n % 7 == 0)
return false;
for (int c = 12; (c - 1) * (c - 1) <= n; c += 6)
{
if (n % (c - 1) == 0 || n % (c + 1) == 0)
return false;
}
return true;
}
static bool has_prime_n_digit_subset(int p0, int n_digits, const char *buffer, int buflen)
{
//printf("-->> p0 = %5d, n = %d (%s)\n", p0, n_digits, buffer);
assert(buflen >= 0 && strlen(buffer) == (size_t)buflen);
for (int i = 0; i < buflen; i++)
{
int p1 = 10 * p0 + buffer[i] - '0';
if (n_digits > 1)
{
if (has_prime_n_digit_subset(p1, n_digits - 1, &buffer[i+1], buflen - i - 1))
{
//printf("<<-- true\n");
return true;
}
}
else
{
//printf("C %d\n", p1);
if (is_prime(p1))
{
//printf("<<-- p1 = %d: true\n", p1);
return true;
}
}
}
//printf("<<-- false\n");
return false;
}
static void check_minimal_prime(int n)
{
assert(n > 0);
if (is_prime(n))
{
//printf("P %d\n", n);
char buffer[20];
sprintf(buffer, "%d", n);
char n_digits = strlen(buffer);
for (int i = 1; i < n_digits; i++)
{
if (has_prime_n_digit_subset(0, i, buffer, n_digits))
return;
}
printf("%d\n", n); /* It's a minimal prime */
}
}
int main(int argc, char **argv)
{
int max = 100000;
if (argc > 2)
{
fprintf(stderr, "Usage: %s [maximum]\n", argv[0]);
exit(1);
}
else if (argc == 2)
{
max = atoi(argv[1]);
if (max <= 0)
{
fprintf(stderr, "Invalid number (%d from %s)\n", max, argv[1]);
exit(1);
}
}
max /= 6;
check_minimal_prime(2);
check_minimal_prime(3);
for (int c = 1; c < max; c++)
{
check_minimal_prime(6 * c - 1);
check_minimal_prime(6 * c + 1);
}
return 0;
}
The list of numbers generated was:
2
3
5
7
11
19
41
61
89
409
449
499
881
991
6469
6949
9001
9049
9649
9949
60649
666649
946669
60000049
66000049
66600049
I didn't find any more minimal primes when checking up to 1,000,000,000. Timing was:
100 0m0.006s
1000 0m0.006s
10000 0m0.006s
100000 0m0.012s
1000000 0m0.129s
10000000 0m2.617s
100000000 1m8.200s
1000000000 32m34.561s

Related

How to find common prime factors of two given numbers in C?

I am trying to solve this problem:
Input: the first line contains an integer T which represents the total cases you need to solve. Each test case contains P and Q, separated by space, represent the number you need to work on.
Output: print the result which is calculated from the multiplication of P and Q’s minimum factor and maximum prime factor.
Constraints: 1 ≤ 𝑇 ≤ 100 and 2 ≤ 𝑃,𝑄 ≤ 1000000
Sample Input: 2 210 84 6 12
Sample Output:
Case #1: 14
Case #2: 6
Explanation: Let’s take an example from the first case. The numbers 210 and 84 have several identical prime factors which are 2, 3, and 7. Number ‘2’ is the smallest common prime factor of the numbers, meanwhile number ‘7’ is their largest common prime factor. So, the result must be the multiplication of 2 and 7, which is 14.
Here's my code that I've been working, I tried to find factors from the given number the store the factors into array then check for the prime, but I feel that this isn't the right algorithm :(
void factor(int num1) {
int arrA[100000], a = 0, flag = 1;
//check factor
for (int i = 2; i <= num1; i++) {
if (num1 % i == 0) {
arrA[a] = i;
a++;
}
}
// check prime
for (int i = 0; i < a; i++) {
for (int j = 2; j < a; j++) {
if ((arrA[i] % j) == 0) {
flag = 0;
}
}
if (flag == 1) {
printf("%d ", arrA[i]);
}
flag = 1;
}
printf("\n");
}
Your function does not compute the prime factors correctly because it will find factors that are not prime. For num = 6, it will find 2, 3 but also 6.
You should divide num by i when you find that i divides num and otherwise increase i.
You can then make arrA much smaller as the maximum number of prime factors in an int is less than the number of bits in an int: 31 would suffice for 32-bit ints and 63 for 64-bit ints.
Once you have the prime factors of num, you should try and find the smallest and largest that divide the other number. Note that the first and last such prime numbers could be identical or might not even exist if the numbers have no common prime factor.
Note that you do not need to store the factors: for every prime factor of num, you can try and check if it divides the other number and keep the first one that does and the last one too.
Here is a simple implementation:
#include <stdio.h>
int main() {
int i, n, a, aa, b, p, p1, p2;
if (scanf("%d", &n) == 1) {
for (i = 1; i <= n; i++) {
if (scanf("%d%d", &a, &b) != 2)
break;
p1 = p2 = 1;
aa = a;
for (p = 2; p * p <= aa; p++) {
if (aa % p == 0) {
/* p is a prime factor of a */
if (b % p == 0) {
/* p is a common prime factor */
p2 = p;
if (p1 == 1) {
/* p is the smallest common prime factor */
p1 = p;
}
}
/* remove p as a factor of aa */
do { aa /= p; } while (aa % p == 0);
}
}
if (aa > 1) {
/* aa is the largest prime factor of a */
if (b % aa == 0) {
/* aa is the largest common prime factor */
p2 = aa;
if (p1 == 1) {
/* aa is also the smallest common prime factor */
p1 = aa;
}
}
}
/* print the product of the smallest and largest common prime factors */
/* if a == b and a is a large prime, a * a might overflow int */
printf("Case #%d: %lld\n", i, (long long)p1 * p2);
}
}
return 0;
}

Find the minimum number of steps to decrease N to zero

I'm facing some difficulties in the last few days while trying to finish the following task, I hope you guys can assist :
I'm given a single number N, and I'm allowed to perform any of the two operations on N in each move :
One - If we take 2 integers where N = x * y , then we can change the value of N to the maximum between x and y.
Two - Decrease the value of N by 1.
I want to find the minimum number of steps to reduce N to zero.
This is what I have so far, I'm not sure what is the best way to implement the function to find the divisor (someFindDevisorFunction), and if this 'f' function would actually produce the required output.
int f(int n)
{
int div,firstWay,secondWay;
if(n == 0)
return 0;
div = SomefindDivisorFunction(n);
firstWay = 1 + f(n-1);
if(div != 1)
{
secondWay = 1 + f(div);
if (firstWay < secondWay)
return firstWay;
return secondWay;
}
return firstWay;
}
For example, if I enter the number 150 , the output would be :
75 - 25 - 5 - 4 - 2 - 1 - 0
I see this a recursive or iterative problem.
OP's approach hints at recursive.
A recursive solution follows:
At each step, code counts the steps of the various alternatives:
steps(n) = min(
steps(factor1_of_n) + 1,
steps(factor2_of_n) + 1,
steps(factor3_of_n) + 1,
...
steps(n-1) + 1)
The coded solution below is inefficient, but it does explore all possibilities and gets to the answer.
int solve_helper(int n, bool print) {
int best_quot = 0;
int best_quot_score = INT_MAX;
int quot;
for (int p = 2; p <= (quot = n / p); p++) {
int rem = n % p;
if (rem == 0 && quot > 1) {
int score = solve_helper(quot, false) + 1;
if (score < best_quot_score) {
best_quot_score = score;
best_quot = quot;
}
}
}
int dec_score = n > 0 ? solve_helper(n - 1, false) + 1 : 0;
if (best_quot_score < dec_score) {
if (print) {
printf("/ %d ", best_quot);
solve_helper(best_quot, true);
}
return best_quot_score;
}
if (print && n > 0) {
printf("- %d ", n - 1);
solve_helper(n - 1, true);
}
return dec_score;
}
int main() {
int n = 75;
printf("%d ", n);
solve(n, true);
printf("\n");
}
Output
75 / 25 / 5 - 4 / 2 - 1 - 0
Iterative
TBD
If you start looking for a divisor with 2, and work your way up, then the last pair of divisors you find will include the largest divisor. Alternatively you can start searching with divisor = N/2 and work down, when the first divisor found will have be largest divisor of N.
int minmoves(int n){
if(n<=3){
return n;
}
int[] dp=new int[n+1];
Arrays.fill(dp,-1);
dp[0]=0;
dp[1]=1;
dp[2]=2;
dp[3]=3;
int sqr;
for(int i=4;i<=n;i++){
sqr=(int)Math.sqrt(i);
int best=Integer.MAX_VALUE;
while(sqr >1){
if(i%sqr==0){
int fact=i/sqr;
best=Math.min(best,1+dp[fact]);
}
sqr--;
}
best=Math.min(best,1+dp[i-1]);
dp[i]=best;
}
return dp[n];
}

Prime factorization of larger numbers than int

This program does Prime Factorization Of Numbers In C.
#include <stdio.h>
int main(void) {
int number, i, p, n, factors, count;
int numbers[1000000];
int counter = 0;
char text[100000];
for (count = 0; count < 1000000; count++) {
fgets(text, 10000000, stdin);
if (sscanf(text, "%d", &number) == 1) {
if (number == 0)
break;
numbers[count] = number;
} else {
numbers[count] = 0;
}
}
counter = 0;
for (i = 0; i < count; i++) {
if ((numbers[i] < 0) || (numbers[i] == 0)) {
fprintf(stderr, "Error: Wrong Input!\n");
return 100;
break;
}
number = numbers[i];
printf("Prime factorization of nubmer %d is:\n", number);
factors = 0;
for (p = 2; p * p <= number; p += 1 + (p & 1)) {
if (number % p == 0) {
n = 0;
factors++;
do {
number /= p;
n++;
} while (number % p == 0);
if (n == 1) {
printf("%d ", p);
++counter;
} else
printf("%d^%d ", p, n);
++counter;
if (count > 0 && number != 1)
printf("x ");
}
}
if (factors == 0 || number != 1)
printf("%d", number);
printf("\n");
}
return 0;
}
This program works fine for numbers smaller than 108. But my question is, if there is a way to make this program even for numbers like 1012. I know that int would not be enough, but when I tried for example long int, it didn't worked. Also I heard something about malloc, but I keep failing to implement (understand) it.
Factorising large numbers usually needs a more subtle approach than simple trial division. Here is a possible outline method:
Make a list of all the primes up to, say, 25,000.
Use the list to remove all prime factors below 25,000.
If there is a remainder > 1 then check if the remainder is prime with a Miller-Rabin test or similar.
If the remainder is prime, then you have found the last factor.
If the remainder is not prime, then you are going to have to factorise it. That will inevitably be slow I'm afraid.
You can use long long. But probably, the real problem is, that it will take a veeeeerrrryyy long time to do the factorization on numbers, that don't fit in a normal int. E.g. you're trying to factorize a prime number in the range 10^12, then you will have to do about 10^6 divisions.
The thing about malloc won't help you with this problem at all, because even bigger values will take even longer to factorize. So, if you want to know, how malloc works, I suggest opening a separate question for that.
Below is a rework of the code using unsigned long long. (I tossed the file stuff to keep this to a minimal example.) Whether this works for your purpose depends on how your system defines a long long (on my system it's 64 bits). I also redid the output format to be compatible with the Unix dc command's postfix notation so I could easily check if the results were correct:
#include <stdio.h>
#include <stdlib.h>
int main() {
unsigned long long large = 18446744073709551615ULL; // 2^64 - 1
for (unsigned long long counter = large - 1000; counter < large; counter++) {
unsigned long long number = counter;
printf("Prime factorization of %llu is:", number);
unsigned long factors = 0;
for (unsigned long long p = 2; p * p <= number; p += 1 + (p & 1)) {
if (number % p == 0) {
factors++;
unsigned long n = 0;
do {
number /= p;
n++;
} while (number % p == 0);
if (n == 1) {
printf(" %llu", p);
}
else {
printf(" %llu %lu ^", p, n);
}
if (number != 1 && factors > 1) {
printf(" *");
}
}
}
if (factors == 0 || number != 1) {
factors++;
printf(" %llu", number);
}
if (factors > 1) {
printf(" *");
}
printf("\n");
}
return 0;
}
SAMPLE OUTPUT
% ./a.out
Prime factorization of 18446744073709550615 is: 5 563 * 751 * 8725722280871 *
Prime factorization of 18446744073709550616 is: 2 3 ^ 3 * 41 * 7523 * 8243 * 14479 * 20879 *
Prime factorization of 18446744073709550617 is: 79 557 * 419215600611539 *
Prime factorization of 18446744073709550618 is: 2 2298974999 * 4011949691 *
Prime factorization of 18446744073709550619 is: 3 3 ^ 1008659 * 677347590683 *
Prime factorization of 18446744073709550620 is: 2 2 ^ 5 * 7 * 149 * 233 * 3795329598449 *
Prime factorization of 18446744073709550621 is: 11 23 * 72912031911895457 *
Prime factorization of 18446744073709550622 is: 2 3 * 479909 * 6406334004193 *
Prime factorization of 18446744073709550623 is: 3421377637 5391612979 *
Prime factorization of 18446744073709550624 is: 2 5 ^ 61 * 593 * 1699 * 9379762391 *
Prime factorization of 18446744073709550625 is: 3 5 4 ^ * 13 * 756789500459879 *
Prime factorization of 18446744073709550626 is: 2 3743461 * 2463862195133 *
Prime factorization of 18446744073709550627 is: 7 1283 * 4339 * 627089 * 754877 *
Prime factorization of 18446744073709550628 is: 2 2 ^ 3 2 ^ * 101 * 293 * 42751 * 405025111 *
Prime factorization of 18446744073709550629 is: 17 43 * 613 * 66457 * 619442699 *
...
This runs slower but reasonably. You can push this further on some systems by swapping unsigned long long for a uint128_t which some compilers support somewhat:
typedef unsigned __int128 uint128_t;
(And up the unsigned long declarations to unsigned long long.) You'd need to supply number printing routines for the uint128_t type as printf() isn't going to handle them directly. I tried this with the above code and it worked:
Prime factorization of 340282366920938463426481119284349108124 is: 2 2 ^ 31 * 6131 * 7654271 * 21163829 * 21491837 * 128562653437 *
% dc
2 2 ^ 31 * 6131 * 7654271 * 21163829 * 21491837 * 128562653437 * p
340282366920938463426481119284349108124
But I never saw it complete more than one number while running it!
Using type unsigned long long for number and the prime factors will take you to 1019 at the price of longer computation times.
Note however that defining a large local array with automatic storage may cause problems, especially when it reaches a size of 8 megabytes as would be the case for type unsigned long long (this type is at least 64-bit wide). Allocating it from the heap is safer.
Here is an adapted version of the code:
#include <stdio.h>
#include <stdlib.h>
#define NUMBER_MAX 1000000
int main(void) {
unsigned long long *numbers;
unsigned long long number, p;
int i, n, factors, count;
char text[100];
numbers = calloc(NUMBER_MAX, sizeof(*numbers));
if (numbers == NULL) {
printf("cannot allocate number array\n");
return 1;
}
for (count = 0; count < NUMBER_MAX; count++) {
if (!fgets(text, sizeof text, stdin)) {
break;
}
if (sscanf(text, "%llu", &number) == 1 && number > 0) {
numbers[count] = number;
} else {
fprintf(stderr, "Error: Wrong Input!\n");
return 100;
}
}
for (i = 0; i < count; i++) {
number = numbers[i];
printf("Prime factorization of nubmer %llu is:\n", number);
factors = 0;
for (p = 2; p < 0x100000000 && p * p <= number; p += 1 + (p & 1)) {
if (number % p == 0) {
n = 0;
factors++;
do {
number /= p;
n++;
} while (number % p == 0);
if (n == 1) {
printf("%llu ", p);
} else {
printf("%llu^%d ", p, n);
}
if (number != 1) {
printf("* ");
}
}
}
if (factors == 0 || number != 1) {
printf("%llu", number);
}
printf("\n");
}
free(numbers);
return 0;
}

Trailing zeroes in a Factorial

I am trying to write a code for calculating the number of trailing zeroes in a factorial of a specific number (large numbers). However, for small numbers, i get the correct result, but for large the deviations keeps increasing. What's wrong with my logic
#include <stdio.h>
int main(void) {
int t;
scanf("%d", &t);
while (t > 0) {
int factorten = 0, factorfive = 0, factortwo = 0, remainingfive = 0,
remainingtwo = 0;
unsigned int factors = 0;
unsigned int n;
scanf("%u", &n);
for (unsigned int i = n; i > 0; i--) {
if (i % 10 == 0) {
factorten++;
continue;
} else if (i % 5 == 0) {
factorfive++;
continue;
} else if (i % 2 == 0) {
// int new = i;
// while(new % 2 == 0)
//{
// new = new / 2;
factortwo++;
//}
continue;
}
}
factors = factors + factorten;
printf("%u\n", factors);
if (factorfive % 2 == 0 && factorfive != 0) {
factors = factors + (factorfive / 2);
} else {
remainingfive = factorfive % 2;
factors = factors + ((factorfive - remainingfive) / 2);
}
printf("%u\n", factors);
if (factortwo % 5 == 0 && factortwo != 0) {
factors = factors + (factortwo / 5);
} else {
remainingtwo = factortwo % 5;
factors = factors + ((factortwo - remainingtwo) / 5);
}
printf("%u\n", factors);
if ((remainingfive * remainingtwo % 10) == 0 &&
(remainingfive * remainingtwo % 10) != 0) {
factors++;
}
printf("%u\n", factors);
t--;
}
}
Sample Input:
6
3
60
100
1024
23456
8735373
Sample Output:
0
14
24
253
5861
2183837
My OUTPUT
0
13
23
235
5394
2009134
Edit: ignore the first two, they are suboptimal. The third algorithm is optimal.
I think this does what you're trying to do, but is a lot simpler and works:
int tzif(int n)
{
int f2 = 0, f5 = 0;
for (;n > 1; n--)
{
int x = n;
for (;x % 2 == 0; x /= 2)
f2++;
for (;x % 5 == 0; x /= 5)
f5++;
}
return f2 > f5 ? f5 : f2;
}
It counts 2-factors and 5-factors of numbers N...2. Then it returns the smaller of the two (because adding 2-factors is useless without adding 5-factors and vice-versa). Your code is too strange for me to analyze.
I think this should work too, because a factorial will have enough 2-factors to "cover" the 5-factors:
int tzif(int n)
{
int f5 = 0;
for (;n > 1; n--)
for (x = n;x % 5 == 0; x /= 5)
f5++;
return f5;
}
This only counts 5-factors and returns that.
Another method I think should work:
int tzif(int n)
{
int f5 = 0;
for (int d = 5; d <= n; d *= 5)
f5 += n / d;
return f5;
}
Count every fifth number (each has a 5-factor), then every 25-th number (each has another 5-factor), etc.
Have 3 counters - c2,c5,c10.
I think the checks should be
divisible by 5 but not by 10 -> c5++
divisible by 2 but not by 10 -> c2++
divisible by 10. Here if true, then count number of 0's. (c10++)
At last number of 0's will be
smaller_of(c2,c5) + c10
Try to code using this. Should work.
First the trailing 0 in N! are determined by factors 2 and 5 (10). The factors 2 always would be more that the factors 5 in this case you only need to calculate how factors 5 are in the N!.
(N!/5) would give you the number of multiple of 5 (5^1) in N!
(N!/25) would give you the number of multiple of 25 (5^2) in N!
(N!/125) would give you the number of multiple of 125 (5^3) in N!
...
(N!/5^n) would give you the number of multiple of 5^n in N!
When you add the multiple of 5 you are adding too the multiple of 25, 125, ..., 5^n, when you add multiple of 25 you are adding too the multiple of 125, ..., 5^n, etc...
In that case you only need to iterate the power of 5 less or equal than N and add the number of multiple of that 5 power.
Code:
long long trailing_zeros(long long N) {
long long zeros = 0;
for (long long power5 = 5; power5 <= N; power5 *= 5)
zeros += N / power5;
return zeros;
}
#include<iostream>
int main()
{
int size,i;
std::cin >> size;
int*fact;
fact = new int[size];
for (i = 0; i < size; i++)
{
std::cin >> fact[size];
}
for (i = 0; i < size; i++)
{
int con = 5;
int multiple = 0;
do
{
multiple = multiple+(fact[size] / con);
con = con * 5;
} while (con < fact[size]);
std::cout << multiple <<'\n';
}
return 0;
}
this code works perfectly for a single input..bt for multiple inputs it prints the o/p for the last entered number...what is wrong..i jst cant think off it

Finding largest prime factor of a composite number in c

I am accepting a composite number as an input. I want to print all its factors and also the largest prime factor of that number. I have written the following code. It is working perfectly ok till the number 51. But if any number greater than 51 is inputted, wrong output is shown. how can I correct my code?
#include<stdio.h>
void main()
{
int i, j, b=2, c;
printf("\nEnter a composite number: ");
scanf("%d", &c);
printf("Factors: ");
for(i=1; i<=c/2; i++)
{
if(c%i==0)
{
printf("%d ", i);
for(j=1; j<=i; j++)
{
if(i%j > 0)
{
b = i;
}
if(b%3==0)
b = 3;
else if(b%2==0)
b = 2;
else if(b%5==0)
b = 5;
}
}
}
printf("%d\nLargest prime factor: %d\n", c, b);
}
This is a bit of a spoiler, so if you want to solve this yourself, don't read this yet :). I'll try to provide hints in order of succession, so you can read each hint in order, and if you need more hints, move to the next hint, etc.
Hint #1:
If divisor is a divisor of n, then n / divisor is also a divisor of n. For example, 100 / 2 = 50 with remainder 0, so 2 is a divisor of 100. But this also means that 50 is a divisor of 100.
Hint #2
Given Hint #1, what this means is that we can loop from i = 2 to i*i <= n when checking for prime factors. For example, if we are checking the number 100, then we only have to loop to 10 (10*10 is <= 100) because by using hint #1, we will get all the factors. That is:
100 / 2 = 50, so 2 and 50 are factors
100 / 5 = 20, so 5 and 20 are factors
100 / 10 = 10, so 10 is a factor
Hint #3
Since we only care about prime factors for n, it's sufficient to just find the first factor of n, call it divisor, and then we can recursively find the other factors for n / divisor. We can use a sieve approach and mark off the factors as we find them.
Hint #4
Sample solution in C:
bool factors[100000];
void getprimefactors(int n) {
// 0 and 1 are not prime
if (n == 0 || n == 1) return;
// find smallest number >= 2 that is a divisor of n (it will be a prime number)
int divisor = 0;
for(int i = 2; i*i <= n; ++i) {
if (n % i == 0) {
divisor = i;
break;
}
}
if (divisor == 0) {
// we didn't find a divisor, so n is prime
factors[n] = true;
return;
}
// we found a divisor
factors[divisor] = true;
getprimefactors(n / divisor);
}
int main() {
memset(factors,false,sizeof factors);
int f = 1234;
getprimefactors(f);
int largest;
printf("prime factors for %d:\n",f);
for(int i = 2; i <= f/2; ++i) {
if (factors[i]) {
printf("%d\n",i);
largest = i;
}
}
printf("largest prime factor is %d\n",largest);
return 0;
}
Output:
---------- Capture Output ----------
> "c:\windows\system32\cmd.exe" /c c:\temp\temp.exe
prime factors for 1234:
2
617
largest prime factor is 617
> Terminated with exit code 0.
I presume you're doing this to learn, so I hope you don't mind a hint.
I'd start by stepping through your algorithm on a number that fails. Does this show you where the error is?
You need to recode so that your code finds all the prime numbers of a given number, instead of just calculating for the prime numbers 2,3, and 5. In other words, your code can only work with the number you are calculating is a prime number or is a multiple of 2, 3, or 5. But 7, 11, 13, 17, 19 are also prime numbers--so your code should simply work by finding all factors of a particular number and return the largest factor that is not further divisible.
Really, this is very slow for all but the smallest numbers (below, say, 100,000). Try finding just the prime factors of the number:
#include <cmath>
void addfactor(int n) {
printf ("%d\n", n);
}
int main()
{
int d;
int s;
int c = 1234567;
while (!(c&1)) {
addfactor(2);
c >>= 1;
}
while (c%3 == 0) {
addfactor(3);
c /= 3;
}
s = (int)sqrt(c + 0.5);
for (d = 5; d <= s;) {
while (c % d == 0) {
addfactor(d);
c /= d;
s = (int)sqrt(c + 0.5);
}
d += 2;
while (c % d == 0) {
addfactor(d);
c /= d;
s = (int)sqrt(c + 0.5);
}
d += 4;
}
if (c > 1)
addfactor(c);
return 0;
}
where addfactor is some kind of macro that adds the factor to a list of prime factors. Once you have these, you can construct a list of all the factors of the number.
This is dramatically faster than the other code snippets posted here. For a random input like 10597959011, my code would take something like 2000 bit operations plus 1000 more to re-constitute the divisors, while the others would take billions of operations. It's the difference between 'instant' and a minute in that case.
Simplification to dcp's answer(in an iterative way):
#include <stdio.h>
void factorize_and_print(unsigned long number) {
unsigned long factor;
for(factor = 2; number > 1; factor++) {
while(number % factor == 0) {
number = number / factor;
printf("%lu\n",factor);
}
}
}
/* example main */
int main(int argc,char** argv) {
if(argc >= 2) {
long number = atol(argv[1]);
factorize_and_print(number);
} else {
printf("Usage: %s <number>%<number> is unsigned long", argv[0]);
}
}
Note: There is a number parsing bug here that is not getting the number in argv correctly.

Resources