Prime number calculator. Are these both correct? - c

Been trying to write program for displaying prime numbers and just wanted to know if there is much difference between the following two algorithms.
1,
#include <stdio.h>
#define MAXNUMB 100000
int main(void){
int flag;
long i,j=MAXNUMB;
printf ("The Prime Numbers up to %ld are:\n 2\n", j);
for(i=3 ; i<=MAXNUMB; i = i+2){
j = 3; //only difference is in this line
flag = 0;
while((j*j <= i) && flag == 0){
if(i%j == 0){
flag = 1;
}
j++;
}
if (flag == 0){
printf("%8ld\n",i);
}
}
}
2,
#include <stdio.h>
#define MAXNUMB 100000
int main(void){
int flag;
long i,j=MAXNUMB;
printf ("The Prime Numbers up to %ld are:\n 2\n", j);
for(i=3 ; i<=MAXNUMB; i = i+2){
j = 2; //again this is the only different line
flag = 0;
while((j*j <= i) && flag == 0){
if(i%j == 0){
flag = 1;
}
j++;
}
if (flag == 0){
printf("%8ld\n",i);
}
}
}
It seems to me that both work but im not sure, maybe someone can shed some light.
Also, any general tips for someone starting to code, that apply for all programmers?
Thanks!

They both have the same output because you're skipping over even numbers with i = i + 2 and starting the loop with i = 3. So the i % j == 0 condition will never be true when j = 2.
To me it seems like they have the same output but i cant check every number
Wrap your approaches into separate functions, return the results in an array and then compare both arrays.

You can very quickly see the time it takes for these to complete with the built in time function for GNU/Linux or Cygwin. Using the G++ compiler, it takes around 0.109s to run the first snippet and around 0.141s to run the second one. So I guess it depends on what your definition of "more efficient" is. Note: I did not check for the accuracy of the results, just running the programs as they are.
As for general programming tips, you have access to boundless information on the internet, just search up programming tips. One could write an entire book on "tips" for a beginning programmer. Here is a good example.

Related

C program: print prime number between 1 to 100

I was just wondering why my code doesn't work. Yes I know that it's easy to find answers online but I just wanted to delve in why the things I do doesn't function well rather than simply getting answers.
#include <stdio.h>
int main() {
int i;
int j;
printf("all prime numbers between 1 and 100\n");
for (i = 2; i <= 100; ++i) {
if (i % !i != 0 && i>0 ) {
printf("%d ", i);
}
}
}
As you have noticed yourself, there are tons of example code for this out there, so there's little point for me in showing how to calculate primes. So instead, I show how to debug your code. In this case I'd doe something like this:
for (i = 2; i <= 100; ++i) {
printf("i: %d !i: %d\n", i, !i);
printf("i \% !i != 0: ", i % !i != 0);
if (i % !i != 0 && i>0 ) {
printf("%d ", i);
}
}
The exact printouts is something that you have to find out for yourself. But start with individual values, and then look at more complicated expressions. Also, use parenthesis whenever unsure. I don't know exactly how the expression in your if statement is parsed. I can think of several possibilities. Like:
((i % !i) != 0) && (i>0)
(i % (!i != 0)) && (i>0)
(i % !i) != (0 && i>0)
The point here is that your code does not work, and you have a very messy expression that is hard to understand exactly what it does. So use parenthesis.
Another thing you should do with that expression is to motivate each part with words. Can you explain why you have i>0? Because that's always true, to it's completely pointless. Instead of asking why it doesn't work. Try to explain to yourself why it should work. Get more and more detailed until you find something that you cannot explain. Then you probably have your bug there.
The definition of a prime is that it is an integer strictly greater than one, and is not divisible by any other integers than itself and and one. So now it's your job to explain how i % !i != 0 && i>0 should be able to check if i is an integer or not. And take explicit examples. For instance, if i is 5, describe the process when i % !i != 0 && i>0 checks if it is divisible by 2. Then explain how it checks for divisibility by 3.
The very simple question to your answer why it does not work is because the algorithm is wrong. :)

C program optimization/speed increase

