How to factorize a number? - c

I've been asked to factorize a number and show it in a specific way .
e.g: 100 = 2^2*5^2
This is the C++ code I've used so far with no dice , unfortunately:
#include <stdio.h>
#include <math.h>
//IsPrime indicates whether a given number is or is not prime.
bool IsPrime(long long n)
{
int j = 3;
if (n == 2)
{
return true;
}
else if (n % 2 == 0)
{
return false;
}
else
{
for (j = 3; j <= sqrt(n); j += 2)
{
if (n%j == 0)
{
return false;
}
}
}
return true;
}
int main(void)
{
long long n_orig,n, i=3 , primecount=0;
scanf("%lld", &n_orig);
n = n_orig;
if (n == 1)
{
printf("1");
return 0;
}
if (IsPrime(n))
{
printf("%lld", n);
return 0;
}
if (n % 2 == 0)
{
while (n >= 2 && n % 2 == 0)
{
primecount++;
n = n / 2;
}
if (primecount == 1)
{
printf("2*");
}
else
{
printf("2^%lld*", primecount);
}
}
primecount = 0;
n = n_orig;
while (i <= n/2)
{
if (IsPrime(i))
{
while (n >= i && n % i == 0)
{
primecount++;
n = n / i;
}
}
n = n_orig;
if (primecount == 0)
{
i++;
continue;
}
if (primecount == 1)
{
printf("%lld*", i);
}
else
{
printf("%lld^%lld*", i, primecount);
}
primecount = 0;
i+=2;
}
printf("\b");
return 0;
}
Using this code I was able to generate a few test cases, though when I uploaded my answer to the website where the codes are presumably evaluated , out of 7 test cases (which I cannot know what they exactly are) , I pass 3 , fail 3 and exceed time limit (the one that hasn't even been declared in the question) in one case. I'd really appreciate some help , and please be noob-friendly!
Also , I don't really wanna know if my answer could be improved in some way , my top priority right now is understanding why MY own code doesn't work as intended.
P.S : Usage of iostream and arrays is not allowed.
Thanks in advance.

Try this:
#include <stdio.h>
#include <math.h>
unsigned long long PrintMultiplicity(unsigned long long n,unsigned long long factor)
{
unsigned int count = 0;
while (n%factor == 0)
{
count++;
n /= factor;
}
if (count > 0)
{
printf("%llu^%u",factor,count);
if (n > 1)
printf("*");
}
return n;
}
void PrintFactorization(unsigned long long n)
{
unsigned long long factor;
unsigned int add;
printf("%llu = ",n);
n = PrintMultiplicity(n,2);
n = PrintMultiplicity(n,3);
// Check only factors that are adjacent to multiples of 6
for (factor = 5, add = 2; factor <= sqrt(n); factor += add, add = 6-add)
n = PrintMultiplicity(n,factor);
if (n > 1)
printf("%llu^1",n);
printf("\n");
}
int main()
{
unsigned long long n;
scanf("%llu",&n);
PrintFactorization(n);
return 0;
}

You need to perform some fine optimisations. Do not invoke isPrime() method for each value, instead consider a different approach so that irrelevant values can be ignored altogether at the very beginning.
Get the list of relevant primes numbers that comes under n, using Sieve of Eratosthenes concepts.
Start from the lowest prime value from the list, divide n to get intermediate values as
n / lowest_prime_that_perfectly_divide_n.
Continue doing this by checking with next higher prime value till n becomes 1. This way you would have count of each dividing factors.

You do not need prime tests, and lists of primes or prime wheels are only needed for acceleration. A simple program listing all prime factors is
#include <stdio.h>
#include <math.h>
int main(void)
{
long long n_orig,n,k;
scanf("%lld", &n_orig);
n = n_orig;
k=2;
while(k*k<=n) {
while(0==n%k) {
n = n/k;
printf("%lld ",k);
}
k++;
}
if(n>1) printf("%lld ",n);
printf("\n");
return 0;
}
This does not generate the required output format, but that can easily added to it.

Related

How to print 10 perfect numbers from a user given number in C?

I can't figure out how to print next ten Perfect numbers.
Here's what I have got so far:
#include <stdio.h>
int main() {
int n, c = 1, d = 2, sum = 1;
printf("Enter any number \n");
scanf("%d", &n);
printf("The perfect numbers are:");
while(c <= 10) {
sum = 1;
d = 2;
while(d <= n / 2) { //perfect no
if(n % d == 0) {
sum = sum + d;
}
d++;
}
if(sum == n) {
printf("%d\n", n);
}
c++;
}
return 0;
}
The output I am currently receiving:
input: 2 (say)
output: 6
What I want:
input: 2
output:
6
28
496
8128
33550336
858986905
137438691328
2305843008139952128
2658455991569831744654692615953842176
191561942608236107294793378084303638130997321548169216
I have just started coding. Any help will be appreciated.
The integer overflow issue mentioned by several folks is significant, but secondary. Even if we fix your broken logic, and adjust it to handle larger, fixed sized integers:
#include <stdio.h>
int main() {
unsigned long long number;
printf("Enter any number \n");
scanf("%llu", &number);
printf("The perfect numbers are:\n");
int total = 0;
while (total < 10) {
unsigned long long sum = 1, divisor = 2;
while (divisor <= number / 2) {
if (number % divisor == 0) {
sum += divisor;
}
divisor++;
}
if (sum == number) {
printf("%llu\n", number);
total++;
}
number += 1;
}
return 0;
}
You still wouldn't get past the first four perfect numbers in any reasonable amount of time:
> ./a.out
Enter any number
2
The perfect numbers are:
6
28
496
8128
The primary issue is you're using a bad algorithm. Read about Mersenne primes, and their relationship to perfect numbers, as well as the Lucas-Lehmer test. This approach takes more thought, but surprisingly, not much more code. And will produce more results faster (though eventually bog down as well.)
You have to put the counter after you find a perfect number, so increasing c must happen in the if statement that checks the perfect number, like this:
if(sum==n){
printf("%d",n);
c++;
}
After this you need to increase the number, called n, like this:
n++;
and based on the numbers, #Jonathan Leffler is right, you should use proper variables.
Research, divide and conquer
Perfect numbers are of the form 2p − 1 * (2p − 1).
Code will need extended precision to form 191561942608236107294793378084303638130997321548169216
Increase efficiency
Iterating to <= n / 2 takes far too long. Iterate up to <= n / d
// while(d <= n / 2) {
while(d <= n / d) {
Sample improved code:
bool isprime(unsigned long long x) {
if (x > 3) {
if (x % 2 == 0) {
return false;
}
for (unsigned long t = 3; t <= x / t; t += 2) {
if (x % t == 0) {
return false;
}
}
return true;
}
return x >= 2;
}
Advanced: See Lucas–Lehmer primality test for quick prime test of Mersenne numbers
The below code works for all but the 10th perfect number as code must test for isprime(267 - 1) and I should leave something for OP to do.
static void buff_mul(char *buff, unsigned power_of_2) {
unsigned long long m = 1ull << power_of_2;
size_t len = strlen(buff);
unsigned long long carry = 0;
for (size_t i = len; i > 0;) {
i--;
unsigned long long sum = (buff[i] - '0') * m + carry;
buff[i] = sum % 10 + '0';
carry = sum / 10;
}
while (carry) {
memmove(buff + 1, buff, ++len);
buff[0] = carry % 10 + '0';
carry /= 10;
}
}
void print_perfext(unsigned p) {
// 2**(p-1) * (2**p - 1)
assert(p > 1 && p <= 164);
char buff[200] = "1";
buff_mul(buff, p);
buff[strlen(buff) - 1]--; // Decrement, take advantage that the LSDigit is never 0
buff_mul(buff, p - 1);
puts(buff);
fflush(stdout);
}
//unsigned next_prime(unsigned first_numeber_to_test_if_prime) {
#include <stdio.h>
int main() {
unsigned p = 0;
for (unsigned i = 0; i < 9; i++) {
// If p prime && 2**p − 1 is prime, then 2**(p − 1) * (2**p − 1) is a perfect number.
while (!isprime(p) || !isprime((1uLL << p) - 1))
p++;
printf("%2u ", p);
print_perfext(p);
p++;
}
return 0;
}
Output
2 6
3 28
5 496
7 8128
13 33550336
17 8589869056
19 137438691328
31 2305843008139952128
61 2658455991569831744654692615953842176
From output you wrote I belive that u want to show 10 first perfect numbers
Now u are only showing 6 because u show them from 1 to 10. In this range there is only 6.
I wrote sth like this:
#include <stdio.h>
int isperfect(int input) {
int sum = 0, value = input / 2;
do {
if (input % value == 0) sum += value;
value--;
} while (value);
if (input == sum) return 1;
else return 0;
}
int main() {
int i;
int count;
for (i = 2, count = 0; count < 4; i++) {
if (isperfect(i) == 1) {
count++;
printf("%d\n", i);
}
}
return 0;
}
But I don't recomend counting more than 4 because its gonna take too much time

Performance issue in c while dealing with 12 digit number

currently i am working on a program. program is working perfectly but it has performance issue. the code is below.
#include<stdio.h>
int calculate(int temp)
{
int flag = 0,i = 2,tmp = 0;
for(i = 2;i < temp;i++)
{
if(temp % i == 0)
{
return 1;
}
}
}
int main()
{
long int i = 2,j,count = 0,n = 600851475143,flag = 0,prime = 0;
long int check;
while(i < n)
{
if(n % i == 0)
{
check = calculate(i);
if(check != 1)
{
prime = i;
printf(" Prime number is : %ld \n", prime);
}
}
i++;
}
printf(" Max prime number of %ld is : %ld \n",n,prime);
return 0;
}
I can't able to get the maximum prime number here.
can anyone tell me what should i do it takes too much time what should i do to get output fast?
If you are looking for a maximum prime, why are you starting at 2? Begin checking at n and work backwards
calculate can run faster since you only need to check for a divisor up to sqrt(temp), if it has a divisor larger than that, it also has a divisor smaller than that.
Your loop increments and decrements can be done in hops of 2. So you'd also halve the range of numbers to check.
Calling printf in the middle of a search loop for when the check fails is just a waste of execution speed. Instead, check for success and break out of the loop.
With these modifications in mind (and your code cleaned from a lot of UB):
#include<stdio.h>
int calculate(long int temp)
{
long int flag = 0,i = 2,tmp = 0;
if (temp % 2 == 0)
return 1;
for(i = 3; i*i <= temp; i+=2)
{
if(temp % i == 0)
{
return 1;
}
}
return 0;
}
int main(void)
{
long int j, count = 0, n = 600851475143, i = n, flag = 0, prime = 0;
long int check;
while(i > 0)
{
if(n % i == 0)
{
check = calculate(i);
if(check)
{
prime = i;
break;
}
}
i-=2;
}
printf(" Max prime number of %ld is : %ld \n",n,prime);
return 0;
}

Prime Number Generator in C

This is the Link to the problem: http://www.spoj.com/problems/PRIME1/
Basically we get two limits and we have to print out all the primes between them...
Here is my Code (Language == C) :
#include <stdio.h>
void IsPrime(int test){
for(int i= 2; i<test; i++){
if(test%i==0){
return;
}
}
printf("%d\n",test);
}
int main(){
int T,lower,upper;
scanf("%d",&T);
while(T--){
scanf("%d",&lower);
scanf("%d",&upper);
for(int i = lower;i<=upper;i++){
if(i>1){
IsPrime(i);
}
}
}
return 0;
}
On my local machine I ran this and it works for the simple test cases... My message from the website is timeout error so I was wondering if there is a more efficient way to solve this problem because apparently I am not solving it fast enough?
To begin with, you don't have to go checking every number up to n to determine if n is prime, only to its square root (there is a mathematical proof, not going to give it now). So:
void IsPrime(int test){
// i <= sqrt(test)
// but to avoid sqrt you can do i * i <= test
for(int i= 2; i * i <= test; i++){
if(test%i==0){
return;
}
}
printf("%d\n",test);
}
Next, we know that after 2, all other prime numbers are odd, so we can loop by 2 if we treat 2 as special case:
// Do greater than one check only once
if (lower > 1) {
// Special case - lower is 2
if (lower == 2) {
printf("%d\n", 2);
++lower;
}
for(int i = lower; i <= upper; i += 2){
IsPrime(i);
}
}
However since you have to do it T times, you will end up doing the checks a lot more than needed. Also, the problem has limits on n and m so it's basically perfect for a sieve, as #HennoBrandsma said.
Using these optimizations, you should go find all prime numbers to the limit, and store them in a container. Then, when prompted with a range, simply traverse the sieve and print out the numbers.
(That will require you to change up the IsPrime function a bit more - instead of printing the number right away, let it return true or false, and then based on that, add the number to the container)
You can try the following which has a slight optimization on the number of tests as well as skipping any even values greater than 2:
int isprime (int v)
{
int i;
if (v < 0) v = -v; /* insure v non-negative */
if (v < 2 || !((unsigned)v & 1)) /* 0, 1 + even > 2 are not prime */
return 0;
if (v == 2) return 1;
for (i = 3; i * i <= v; i+=2)
if (v % i == 0)
return 0;
return 1;
}
If you can use the math library and math.h, the following may be faster:
int isprime (int v)
{
int i;
if (v < 0) v = -v; /* insure v non-negative */
if (v < 2 || !((unsigned)v & 1)) /* 0, 1 + even > 2 are not prime */
return 0;
if (v == 2) return 1;
for (i = 3; i <= sqrt (v); i+=2)
if (v % i == 0)
return 0;
return 1;
}
I timed both versions over the int range for values between 1-2 million and they are close.
Note: In actual testing with repetitive calls, the version with i * i <= v (isprime2 below) is consistently faster than the call with i <= sqrt (v) (isprime3 below). e.g.:
$ ./bin/isprimetst2
isprime (1.650138 sec) - 78497 primes
isprime2 (0.805816 sec) - 78497 primes
isprime3 (0.983928 sec) - 78497 primes
The short driver iterated over all primes from 0-2000000, e.g.:
r = 0;
t1 = clock ();
for (v = 0; v < 2000000 - 1; v++) r += isprime2 (v);
t2 = clock ();
printf (" isprime2 (%lf sec) - %u primes\n", (t2-t1)/CLOCKS_PER_SEC, r);
r = 0;
t1 = clock ();
for (v = 0; v < 2000000 - 1; v++) r += isprime3 (v);
t2 = clock ();
printf (" isprime3 (%lf sec) - %u primes\n", (t2-t1)/CLOCKS_PER_SEC, r);
You can use a library maths.h in C and use sqrt function to calculate the square root of given number. So the program might be like this:
#include <stdio.h>
#include <maths.h>
int isPrime(int number){
int i;
if(number % 2 == 0){
return;
}
for(i=3; i<=sqrt(number); i++){
if(number % i == 0){
return;
}
printf("%d\n",number);
}
int main(){
int lower,upper,i;
if(lower >1){
if(lower == 2){
printf("2\n");
}
for(i=lower; i<=upper; i++){
isPrime(i);
}
return 0;
}
In short you can use some extra checks (like if(number % 2 == 0)) using if-else condition to decrease the time complexity of the program.For example a new if condition may be if(number % 5 ==0) etc. ,so with the help of these conditions check won't go in for loop in many of the cases, and that would decrease the time of the program.
#include<stdio.h>
int main()
{
int low,high,j;
int prime(int);
int t;
scanf("%d",&t);
while (t>0)
{
scanf("%d %d",&low,&high);
while (low<=1)
{
low++;
continue;
}
for (j=low;j<=high;j++)
{
if (prime(j)){
printf("%d\n",j);
}
}
printf("\n");
t--;
}
return 0;
}
int prime(int n)
{
int i;
for (i=2;i*i<=n;i++)
{
if (n%i==0){
return 0;
}
}
return 1;
}

Finding the length of an integer in C

I would like to know how I can find the length of an integer in C.
For instance:
1 => 1
25 => 2
12512 => 5
0 => 1
and so on.
How can I do this in C?
C:
You could take the base-10 log of the absolute value of the number, round it down, and add one. This works for positive and negative numbers that aren't 0, and avoids having to use any string conversion functions.
The log10, abs, and floor functions are provided by math.h. For example:
int nDigits = floor(log10(abs(the_integer))) + 1;
You should wrap this in a clause ensuring that the_integer != 0, since log10(0) returns -HUGE_VAL according to man 3 log.
Additionally, you may want to add one to the final result if the input is negative, if you're interested in the length of the number including its negative sign.
Java:
int nDigits = Math.floor(Math.log10(Math.abs(the_integer))) + 1;
N.B. The floating-point nature of the calculations involved in this method may cause it to be slower than a more direct approach. See the comments for Kangkan's answer for some discussion of efficiency.
If you're interested in a fast and very simple solution, the following might be quickest (this depends on the probability distribution of the numbers in question):
int lenHelper(unsigned x) {
if (x >= 1000000000) return 10;
if (x >= 100000000) return 9;
if (x >= 10000000) return 8;
if (x >= 1000000) return 7;
if (x >= 100000) return 6;
if (x >= 10000) return 5;
if (x >= 1000) return 4;
if (x >= 100) return 3;
if (x >= 10) return 2;
return 1;
}
int printLen(int x) {
return x < 0 ? lenHelper(-x) + 1 : lenHelper(x);
}
While it might not win prizes for the most ingenious solution, it's trivial to understand and also trivial to execute - so it's fast.
On a Q6600 using MSC I benchmarked this with the following loop:
int res = 0;
for(int i = -2000000000; i < 2000000000; i += 200) res += printLen(i);
This solution takes 0.062s, the second-fastest solution by Pete Kirkham using a smart-logarithm approach takes 0.115s - almost twice as long. However, for numbers around 10000 and below, the smart-log is faster.
At the expense of some clarity, you can more reliably beat smart-log (at least, on a Q6600):
int lenHelper(unsigned x) {
// this is either a fun exercise in optimization
// or it's extremely premature optimization.
if(x >= 100000) {
if(x >= 10000000) {
if(x >= 1000000000) return 10;
if(x >= 100000000) return 9;
return 8;
}
if(x >= 1000000) return 7;
return 6;
} else {
if(x >= 1000) {
if(x >= 10000) return 5;
return 4;
} else {
if(x >= 100) return 3;
if(x >= 10) return 2;
return 1;
}
}
}
This solution is still 0.062s on large numbers, and degrades to around 0.09s for smaller numbers - faster in both cases than the smart-log approach. (gcc makes faster code; 0.052 for this solution and 0.09s for the smart-log approach).
int get_int_len (int value){
int l=1;
while(value>9){ l++; value/=10; }
return l;
}
and second one will work for negative numbers too:
int get_int_len_with_negative_too (int value){
int l=!value;
while(value){ l++; value/=10; }
return l;
}
You can write a function like this:
unsigned numDigits(const unsigned n) {
if (n < 10) return 1;
return 1 + numDigits(n / 10);
}
length of n:
length = ( i==0 ) ? 1 : (int)log10(n)+1;
The number of digits of an integer x is equal to 1 + log10(x). So you can do this:
#include <math.h>
#include <stdio.h>
int main()
{
int x;
scanf("%d", &x);
printf("x has %d digits\n", 1 + (int)log10(x));
}
Or you can run a loop to count the digits yourself: do integer division by 10 until the number is 0:
int numDigits = 0;
do
{
++numDigits;
x = x / 10;
} while ( x );
You have to be a bit careful to return 1 if the integer is 0 in the first solution and you might also want to treat negative integers (work with -x if x < 0).
A correct snprintf implementation:
int count = snprintf(NULL, 0, "%i", x);
The most efficient way could possibly be to use a fast logarithm based approach, similar to those used to determine the highest bit set in an integer.
size_t printed_length ( int32_t x )
{
size_t count = x < 0 ? 2 : 1;
if ( x < 0 ) x = -x;
if ( x >= 100000000 ) {
count += 8;
x /= 100000000;
}
if ( x >= 10000 ) {
count += 4;
x /= 10000;
}
if ( x >= 100 ) {
count += 2;
x /= 100;
}
if ( x >= 10 )
++count;
return count;
}
This (possibly premature) optimisation takes 0.65s for 20 million calls on my netbook; iterative division like zed_0xff has takes 1.6s, recursive division like Kangkan takes 1.8s, and using floating point functions (Jordan Lewis' code) takes a whopping 6.6s. Using snprintf takes 11.5s, but will give you the size that snprintf requires for any format, not just integers. Jordan reports that the ordering of the timings are not maintained on his processor, which does floating point faster than mine.
The easiest is probably to ask snprintf for the printed length:
#include <stdio.h>
size_t printed_length ( int x )
{
return snprintf ( NULL, 0, "%d", x );
}
int main ()
{
int x[] = { 1, 25, 12512, 0, -15 };
for ( int i = 0; i < sizeof ( x ) / sizeof ( x[0] ); ++i )
printf ( "%d -> %d\n", x[i], printed_length ( x[i] ) );
return 0;
}
Yes, using sprintf.
int num;
scanf("%d",&num);
char testing[100];
sprintf(testing,"%d",num);
int length = strlen(testing);
Alternatively, you can do this mathematically using the log10 function.
int num;
scanf("%d",&num);
int length;
if (num == 0) {
length = 1;
} else {
length = log10(fabs(num)) + 1;
if (num < 0) length++;
}
int digits=1;
while (x>=10){
x/=10;
digits++;
}
return digits;
sprintf(s, "%d", n);
length_of_int = strlen(s);
You may use this -
(data_type)log10(variable_name)+1
ex:
len = (int)log10(number)+1;
In this problem , i've used some arithmetic solution . Thanks :)
int main(void)
{
int n, x = 10, i = 1;
scanf("%d", &n);
while(n / x > 0)
{
x*=10;
i++;
}
printf("the number contains %d digits\n", i);
return 0;
}
Quite simple
int main() {
int num = 123;
char buf[50];
// convert 123 to string [buf]
itoa(num, buf, 10);
// print our string
printf("%s\n", strlen (buf));
return 0;
}
keep dividing by ten until you get zero, then just output the number of divisions.
int intLen(int x)
{
if(!x) return 1;
int i;
for(i=0; x!=0; ++i)
{
x /= 10;
}
return i;
}
This goes for both negative and positive intigers
int get_len(int n)
{
if(n == 0)
return 1;
if(n < 0)
{
n = n * (-1); // if negative
}
return log10(n) + 1;
}
Same logic goes for loop
int get_len(int n)
{
if(n == 0)
return 1;
int len = 0;
if(n < 0)
n = n * (-1);
while(n > 1)
{
n /= 10;
len++;
}
return len;
}
Why don't you cast your integer to String and get length like this :
int data = 123;
int data_len = String(data).length();
For simple programs...
int num = 456, length=0 // or read value from the user to num
while(num>0){
num=num/10;
length++;
}
Use another variable to retain the initial num value.
In my opinion the shortest and easiest solution would be:
int length , n;
printf("Enter a number: ");
scanf("%d", &n);
length = 0;
while (n > 0) {
n = n / 10;
length++;
}
printf("Length of the number: %d", length);
My way:
Divide as long as number is no more divisible by 10:
u8 NumberOfDigits(u32 number)
{
u8 i = 1;
while (number /= 10) i++;
return i;
}
I don't know how fast is it in compared with other propositions..
int intlen(int integer){
int a;
for(a = 1; integer /= 10; a++);
return a;
}
A more verbose way would be to use this function.
int length(int n)
{
bool stop;
int nDigits = 0;
int dividend = 1;
do
{
stop = false;
if (n > dividend)
{
nDigits = nDigits + 1;
dividend = dividend * 10;
}
else {
stop = true;
}
}
while (stop == false);
return nDigits;
}
int returnIntLength(int value){
int counter = 0;
if(value < 0)
{
counter++;
value = -value;
}
else if(value == 0)
return 1;
while(value > 0){
value /= 10;
counter++;
}
return counter;
}
I think this method is well suited for this task:
value and answers:
-50 -> 3 //it will count - as one character as well if you dont want to count
minus then remove counter++ from 5th line.
566666 -> 6
0 -> 1
505 -> 3
Solution
Use the limit where the integer length changes, in the case of the decimal it is a power of 10, and thus use a counter for each verification that the specified integer has not exceeded the limit.
With the math.h dependency:
#include <math.h>
int count_digits_of_integer(unsigned int integer) {
int count = 1;
while(1) {
int limit = pow(10, count);
if(integer < limit) break;
count++;
}
return count;
}
Without dependency:
int int_pow(int base, int exponent) {
int potency = base;
for(int i = 1; i < exponent; i++) potency *= base;
return potency;
}
int count_digits_of_integer(unsigned int integer) {
int count = 1;
while(1) {
int limit = int_pow(10, count);
if(integer < limit) break;
count++;
}
return count;
}
Implementation
#include <stdio.h>
// Copy and paste the solution code here
int main() {
printf("%i -> (%i digits)\n", 0, count_digits_of_integer(0));
printf("%i -> (%i digits)\n", 12, count_digits_of_integer(12));
printf("%i -> (%i digits)\n", 34569, count_digits_of_integer(34569));
printf("%i -> (%i digits)\n", 1234, count_digits_of_integer(1234));
printf("%i -> (%i digits)\n", 3980000, count_digits_of_integer(3980000));
printf("%i -> (%i digits)\n", 100, count_digits_of_integer(100));
printf("%i -> (%i digits)\n", 9, count_digits_of_integer(9));
printf("%i -> (%i digits)\n", 385784, count_digits_of_integer(385784));
return 0;
}
Output:
0 -> (1 digits)
12 -> (2 digits)
34569 -> (5 digits)
1234 -> (4 digits)
3980000 -> (7 digits)
100 -> (3 digits)
9 -> (1 digits)
385784 -> (6 digits)
Hmm, maybe like this...?
#define _LEN(x) (sizeof(#x)/sizeof(char)-1)
You can also use this function to find the length of an integer:
int countlength(int number)
{
static int count = 0;
if (number > 0)
{
count++;
number /= 10;
countlength(number);
}
return count;
}
I think I got the most efficient way to find the length of an integer
its a very simple and elegant way
here it is:
int PEMath::LengthOfNum(int Num)
{
int count = 1; //count starts at one because its the minumum amount of digits posible
if (Num < 0)
{
Num *= (-1);
}
for(int i = 10; i <= Num; i*=10)
{
count++;
}
return count;
// this loop will loop until the number "i" is bigger then "Num"
// if "i" is less then "Num" multiply "i" by 10 and increase count
// when the loop ends the number of count is the length of "Num".
}
int main(void){
unsigned int n, size=0;
printf("get the int:");
scanf("%u",&n);
/*the magic*/
for(int i = 1; n >= i; i*=10){
size++;
}
printf("the value is: %u \n", n);
printf("the size is: %u \n", size);
return 0;
}
#include <stdio.h>
int main(void){
int c = 12388884;
printf("length of integer is: %d",printf("%d",c));
return 0;
}

Help making this code run faster for SPOJ

I've been doing a few of the challenges on the Sphere Online Judge (SPOJ), but I can't seem to get the second problem (the prime generator) to run within the time limit. How can the speed of the following code be increased?
#include <stdio.h>
#include <math.h>
int is_prime(int n);
void make_sieve();
void fast_prime(int n);
int primes[16000];
int main()
{
int nlines;
int m, n;
make_sieve();
scanf("%d", &nlines);
for (; nlines >= 1; nlines--) {
scanf("%d %d", &m, &n);
if (!(m % 2)) {
m++;
}
for ( ; m < n; m+=2) {
fast_prime(m);
}
printf("\n");
}
return 0;
}
/* Prints a number if it's prime. */
inline void fast_prime(int n)
{
int j;
for (int i = 0; ((j = primes[i]) > -1); i++) {
if (!(n % j)) {
return;
}
}
printf("%d\n", n);
}
/* Create an array listing prime numbers. */
void make_sieve()
{
int j = 0;
for (int i = 0; i < 16000; i++) {
primes[i] = -1;
}
for (int i = 2; i < 32000; i++) {
if (i % 2) {
if (is_prime(i)) {
primes[j] = i;
j++;
}
}
}
return;
}
/* Test if a number is prime. Return 1 if prime. Return 0 if not. */
int is_prime(int n)
{
int rootofn;
rootofn = sqrt(n);
if ((n <= 2) || (n == 3) || (n == 5) || (n == 7)) {
return 1;
}
if (((n % 2) == 0) || ((n % 3) == 0) || ((n % 5) == 0) || ((n % 7) == 0)) {
return 0;
}
for (int i = 11; i < rootofn; i += 2) {
if ((n % i) == 0) {
return 0;
}
}
return 1;
}
isprime() does not make use of the prime number table primes[].
Plus, implement a search of the primes array that will complete quickly using a binary search algorithm. The standard library has one.
To see where your time is spent in code you can use profiling
gcc example
gcc -p -g - o mycode mycode.c
===run the code--
gprof mycode
Currently, your problem isn't time limit. Its the fact that your program never print any numbers.
The most obvious error is that in fast_prime you are checking if n is divisible by prime[0], prime[1],... up to prime[k]. Even if n is prime, you won't print it, because n is somewhere in primes[], and so you'll get that n is divisible by some number...
To correct this, you need to check that n is divisible by some prime number up to the square root of n (this will also have the side effect of speeding up the code, as less numbers will be checked before deciding some number is a prime)
change fast_prime to
inline void fast_prime(int n)
{
int j;
int rootofn;
rootofn = sqrt(n);
for (int i = 0; ((j = primes[i]) > -1) && (j<rootofn); i++) {
if (!(n % j)) {
return;
}
}
printf("%d\n", n);
}

Resources