Related
I'm trying to write a program that prints all possible combinations of three digits.
And there is the constraint that:
The three digits must be different
012, 120, 102, 021, 201, and 210 are considered the same combination of the three digits 0, 1 and 2
Print only the smallest combination of three digits
The expected output is as follows
012, 013, 014, 015, 016, 017, 018, 019, 023, 024, 025, 026, 027, 028, 029, 034, 035, 036, 037, 038, 039, 045, 046, 047, 048, 049, 056, 057, 058, 059, 067, 068, 069, 078, 079, 089, 123, 124, 125, 126, 127, 128, 129, 134, 135, 136, 137, 138, 139, 145, 146, 147, 148, 149, 156, 157, 158, 159, 167, 168, 169, 178, 179, 189, 234, 235, 236, 237, 238, 239, 245, 246, 247, 248, 249, 256, 257, 258, 259, 267, 268, 269, 278, 279, 289, 345, 346, 347, 348, 349, 356, 357, 358, 359, 367, 368, 369, 378, 379, 389, 456, 457, 458, 459, 467, 468, 469, 478, 479, 489, 567, 568, 569, 578, 579, 589, 678, 679, 689, 789
I'm trying to implement in C but the algorithm or any language implementation will suffice.
Here is what I've done so far but it's inacurrate.
#include <stdio.h>
/**
* main - entry point
*
* Description: display triple digits and ,
*
* Return: Always 0 (successful)
*/
int main(void)
{
int i, j, k, l;
i = 0;
while (i < 1000)
{
j = i / 100; /* hundreds */
k = (i / 10) % 10; /* tens */
l = i % 100; /* units */
if (j < k && k < l)
{
putchar(l + '0');
putchar(k + '0');
putchar(j + '0');
if (i < 789)
{
putchar(',');
putchar(' ');
}
}
i++;
}
putchar('\n');
return (0);
}
Here is a fairly compact snippet of code for giving the smallest unique three-digit number.
#include <stdio.h>
int main()
{
char digit[4];
for (int i = 0; i < 8; i++)
{
for (int j = i + 1; j < 9; j++)
{
for (int k = j + 1; k < 10; k++)
{
digit[0] = i + '0';
digit[1] = j + '0';
digit[2] = k + '0';
digit[3] = '\0';
printf("%s\n", digit);
}
}
}
return 0;
}
You can give that a try.
You can do:
#include <stdio.h>
int main (void) {
char h = '0', t = '1', u = '2';
while ((h <= '7') || (t <= '8') || (u <= '9')) {
printf ("%c%c%c, ", h, t, u);
u != '9' ? ++u : (t != '8' ? (++t, u = t + 1) : (++h, t = h + 1, u = t + 1));
}
return 0;
}
Output:
012, 013, 014, 015, 016, 017, 018, 019, 023, 024, 025, 026, 027, 028, 029, 034,
035, 036, 037, 038, 039, 045, 046, 047, 048, 049, 056, 057, 058, 059, 067, 068,
069, 078, 079, 089, 123, 124, 125, 126, 127, 128, 129, 134, 135, 136, 137, 138,
139, 145, 146, 147, 148, 149, 156, 157, 158, 159, 167, 168, 169, 178, 179, 189,
234, 235, 236, 237, 238, 239, 245, 246, 247, 248, 249, 256, 257, 258, 259, 267,
268, 269, 278, 279, 289, 345, 346, 347, 348, 349, 356, 357, 358, 359, 367, 368,
369, 378, 379, 389, 456, 457, 458, 459, 467, 468, 469, 478, 479, 489, 567, 568,
569, 578, 579, 589, 678, 679, 689, 789,
Explanation:
In the program - h, t and u represents digit at hundredth location, digit at tenth location and digit at unit location respectively in a three digit number.
Initialised h with '0', t with '1' and u with '2' because 012 is the smallest three digit number without any of the digits being repeated.
while loop condition ((h <= '7') || (t <= '8') || (u <= '9')) because 789 is biggest three digit number which follow constraint of - smallest combination of three digits without any of the digits being repeated. Any other combination of 7, 8 and 9 will be bigger than 789 and any three digit number bigger than 789 will violat one of the given constraints.
If you find it difficult to understand the expression with ternary operation
u != '9' ? ++u : (t != '8' ? (++t, u = t + 1) : (++h, t = h + 1, u = t + 1));
then here is simplified version using if else :
if (u != '9') {
++u;
} else {
if (t != '8') {
++t;
u = t + 1; // due to given constraint, u will always greater than t
} else {
++h;
t = h + 1; // due to given constraint, t will always greater than h
u = t + 1; // due to given constraint, u will always greater than t
}
}
Here's some annotated code that might improve the outcome.
char *sep = ""; // the separator to use. Put this line ahead of the loop
and
// meaningful names mean no comment required
// EDIT: thank you, #Chux
int unit = i % 10;
int tens = i / 10 % 10;
int hund = i /100 % 10;
if ( unit < tens && tens < hund )
printf( "%s%c%c%c", sep, hund + '0', tens + '0', unit + '0' ), sep = ", ";
Notice that 'j', 'k' and 'l' have no meaning to this problem. Easy to putchar() the numbers in reverse order without noticing...
Of course, if this is not a homework assignment (Prof wouldn't believe you wrote this)...
#include <stdio.h>
int main() {
char *sep = "", *dgts = "0123456789";
for( int h = 0; dgts[h]; h++ )
for( int t = h+1; dgts[t]; t++ )
for( int u = t+1; dgts[u]; u++ )
printf( "%s%c%c%c", sep, dgts[h], dgts[t], dgts[u] ), sep = ", ";
putchar( '\n' );
return 0;
}
And, to use the equivalence of array addressing and pointers.
#include <stdio.h>
int main() {
char *h, *t, *u, *sep = "";
for( h = "0123456789"; *h; h++ )
for( t = h+1; *t; t++ )
for( u = t+1; *u; u++ )
printf( "%s%c%c%c", sep, *h, *t, *u), sep = ", ";
putchar( '\n' );
return 0;
}
Inspired by comment by #Chux, here is the same thing expanded to printing 4 digits. Comparison will show the few trivial alterations needed.
#include <stdio.h>
int main() {
char *m, *h, *t, *u, *sep = "";
for( m = "0123456789"; *m; m++ )
for( h = m+1; *h; h++ )
for( t = h+1; *t; t++ )
for( u = t+1; *u; u++ )
printf( "%s%c%c%c%c", sep, *m, *h, *t, *u), sep = ", ";
putchar( '\n' );
return 0;
}
Here is how I went about my solution:
int main(void)
{
int a, b, c;
for (a = 0; a < 8; a++)
{
for (b = a + 1; b < 9; b++)
{
for (c = b + 1; c < 10; c++)
{
if (a != b && a != c && b != c)
{
putchar(a + '0');
putchar(b + '0');
putchar(c + '0');
if (a + b + c < 24)
{
putchar(',');
putchar(' ');
}
}
}
}
}
putchar('\n');
return (0);
}
The variables in order of a, b, & c; a for 1st digit, b for 2nd and c for 3rd.
The use of b = a + 1 & c = b + 1 was an idea given to me by user #chux - Reinstate Monica in another post that linked me to this one that involved two integers instead of 3 (For two digits, the code only needs to be slightly tweaked to cater for 2 integers).
Moving on.
The if statements:
if (a != b && a != c && b != c)
and
if (a + b + c < 24)
will filter out the duplicates and ensure that the comma and space are not applied to the last combo of integers respectively (i.e. 789, which sum up to give 24).
I'm trying to write a program that prints all possible combinations of three digits.
And there is the constraint that:
The three digits must be different
012, 120, 102, 021, 201, and 210 are considered the same combination of the three digits 0, 1 and 2
Print only the smallest combination of three digits
The expected output is as follows
012, 013, 014, 015, 016, 017, 018, 019, 023, 024, 025, 026, 027, 028, 029, 034, 035, 036, 037, 038, 039, 045, 046, 047, 048, 049, 056, 057, 058, 059, 067, 068, 069, 078, 079, 089, 123, 124, 125, 126, 127, 128, 129, 134, 135, 136, 137, 138, 139, 145, 146, 147, 148, 149, 156, 157, 158, 159, 167, 168, 169, 178, 179, 189, 234, 235, 236, 237, 238, 239, 245, 246, 247, 248, 249, 256, 257, 258, 259, 267, 268, 269, 278, 279, 289, 345, 346, 347, 348, 349, 356, 357, 358, 359, 367, 368, 369, 378, 379, 389, 456, 457, 458, 459, 467, 468, 469, 478, 479, 489, 567, 568, 569, 578, 579, 589, 678, 679, 689, 789
I'm trying to implement in C but the algorithm or any language implementation will suffice.
Here is what I've done so far but it's inacurrate.
#include <stdio.h>
/**
* main - entry point
*
* Description: display triple digits and ,
*
* Return: Always 0 (successful)
*/
int main(void)
{
int i, j, k, l;
i = 0;
while (i < 1000)
{
j = i / 100; /* hundreds */
k = (i / 10) % 10; /* tens */
l = i % 100; /* units */
if (j < k && k < l)
{
putchar(l + '0');
putchar(k + '0');
putchar(j + '0');
if (i < 789)
{
putchar(',');
putchar(' ');
}
}
i++;
}
putchar('\n');
return (0);
}
Here is a fairly compact snippet of code for giving the smallest unique three-digit number.
#include <stdio.h>
int main()
{
char digit[4];
for (int i = 0; i < 8; i++)
{
for (int j = i + 1; j < 9; j++)
{
for (int k = j + 1; k < 10; k++)
{
digit[0] = i + '0';
digit[1] = j + '0';
digit[2] = k + '0';
digit[3] = '\0';
printf("%s\n", digit);
}
}
}
return 0;
}
You can give that a try.
You can do:
#include <stdio.h>
int main (void) {
char h = '0', t = '1', u = '2';
while ((h <= '7') || (t <= '8') || (u <= '9')) {
printf ("%c%c%c, ", h, t, u);
u != '9' ? ++u : (t != '8' ? (++t, u = t + 1) : (++h, t = h + 1, u = t + 1));
}
return 0;
}
Output:
012, 013, 014, 015, 016, 017, 018, 019, 023, 024, 025, 026, 027, 028, 029, 034,
035, 036, 037, 038, 039, 045, 046, 047, 048, 049, 056, 057, 058, 059, 067, 068,
069, 078, 079, 089, 123, 124, 125, 126, 127, 128, 129, 134, 135, 136, 137, 138,
139, 145, 146, 147, 148, 149, 156, 157, 158, 159, 167, 168, 169, 178, 179, 189,
234, 235, 236, 237, 238, 239, 245, 246, 247, 248, 249, 256, 257, 258, 259, 267,
268, 269, 278, 279, 289, 345, 346, 347, 348, 349, 356, 357, 358, 359, 367, 368,
369, 378, 379, 389, 456, 457, 458, 459, 467, 468, 469, 478, 479, 489, 567, 568,
569, 578, 579, 589, 678, 679, 689, 789,
Explanation:
In the program - h, t and u represents digit at hundredth location, digit at tenth location and digit at unit location respectively in a three digit number.
Initialised h with '0', t with '1' and u with '2' because 012 is the smallest three digit number without any of the digits being repeated.
while loop condition ((h <= '7') || (t <= '8') || (u <= '9')) because 789 is biggest three digit number which follow constraint of - smallest combination of three digits without any of the digits being repeated. Any other combination of 7, 8 and 9 will be bigger than 789 and any three digit number bigger than 789 will violat one of the given constraints.
If you find it difficult to understand the expression with ternary operation
u != '9' ? ++u : (t != '8' ? (++t, u = t + 1) : (++h, t = h + 1, u = t + 1));
then here is simplified version using if else :
if (u != '9') {
++u;
} else {
if (t != '8') {
++t;
u = t + 1; // due to given constraint, u will always greater than t
} else {
++h;
t = h + 1; // due to given constraint, t will always greater than h
u = t + 1; // due to given constraint, u will always greater than t
}
}
Here's some annotated code that might improve the outcome.
char *sep = ""; // the separator to use. Put this line ahead of the loop
and
// meaningful names mean no comment required
// EDIT: thank you, #Chux
int unit = i % 10;
int tens = i / 10 % 10;
int hund = i /100 % 10;
if ( unit < tens && tens < hund )
printf( "%s%c%c%c", sep, hund + '0', tens + '0', unit + '0' ), sep = ", ";
Notice that 'j', 'k' and 'l' have no meaning to this problem. Easy to putchar() the numbers in reverse order without noticing...
Of course, if this is not a homework assignment (Prof wouldn't believe you wrote this)...
#include <stdio.h>
int main() {
char *sep = "", *dgts = "0123456789";
for( int h = 0; dgts[h]; h++ )
for( int t = h+1; dgts[t]; t++ )
for( int u = t+1; dgts[u]; u++ )
printf( "%s%c%c%c", sep, dgts[h], dgts[t], dgts[u] ), sep = ", ";
putchar( '\n' );
return 0;
}
And, to use the equivalence of array addressing and pointers.
#include <stdio.h>
int main() {
char *h, *t, *u, *sep = "";
for( h = "0123456789"; *h; h++ )
for( t = h+1; *t; t++ )
for( u = t+1; *u; u++ )
printf( "%s%c%c%c", sep, *h, *t, *u), sep = ", ";
putchar( '\n' );
return 0;
}
Inspired by comment by #Chux, here is the same thing expanded to printing 4 digits. Comparison will show the few trivial alterations needed.
#include <stdio.h>
int main() {
char *m, *h, *t, *u, *sep = "";
for( m = "0123456789"; *m; m++ )
for( h = m+1; *h; h++ )
for( t = h+1; *t; t++ )
for( u = t+1; *u; u++ )
printf( "%s%c%c%c%c", sep, *m, *h, *t, *u), sep = ", ";
putchar( '\n' );
return 0;
}
Here is how I went about my solution:
int main(void)
{
int a, b, c;
for (a = 0; a < 8; a++)
{
for (b = a + 1; b < 9; b++)
{
for (c = b + 1; c < 10; c++)
{
if (a != b && a != c && b != c)
{
putchar(a + '0');
putchar(b + '0');
putchar(c + '0');
if (a + b + c < 24)
{
putchar(',');
putchar(' ');
}
}
}
}
}
putchar('\n');
return (0);
}
The variables in order of a, b, & c; a for 1st digit, b for 2nd and c for 3rd.
The use of b = a + 1 & c = b + 1 was an idea given to me by user #chux - Reinstate Monica in another post that linked me to this one that involved two integers instead of 3 (For two digits, the code only needs to be slightly tweaked to cater for 2 integers).
Moving on.
The if statements:
if (a != b && a != c && b != c)
and
if (a + b + c < 24)
will filter out the duplicates and ensure that the comma and space are not applied to the last combo of integers respectively (i.e. 789, which sum up to give 24).
I'm trying to find the first prime number after n, unless entered n is already prime (then the program prints out n and terminates).
Example input:
n = 7
The first prime number is: 7 (Good)
n = 591
The first prime number is: 591 (Not right, 591 is not a prime number)
n = 14
The first prime number is: 15 (This is also false, shouldn't it be 17?)
Where am I making a mistake? It might be an obvious one, but I'm just starting out.
#include <stdio.h>
int main(){
int i = 2, n, m;
printf("n = ");
do
scanf("%d", &n);
while (n < 2);
m = n / 2;
if (n == 2){
printf("The first prime number is: %d", n);
return 0;
}
while ( i <= m ){
if (n % i == 0)
n++;
if (n % i != 0){
printf("The first prime number is: %d", n);
return 0;
} else i++;
}
return 0;
}
Your logic for determining a prime number is wrong.
First of all you should write a function ( not necessarily but it is recommended ) to check whether one number is prime. Here's the code for this function:
int checkPrimeNumber(int n)
{
int j, flag = 1;
for(j=2; j <= n/2; ++j)
{
if (n%j == 0)
{
flag =0;
break;
}
}
return flag;
}
Once you include the function your while loop should loop until if finds the first prime number starting from N using that function. Below is a code for that function.
You can also check this answer here:
https://codereview.stackexchange.com/questions/71212/find-smallest-prime-number-greater-than-given-n
The following two pieces of logic should solve your problem.
int IsPrime(int n)
{
int i;
for( i=2; i <= n/i; i++)
if( n%i == 0 ) return 0;
return 1;
}
This function determines reasonably quickly whether the integer passed in is prime. It stops testing once it has passed the square root of the test integer.
int FirstPrime(int n)
{
while( !IsPrime(n) )
n++;
return n;
}
This function contains the basic logic set out in your problem statement: return the input value, if prime, or failing that the first integer after that value that is prime.
Breaking the code into separate functions makes it much easier to test and to reason about the code.
Checking primality
This is the simpler code that I use for detecting primes:
int isprime(unsigned number)
{
if (number <= 1)
return 0;
if (number == 2 || number == 3)
return 1;
if (number % 2 == 0 || number % 3 == 0)
return 0;
for (unsigned x = 5; x * x <= number; x += 6)
{
if (number % x == 0 || number % (x + 2) == 0)
return 0;
}
return 1;
}
It exploits the fact that all prime numbers larger than 3 have the form 6N±1. It's easy to see why. All the numbers of the forms 6N+0, 6N+2, 6N+4 are clearly divisible by 2 and the numbers of the form 6N+3 are clearly divisible by 3, which leaves only 6N+1 and 6N+5 as possibly prime — and 6N+5 is equivalent to 6(N+1)-1, so the formula 6N±1 covers them properly. For N = 1, 6N±1 yields 5 and 7 which are prime; N = 2 yields 11 and 13 which are prime; N = 3 yields 17 and 19 which are prime; N = 4 yields 23 and 25, of which 23 is prime and 25 is not. All primes bigger than 3 are of the form 6N±1; not all numbers of the form 6N±1 are prime. All this means that the code only checks two divisors out of every six as it steps through the range up to the square root of the number.
I have a more complex variant which knows the primes up to 100, and then goes stepping every 6:
int isprime(unsigned number)
{
if (number <= 1)
return 0;
if (number == 2 || number == 3)
return 1;
if (number % 2 == 0 || number % 3 == 0)
return 0;
static const unsigned int small_primes[] =
{
5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47,
53, 59, 61, 67, 71, 73, 79, 83, 87, 89, 91, 97
};
enum { NUM_SMALL_PRIMES = sizeof(small_primes) / sizeof(small_primes[0]) };
for (unsigned i = 0; i < NUM_SMALL_PRIMES; i++)
{
if (number == small_primes[i])
return 1;
if (number % small_primes[i] == 0)
return 0;
}
for (unsigned i = 101; i * i <= number; i += 6)
{
if (number % i == 0 || number % (i + 2) == 0)
return 0;
}
return 1;
}
This is usually marginally faster than the other, but only by a very small amount.
Next prime after
I originally wrote this code for another SO question that was deleted before I posted an answer; it uses another variant of isprime() with a table of primes up to 1013.
/* Inspired by the deleted question SO 5308-6674 */
/* Determine the next prime after a given number */
#include <assert.h>
#include <stdio.h>
#include <limits.h>
#include <stdbool.h>
#define NEXT_PRIME_AFTER /* Avoid unnecessary checks in is_prime() */
#ifdef TEST
static unsigned primes[] = { 2, 3, 5, 7, 11 };
#else
static unsigned primes[] =
{
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013,
};
#endif /* TEST */
enum { N_PRIMES = sizeof(primes) / sizeof(primes[0]) };
/*
** In the context of next_prime_after(), this function is never called
** upon to validate small numbers - numbers less than primes[N_PRIMES-1]
** are not passed here. In more general contexts, the extra conditions
** in the conditionally compiled code are necessary for accuracy.
*/
static bool is_prime(unsigned p)
{
for (int i = 0; i < N_PRIMES; i++)
{
#ifndef NEXT_PRIME_AFTER
if (p < primes[i])
return false;
if (p == primes[i])
return true;
#endif /* NEXT_PRIME_AFTER */
if (p % primes[i] == 0)
return false;
}
for (unsigned t = primes[N_PRIMES - 1]; t * t <= p; t += 6)
{
if (p % t == 0)
return false;
if (p % (t + 2) == 0)
return false;
}
return true;
}
static unsigned next_prime_after(unsigned start)
{
for (int i = 0; i < N_PRIMES; i++)
{
if (start < primes[i])
return primes[i];
}
for (unsigned x = (start + 1) / 6; x < UINT_MAX / 6; x++)
{
unsigned t = 6 * x - 1;
if (t > start && is_prime(t))
return(t);
t += 2;
if (t > start && is_prime(t))
return(t);
}
return 0;
}
int main(void)
{
assert((primes[N_PRIMES-1]+1) % 6 == 0);
for (unsigned u = 0; u < 100; u++)
printf("%3u => %3u\n", u, next_prime_after(u));
for (unsigned t = 100, u = next_prime_after(t); u < 12345678; t = u)
printf("%3u => %3u\n", t, (u = next_prime_after(t)));
}
Be wary of the isprime() function here. It is tailored to this context and omits checks that would be necessary with a general purpose, standalone prime tester. The next_prime_after() steps through the list of known primes (if you're likely to be dealing with many big possible primes, you might add a test to see whether it is worth stepping through the first loop at all), and then steps through the 6N±1 sequence looking for a prime.
The test code prints the next prime after each number from 0 to 99. Thereafter, it steps through the primes up to 12345701 (which is the first prime after 12345678).
0 => 2
1 => 2
2 => 3
3 => 5
4 => 5
5 => 7
6 => 7
7 => 11
8 => 11
9 => 11
10 => 11
11 => 13
12 => 13
13 => 17
14 => 17
15 => 17
16 => 17
17 => 19
18 => 19
19 => 23
20 => 23
21 => 23
22 => 23
23 => 29
…
95 => 97
96 => 97
97 => 101
98 => 101
99 => 101
100 => 101
101 => 103
103 => 107
107 => 109
109 => 113
113 => 127
127 => 131
…
12345581 => 12345623
12345623 => 12345637
12345637 => 12345643
12345643 => 12345647
12345647 => 12345653
12345653 => 12345701
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
I have to generate the set Z of the first 100 integers that satisfy the equation i = 2^a * 3^b, with a and b being integers.
That is, Z = {1, 2, 3, 4, 6, 8, 9, 12, ...}
What algorithm could I use ? I'll need to implement it in C.
In C
#include <stdio.h>
#include <math.h>
#include <stdint.h>
typedef unsigned long long int ull;
ull cmp(const void * a, const void * b) { return *(ull *)a - *(ull *)b; }
int main() {
int i = 0, a, b;
int A = 17,
B = 16;
int MAX = A * B;
ull z[MAX];
for (b = 0; b < B; ++b) {
for (a = 0; a < A; ++a) {
if (i >= MAX) break;
z[i++] = pow(2, a) * pow(3, b);
}
}
qsort(z, MAX, sizeof(ull), cmp);
printf("{ ");
for (i = 0; i < 100; ++i)
printf("%lld%c ", z[i], i < 99 ? ',' : 0);
printf("}");
return 0;
}
Output
{ 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 54, 64, 72, 81, 96, 108, 128, 144, 162, 192, 216, 243, 256, 288, 324, 384, 432, 486, 512, 576, 648, 729, 768, 864, 972, 1024, 1152, 1296, 1458, 1536, 1728, 1944, 2048, 2187, 2304, 2592, 2916, 3072, 3456, 3888, 4096, 4374, 4608, 5184, 5832, 6144, 6561, 6912, 7776, 8192, 8748, 9216, 10368, 11664, 12288, 13122, 13824, 15552, 16384, 17496, 18432, 19683, 20736, 23328, 24576, 26244, 27648, 31104, 32768, 34992, 36864, 39366, 41472, 46656, 49152, 52488, 55296, 59049, 62208, 65536, 69984, 73728, 78732, 82944, 93312 }
EDIT: Gives correct output now without overflow (see http://ideone.com/Rpbqms)
too much brute force...
let me propose a O(n*lg n) time O(n) space algorithm to achieve these.
i am not gonna provide any real code, but a piece of self invented pseudocode.
the idea is to use min-heap to maintain ordering:
func first-n-of-that(limit)
heap = min-heap()
heap.insert 1
results = []
while results.length < limit
to-add = heap.pop
results.add to-add
heap.insert 2 * to-add
heap.insert 3 * to-add
return results
the correctness is provable by deduction.
Brute force in Python (I know that C code is required):
sorted(2**a*3**b for a in range(100) for b in range(100))[:100]
And the result is …
I have solved a question that says:
Given a natural number n (1 <= n <= 500000), please output the summation of all its proper divisors.
Definition: A proper divisor of a natural number is the divisor that is strictly less than the number.
e.g. number 20 has 5 proper divisors: 1, 2, 4, 5, 10, and the divisor summation is: 1 + 2 + 4 + 5 + 10 = 22.
Input
An integer stating the number of test cases (equal to about 200000), and that many lines follow, each containing one integer between 1 and 500000 inclusive.
Output
One integer each line: the divisor summation of the integer given respectively.
Example
Sample Input:
3
2
10
20
Sample Output:
1
8
22
My code is as follows:
/* #BEGIN_OF_SOURCE_CODE */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[])
{
int sum = 0,
cases = 0,
i, j, buff;
scanf("%d", &cases); //Number of tests
int *n;
n = (int*) malloc(cases * sizeof(int)); //Defining array for numbers to be tested///////
for (i = 0; i < cases; i++) {
scanf("%d", &n[i]);
}
for (i = 0; i < cases; i++ ) {
buff = n[i] / 2;
if (n[i] == 1) {
sum = -1;
}
if (!(n[i] & 1)) {
for (j = 2; j < buff; j++) {
if (n[i] % j == 0) {
sum += n[i] / j + j;
buff /= j;
}
}
}
else {
for (j = 3; j < buff; j += 2) {
if (n[i] % j == 0) {
if (n[i] / j == j) { sum += j; break; }
else sum += n[i] / j + j;
}
buff /= j;
}
}
printf("%d\n", ++sum);
sum = 0;
}
return 0;
}
/* #END_OF_SOURCE_CODE */
but it is not fast enough. Any suggestions?
I have updated the code below to terminate sooner. Running it for all integers from 1 to 500,000 takes under half a second on a MacBookPro6,1 (2.66 GHz Intel Core i7), compiled with Apple GCC 4.2.1 with -O3.
It uses the formula for σx(n) in the Properties section of the Wikipedia page for the divisor function. It could be made faster with a list of precalculated primes. (126 are needed to support inputs up to 500,000, and this reduces the time to less than a quarter of a second.) There are also some divisions that can be eliminated, at the expense of cluttering the code slightly.
// Return the least power of a that does not divide x.
static unsigned int LeastPower(unsigned int a, unsigned int x)
{
unsigned int b = a;
while (x % b == 0)
b *= a;
return b;
}
// Return the sum of the proper divisors of x.
static unsigned int SumDivisors(unsigned int x)
{
unsigned int t = x;
unsigned int result = 1;
// Handle two specially.
{
unsigned int p = LeastPower(2, t);
result *= p-1;
t /= p/2;
}
// Handle odd factors.
for (unsigned int i = 3; i*i <= t; i += 2)
{
unsigned int p = LeastPower(i, t);
result *= (p-1) / (i-1);
t /= p/i;
}
// At this point, t must be one or prime.
if (1 < t)
result *= 1+t;
return result - x;
}
You don't have to allocate space. Just do line by line.
For each line, there is an O( n ^ 1/2 ) algorithm.
#include <iostream>
using std::cout; using std::endl; using std::cin;
int main() {
int count, number;
cin >> count;
for (int i = 0; i < count; ++i) {
cin >> number;
int sum = 1;
for ( int j = 2; j * j <= number; ++j ) {
if ( number % j == 0 ) {
sum += j;
sum += number / j;
}
if ( j * j == number ) sum -= j; // recalculate twice
}
cout << sum << endl;
}
}
This is the runtime for 200,000 test case
real 0m55.420s
user 0m0.016s
sys 0m16.124s
I would start by NOT storing the numbers in an array at all. You don't need to - just read the value, process it, and output the result. The compiler may well not realize that n[i] is the same value throughout the loop, and that nothing else modifies it.
The logic doesn't seem very clear to me. And if (n[i] == 1) { sum = 1} else ... would make more sense than setting sum = -1.
You could perhaps also, keep a list of "common factors" (http://en.wikipedia.org/wiki/Memoization), so that you don't have to recalculate the same thing many times over. [If you know that somehing has the factor 24, then it also has 2, 3, 4, 6 and 8, for example.
I replied to a similar question on stackoverflow
There is a faster performing algorithm which is based on a formula for the sum of divisor using the decomposition in prime factors.
First you construct a primetable such that the last prime squared is smaller than the upper bound for your number. Then you apply the formula to each entry. If a number is written as
n = a1^p1 * a1^p2 *... *an^pn
the complexity of finding the sum for a given number n will be
p1+p2+...+pn = roughtly log(n)
which is better than the complexity O(sqrt(n)) of the first optimization which stop the loop early
Let's suppose you have a way to compute primes relatively quickly. This could be a one time upfront activity, bounded by the square root of the largest input value. In this case, you already know the bound of the largest input value (500000), so you can simply hard code a table of primes into the program.
static unsigned P[] = {
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233,
239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419,
421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607,
613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701
};
static int P_COUNT = sizeof(P)/sizeof(*P);
Now, from the primes, for each input value, you can:
Compute the prime factorization
Compute the product of the sums of the powers of each prime factor.
This will result in the sum of the divisors. Subtract the input value from the sum to obtain the sum of proper divisors. These two steps can be combined into a single loop.
This algorithm works because multiplying polynomials naturally results in sums of all combinations of the polynomial terms multiplied together. In the case where each polynomial term consists of powers of primes that divide the input, the combinations of the terms multiplied together make up the divisors. The algorithm is fast, and should be able to process 500000 numbers in the interval [1, 500000] in less than a second on a Core i3 or better processor.
The following function implements the method described above.
unsigned compute (unsigned n) {
unsigned sum = 1;
unsigned x = n;
for (int i = 0; i < P_COUNT; ++i) {
if (P[i] > x / P[i]) break; /* remaining primes won't divide x */
if (x % P[i] == 0) { /* P[i] is a divisor of n */
unsigned sub = P[i] + 1; /* add in power of P[i] */
x /= P[i]; /* reduce x by P[i] */
while (x % P[i] == 0) { /* while P[i] still divides x */
x /= P[i]; /* reduce x */
sub = sub * P[i] + 1; /* add by another power of P[i] */
}
sum *= sub; /* product of sums */
}
}
if (x > 1) sum *= x + 1; /* if x > 1, then x is prime */
return sum - n;
}
The complexity of this code in O(n * log(n)). But you can output the required answer with constant time.
int ans[500000 + 10], m = 500000;
int f(){
for(int i = 1; i <= m; i++){
for(int j = i + i; j <= m; j += i){
ans[j] += i;
}
}
}
Here ans is an array that contain sum of proper divisor from 2 to m.