As a beginner, I made a program which finds the number of prime numbers (prime) which are not higher than an input natural number (x). The program works fine (I think), but I want to make it work faster (for higher numbers). Is it possible, and if yes, how?
#include <stdio.h>
int main() {
int x, i, j, flag = 1, prime = 0 ;
scanf("%d", &x);
for (i = 2; i <= x; i++) {
j = 2;
while (flag == 1 && j < i/2 + 1 ) {
if (i % j == 0) {
flag = 0;
}
j++;
}
if (flag == 1) {
prime++;
}
flag = 1;
}
printf("%d\n", prime);
return 0;
}
Your algorithm does trial division, which is slow. A better algorithm is the 2000-year old Sieve of Eratosthenes:
function primes(n):
sieve := makeArray(2..n, True)
for p from 2 to n
if sieve[p]
output p # prime
for i from p*p to n step p
sieve[i] := False
I'll leave it to you to translate to C. If you want to know more, I modestly recommend the essay Programming with Prime Numbers at my blog.
There is one famous prime-number theorem. It states that
π(n)≈n/ln(n)
But there are certain algorithms for calculating this function. Follow the links:
PNT
Computing π(x): The Meissel, Lehmer, Lagarias, Miller, Odlyzko method

Break a number down int array and get factorial of each number - C programming

I apologize in advance for the length of the code and how tedious it may be to follow. I am trying to break a number down into individual digits and get the factorial of each one. I have successfully done that (with the help of paxdiablo) but I want to do this all the way from 99999 to 0. In order to do that I have placed all of the code in a loop starting indx at 99999 and decreasing value until it reaches 1. The reason I am trying to do this is because I need to compare the sum of the factorial of each individual digit to the number and if they are equal then I have a match. The program runs and the first run for the number 99999 works perfectly fine but the next loop SHOULD be 99998 and do the exact same thing but instead the next number is 4. I have no idea why it would do this. Any help would be appreciated.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
int indx;
int fact = 1;
int individualDigit[50];
int length;
for(indx = 99999; indx > 0; indx--)
{
num = indx;
for (length = 0; num > 0; length++, num /= 10)
{
individualDigit[length] = num % 10;
}
printf ("Digit count = %d, digits =", length);
for (indx = length - 1; indx >= 0; indx--)
{
printf (" %d", individualDigit[indx]);
}
for (indx = 0; indx < length; indx++)
{
while (individualDigit[indx] > 0)
{
fact = fact * individualDigit[indx];
individualDigit[indx]--;
}
printf("\n%d ", fact);
fact = 1;
}
printf("\n");
}
return 0;
}
The value in "indx" is being used by multiple for loops. The line
for (indx = 0; indx < length; indx++)
increments indx back up to 4, which is the value used by your outer loop. Just use some new variables to count the different loops
This seems like a homework question and your code quality seems to confirm that so I'm hesitant to write you actual code but I'll give you a few pointers.
As #Cody Braun said above your index variable is getting overwritten in line 23 where you calculate the factorial.
There is a much more efficient way to calculate factorials using dynamic programming
I don't know if you just didn't want to do it in the post but learning how to properly format your code will help you catch these errors quicker and keep yourself form making them. As well as make it easier for others to read your code.
Cheers

Counting number of primes within a given range of long int using C

Well, there are lots of such questions available in SO as well as other forums. However, none of these helped.
I wrote a program in "C" to find number of primes within a range. The range i in long int. I am using Sieve of Eratosthenes" algorithm. I am using an array of long ints to store all the numbers from 1 till the limit. I could not think of a better approach to achieve without using an array. The code works fine, till 10000000. But after that, it runs out of memory and exits. Below is my code.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef unsigned long uint_32;
int main() {
uint_32 i, N, *list, cross=0, j=4, k, primes_cnt = 0;
clock_t start, end;
double exec_time;
system("cls");
printf("Enter N\n");
scanf("%lu", &N);
list = (uint_32 *) malloc( (N+1) * sizeof(uint_32));
start = clock();
for(i=0; i<=N+1; i++) {
list[i] = i;
}
for(i=0; cross<=N/2; i++) {
if(i == 0)
cross = 2;
else if(i == 1)
cross = 3;
else {
for(j=cross+1; j<=N; j++) {
if(list[j] != 0){
cross = list[j];
break;
}
}
}
for(k=cross*2; k<=N; k+=cross) {
if(k <= N)
list[k] = 0;
}
}
for(i=2; i<=N; i++) {
if(list[i] == 0)
continue;
else
primes_cnt++;
}
printf("%lu", primes_cnt);
end = clock();
exec_time = (double) (end-start);
printf("\n%f", exec_time);
return 0;
}
I am stuck and can't think of a better way to achieve this. Any help will be hugely appreciated. Thanks.
Edit:
My aim is to generate and print all prime numbers below the range. As printing consumed a lot of time, I thought of getting the first step right.
There are other algorithm that does not require you to generate prime number up to N to count number of prime below N. The easiest algorithm to implement is Legendre Prime Counting. The algorithm requires you to generate only sqrt(N) prime to determine the number of prime below N.
The idea behind the algorithm is that
pi(n) = phi(n, sqrt(n)) + pi(sqrt(n)) - 1
where
pi(n) = number of prime below N
phi(n, m) = number of number below N that is not divisible by any prime below m.
That's mean phi(n, sqrt(n)) = number of prime between sqrt(n) to n. For how to calculate the phi, you can go to the following link (Feasible implementation of a Prime Counting Function)
The reason why it is more efficient is because it is easiest to compute phi(n, m) than to compute pi(n). Let say that I want to compute phi(100, 3) means that how many number below or equal to 100 that does not divisible by 2 and 3. You can do as following. phi(100, 3) = 100 - 100/2 - 100/3 + 100/6.
Your code uses about 32 times as much memory as it needs. Note that since you initialized list[i] = i the assignment cross = list[j] can be replaced with cross = j, making it possible to replace list with a bit vector.
However, this is not enough to bring the range to 264, because your implementation would require 261 bytes (2 exbibytes) of memory, so you need to optimize some more.
The next thing to notice is that you do not need to go up to N/2 when "crossing" the numbers: √N is sufficient (you should be able to prove this by thinking about the result of dividing a composite number by its divisors above √N). This brings memory requirements within your reach, because your "crossing" primes would fit in about 4 GB of memory.
Once you have an array of crossing primes, you can build a partial sieve for any range without keeping in memory all ranges that precede it. This is called the Segmented sieve. You can find details on it, along with a simple implementation, on the page of primesieve generator. Another advantage of this approach is that you can parallelize it, bringing the time down even further.
You can tweak the algorithm a bit to calculate the prime numbers in chunks.
Load a part of the array (as much as fits the memory), and in addition hold a list of all known prime numbers.
Whenever you load a chunk, first go through the already known prime numbers, and similar to the regular sieve, set all non primes as such.
Then, go over the array again, mark whatever you can, and add to the list the new prime numbers found.
When done, you'll have a list containing all your prime numbers.
I could see that the approach you are using is the basic implementation of Eratosthenes, that first stick out all the 2's multiple and then 3's multiple and so on.
But I have a better solution to the question. Actually, there is question on spoj PRINT. Please go through it and do check the constraints it follows. Below is my code snippet for this problem:
#include<stdio.h>
#include<math.h>
#include<cstdlib>
int num[46500] = {0},prime[5000],prime_index = -1;
int main() {
/* First, calculate the prime up-to the sqrt(N) (preferably greater than, but near to
sqrt(N) */
prime[++prime_index] = 2; int i,j,k;
for(i=3; i<216; i += 2) {
if(num[i] == 0) {
prime[++prime_index] = i;
for(j = i*i, k = 2*i; j<=46500; j += k) {
num[j] = 1;
}
}
}
for(; i<=46500; i+= 2) {
if(num[i] == 0) {
prime[++prime_index] = i;
}
}
int t; // Stands for number of test cases
scanf("%i",&t);
while(t--) {
bool arr[1000005] = {0}; int m,n,j,k;
scanf("%i%i",&m,&n);
if(m == 1)
m++;
if(m == 2 && m <= n) {
printf("2\n");
}
int sqt = sqrt(n) + 1;
for(i=0; i<=prime_index; i++) {
if(prime[i] > sqt) {
sqt = i;
break;
}
}
for(; m<=n && m <= prime[prime_index]; m++) {
if(m&1 && num[m] == 0) {
printf("%i\n",m);
}
}
if(m%2 == 0) {
m++;
}
for(i=1; i<=sqt; i++) {
j = (m%prime[i]) ? (m + prime[i] - m%prime[i]) : (m);
for(k=j; k<=n; k += prime[i]) {
arr[k-m] = 1;
}
}
for(i=0; i<=n-m; i += 2) {
if(!arr[i]) {
printf("%i\n",m+i);
}
}
printf("\n");
}
return 0;
}
I hope you got the point:
And, as you mentioned that your program is working fine up-to 10^7 but above it fails, it must be because you must be running out of the memory.
NOTE: I'm sharing my code only for knowledge purpose. Please, don't copy and paste it, until you get the point.

What are these last lines of code doing in Exercise 1-13 of K & R's The C Programming Language?

I am very new to programming in general, so please bear with my lack of knowledge.
I have spent a couple of hours now on exercise 1-13. I finally decided to look up the answer, which I found at this link https://github.com/ccpalettes/the-c-programming-language-second-edition-solutions/blob/master/Chapter1/Exercise%201-13/word_length.c .
Because I didn't want to copy it completely for the sake of learning, I tried to understand the code and then remake it. (This resulted in almost a complete copy, but I understand it better than I would have otherwise.)
This is what I have so far:
#include <stdio.h>
#define IN 1
#define OUT 0
#define LARGEST 10
main()
{
int c, state, l, i, j;
int length[LARGEST + 1];
for (i = 0; i <= LARGEST; ++i)
length[i] = 0;
state = OUT;
while ((c = getchar()) != EOF) {
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
if (state == OUT) {
l = 0;
state = IN;
}
++l;
}
else
if (state == IN) {
if (l <= LARGEST)
++length[l - 1];
//minus 1 because the nth term of an array is actually array[n-1]
else //if (l > LARGEST)
++length[LARGEST];
state = OUT;
}
if (c == EOF)
break;
}
for (i = 0; i <= LARGEST; ++i) {
if (i != LARGEST) //because array[10] refers to the 11th spot
printf("\t %2d |", i + 1); //plus one because 1st is array [0]
//this actually results in 1-10 because the 0-9 plus one makes the highest 10
else
printf("\t>%2d |", LARGEST);
for (j = 0; j < length[i]; ++j)
putchar('x');
putchar('\n');
}
return 0;
}
Please ignore my comments. They were meant for me, so that I could explain the program to myself.
I am having two issues that I just can't figure out, and they're driving me crazy:
The output always accounts for one word less than in the input, meaning "my name is not bob" results in:
...
2 |xx
3 |x
4 |x
...
Also, I don't understand what is going on at the end of the program. Specifically, I don't understand here why the variable j is being used:
for (j = 0; j < length[i]; ++j)
putchar('x');
Thanks so much for your help, and I'm sorry if this is too beginner for the community.
Well, trying to sum up all the answers since the question is not closed.
First, we need to correct the main() line:
int main(void) {
...
return 0;
}
The int is necessary because you return a value at the end of the function, and the void means that the function doesn't receive any arguments.
I've copied your code and executed on my machine (Ubuntu 12.04) and it worked perfectly. Could you present some examples to generate the error?
As everybody said, j is just a variable to traverse the vector. length[i] is a vector that holds, in each position i the number of words with length i. For instance, if position 3 has a value of 4, e.g. length[3] = 4, it means that there are 4 words
with length 3.
Finally, if I may, I'd like to give you a tip. It is good practice choosing meaningful names for your variables. The code you linked here helped me to understand what the program should do. Variable names such, length, or defines IN, OUT or LARGEST are too vague.
I hope this gather all answers until now and helped you even more.

Resources