Find 10000th prime number [duplicate] - c

This question already has answers here:
Prime Number Algorithm
(7 answers)
Closed 8 years ago.
This is my code for finding 10000th prime number but it is really slow, it takes 7 seconds to calculate.
#include <stdio.h>
#include <stdlib.h>
long int prime (int n)
{
int i;
for(i=2;i<n;i++)
{
if(n%i==0)
return 0;
}
return 1;
}
int main()
{
int i=2,counter=0;
while(1)
{
if(prime(i))
counter++;
if(counter==10000)
break;
i++;
}
printf("10000th prime number is: %d",i);
}
It is brute force method so that's probably reason why it's so slow.
I think problem may be that it has to call function so many times. So what do you think can it be optimised or it's better to find some math formula for this.

You can reduce the time substantially by making the following changes to prime():
Stopping at sqrt(n).
Starting at i=3, and incrementing i by 2.
Here's a program that contains both versions and the time taken by each.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
int is_prime1 (int n)
{
int i;
for(i=2;i<n;i++)
{
if(n%i==0)
return 0;
}
return 1;
}
void do_it1(int max)
{
clock_t start = clock();
clock_t end;
int i=2,counter=0;
while(1)
{
if(is_prime1(i))
counter++;
if(counter==max)
break;
i++;
}
end = clock();
printf("%dth prime number is: %d\n", max, i);
printf("Time taken: %lf\n", 1.0*(end-start)/CLOCKS_PER_SEC);
}
int is_prime2 (int n)
{
int i;
int stop = sqrt(n);
for(i=3;i<=stop;i+=2)
{
if(n%i==0)
return 0;
}
return 1;
}
void do_it2(int max)
{
clock_t start = clock();
clock_t end;
int i=3,counter=1;
while(1)
{
if(is_prime2(i))
counter++;
if(counter==max)
break;
i += 2;
}
end = clock();
printf("%dth prime number is: %d\n", max, i);
printf("Time taken: %lf\n", 1.0*(end-start)/CLOCKS_PER_SEC);
}
int main(int argc, char** argv)
{
int max = atoi(argv[1]);
do_it1(max);
do_it2(max);
}
Sample execution:
./test 10000
Sample output:
10000th prime number is: 104729
Time taken: 9.469000
10000th prime number is: 104729
Time taken: 0.078000

To optimized your code a little bit (changes are made based on comments):
long int prime (int n)
{
int i;
int e = (int)sqrt(n);
for(i=2; i<=e;i++)
{
if(n%i==0)
return 0;
}
return 1;
}

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int *prime;
int prime_n;
void make_prime_table(int n){
prime = malloc(sizeof(int) * n / 2);
prime_n =0;
prime[prime_n++] = 2;
prime[prime_n++] = 3;
int i, j;
for(i = 5; i <= n; i +=2){
bool is_prime = true;
for(j = 1; j < prime_n ; ++j){
int t = prime[j];
if(t * t > i)
break;
if(i % t == 0){
is_prime = false;
break;
}
}
if(is_prime)
prime[prime_n++] = i;
}
}
int main(void){
int n = 105000;
make_prime_table(n);
if(prime_n >= 10000)
printf("10000th prime number is: %d\n", prime[9999]);
free(prime);
return 0;
}

Related

Why does same program act different in ideone and codeblocks?

This code is designed to find the sum of digits of 100!. I get the correct ouput in ideone but the wrong one in codeblocks. Please help.
#include <stdio.h>
#include <stdlib.h>
#define size_of_number 160
#define question 100
//Function Prototypes
void initialise(int[]);
int sum_of_digits(int[]);
void factorial(int[],int);
int main()
{
int number[size_of_number];
int sum;
initialise(number);
factorial(number, question);
//Getting the sum of the digits of the number
sum = sum_of_digits(number);
printf("The sum of the digits of %d! is %d.\n",question, sum);
return 0;
}
//Initially, the number is 0 so all it's digits are set to zero.
void initialise(int number[])
{
int i;
for(i = 0; i < size_of_number; i++)
{
number[i] = 0;
}
}
//Finding the factorial by multiplying the digits
void factorial(int number[], int num)
{
int i, first_digit;
int carry, replace, product;
first_digit = 0;
number[first_digit] = 1;
while(num != 1)
{
carry = 0;
for(i = 0; i <= first_digit; i++)
{
product = num*number[i] + carry;
replace = product%10;
carry = product/10;
number[i] = replace;
if( (i == first_digit) && (carry > 0) )
{
first_digit++;
}
}
num--;
}
}
//Finding the sum of all digits
int sum_of_digits(int number[])
{
int i, sum;
for(i = 0; i < size_of_number; i++)
{
sum = sum + number[i];
}
return sum;
}
I had problems with some other programs too. Why s Codeblocks not giving the correct output which is 648 ?
You don't initialize sum in the function sum_of_digits. Normal local variables don't automatically get a starting value in C, so your program has what the C standard calls undefined behaviour. Anything can happen, but what typically does happen is that the variable starts with whatever data happened to be in the place in memory where the variable happened to be located.

C - Simulator of dice rolling

The intention here is to write a C code for 2 dices rolling simulator.
It has to write the answer in a form of histogram (10 results by line).
Calculate and give the minimum, maximum, and the average of dice rolls. As well as the duplicates. I have to admit I am stuck right now. Any help would be appreciated.
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 100
void initarray(int d[]);
void printarray(int d[]);
void printstar(int n);
void fancyprint(int d[]);
int roll(void);
int main(int argc, char* argv[]) {
{
int roll();
int d[13]; /* 2-12 hold num of rolls */
int i; /* variable de la boucle */
int starttime = time(NULL); /* temps horloge*/
srand(1020);
printf("Simulation de 100 lancees de 2 des");
for (i = 0; i < N; i++)
d[roll() + roll()]++;
printarray(d);
fancyprint(d);
printf("Elapsed time: %ld seconds\n",
time(NULL) - starttime);
return 0;
}
/* initarray: initialize statistic array */
void initarray(int d[]){
int i;
for (i = 2; i < 13; i++)
d[i] = 0;
}
/* printarray: print each num of rolls */
void printarray(int d[]){
int i;
double e[] = {0, 0,
1.0/36.0, 2.0/36.0, 3.0/36.0, 4.0/36.0,
5.0/36.0, 6.0/36.0, 5.0/36.0, 4.0/36.0,
3.0/36.0, 2.0/36.0, 1.0/36.0};
printf("Sum Times Frequency");
printf(" Exact Diff\n\n");
for (i = 2; i < 13; i++)
printf("%2d %7d %11.7f %10.7f %8.4f\n",
i,
d[i],
(double)d[i]/N*100.0,
e[i]*100.0,
((double)(d[i]) -
e[i]*N)/N*100.0);
}
/* printstar: print n stars */
void printstar(int n) {
while (n > 0) {
printf("*");
n--;
}
}
/* fancyprint: print bar graph */
void fancyprint(int d[]){
int i;
printf("\n");
for (i = 2; i < 13; i++) {
printf("Sum:%3d |", i);
printstar(300*d[i]/N);
printf("\n");
}
printf("\n");
}
/* roll: simulate rolling a die */
int roll() {
return (int) (6.0*(rand()/(double)RAND_MAX)
+ 1.0);
return 0;
}
}
OP's roll() generates a 7 once in a while: when rand() == RAND_MAX.
int roll(void) {
// return (int) (6.0*(rand()/(double)RAND_MAX) + 1.0);
return (int) (6.0*(rand()/((double)RAND_MAX + 1) + 1.0);
}
The above will have trouble if (double)RAND_MAX is not exact.
It also still has a small bias.
Consider other approaches that do not use floating point. Such as: https://stackoverflow.com/a/17554531/2410359
Possible other issues.

How to invent a code for square-root?

I want to write a code for making square-root not using pow().
here is what i have tried:
#include <stdio.h>
#include <stdlib.h>
int main(){
int a,I,sum=0,cnt=0;
printf("enter number");
scanf("%d",&a);
for(I=1;sum<a;I+=2){
sum+=I;
cnt++;
}
printf("answer is:%d",cnt);
return 0;
}
for numbers like 4,9,16,... it works but for numbers like 10,17,21,.. it does not work and the result is more than it shoud be.
what is the problem?
for(I=1;;I+=2){
sum+=I;
if(sum>a)
break;
cnt++;
}
#include <stdio.h>
#include <stdlib.h>
int main(){
int a,I,sum=0,cnt=0;
printf("enter number");
scanf("%d",&a);
for(I=1;sum<a;I+=2){
sum+=I;
cnt++;
}
if(sum==a)
printf("answer is:%d",cnt);
else
printf("answer is:%d",cnt-1);
return 0;
}
You can try this
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a,I,cnt=0;
int sum = 0;
printf("enter number");
scanf("%d",&a);
for(I=1;sum<a;I+=2){
sum+=I;
cnt++;
if(sum > a) //add this if statement to decrement cnt by 1 when sum exceeds a.
cnt--;
}
printf("answer is:%d",cnt);
}
Input:
21
Output:
4
Use the Babylonian method:
double babyl_sqrt(double x)
{
double i;
for (i = x / 2; fabs(i * i - x) > 0.000001f; i = (i + x / i) / 2)
;
return i;
}
To get a rounded to nearest int, adjust the limit a little bit.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int sqrt_round(int a) {
int I;
int sum = 0;
int cnt = 0;
// for(I=1;sum<a;I+=2){
for (I = 1; (sum + I / 2) < a; I += 2) {
sum += I;
cnt++;
}
return cnt;
}
int main() {
int a;
printf("enter number");
scanf("%d", &a);
printf("answer is:%d\n", sqrt_round(a));
printf("answer is:%g\n", sqrt(a));
return 0;
}
#include<stdio.h>
int main()
{
float i,x=10;
int lp;
scanf("%f",&i);
for(lp=0;lp<5;lp++)
x=(x-((((x*x)-i))/(2*x)));
printf("sqaure root of %f=%f\n",i,x);
return 0;
}
Compute and return the square root of x, where x is guaranteed to be a non-negative integer.
Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.
Example 1:
Input: 4
Output: 2
Example 2:
Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since
the decimal part is truncated, 2 is returned.
public int mySqrt(int x) {
long start = 1;
long end = x;
while(start + 1< end) {
long mid = start + (end - start) / 2 ;
if(mid * mid == x) {
return (int)mid;
}else if(mid * mid < x) {
start = mid ;
}else {
end = mid;
}
}
if(end * end == x) {
return (int)end;
}
return (int)start;
}

Calculate the highest palindrome that is the product of two 3-digit numbers

I'm stuck on Euler#4 which is to calculate the highest palindrome number by product of two 3-digit numbers. The answer I'm getting is always 0. Evidently help is required.
#include <stdio.h>
#include <conio.h>
int main()
{
int i,j,h=0,m=0,p=0;
clrscr();
for(i=100;i<1000;i++)
{
for(j=100;j<1000;j++)
{
p=i*j;
h=p/100000;
m=p%10;
if(h==m)
{
h=(p/10000)%10;
m=(p/10)%10;
if(h==m)
{
h=(p/1000)%10;
m=(p%1000)/100;
if(h==p)
{
printf("%d\n",p);
}
}
}
}
}
return 0;
}
Its wrong to do this, but still dont make it a habit. I think one can solve first 50 question with ease.
#include <stdio.h>
static int is_palindromic(unsigned int n);
int main(void)
{
unsigned int i, j, max = 0;
for (i = 100; i <= 999; i++) {
for (j = 100; j <= 999; j++) {
unsigned int p = i*j;
if (is_palindromic(p) && p > max) {
max = p;
}
}
}
printf("%u\n", max);
return 0;
}
int is_palindromic(unsigned int n)
{
unsigned int reversed = 0, t = n;
while (t) {
reversed = 10*reversed + (t % 10);
t /= 10;
}
return reversed == n;
}

Counting number of searches

I updated my main and sequetialSearch and now it crashes when it runs. It compiles okay, but then crashes.
main.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include "percentage.h"
#include "sequentialSearch.h"
#define searchAmount 100
int main(int argc, char *argv[])
{
int numbers[100];
int searches[searchAmount];
int testAmounts[searchAmount];
int i;
int where;
int searchSuccess;
int searchUnsuccess;
int percent;
int looker;
int sum;
int average;
srand(time(NULL));
for (i = 0; i < 100; i++){
numbers[i] = rand() % 200;
}
for (i = 0; i < searchAmount; i++){
searches[i] = rand() % 200;
}
searchUnsuccess = 0;
searchSuccess = 0;
sum = 0;
for(i = 0; i < searchAmount; i++){
if(seqSearch(numbers, 100, searches[i], &where, &looker)){
searchSuccess++;
testAmounts[i] = looker;
}else{
searchUnsuccess++;
testAmounts[i] = looker;
}
}
for(i = 0; i < searchAmount; i++){
sum = sum + testAmounts[i];
}
average = sum / searchAmount;
percent = percentRate(searchSuccess, searchAmount);
printf("Total number of searches: %d\n", searchAmount);
printf("Total successful searches: %d\n", searchSuccess);
printf("Success Rate: %d%%\n", percent);
printf("Total number of tests ran: %d\n", average);
system("PAUSE");
return 0;
}
sequentialSearch.h
bool seqSearch (int list[], int last, int target, int* locn, int* looker){
*looker = 0;
while(*looker < last && target != list[*looker]){
*looker++;
}
*locn = *looker;
return(target == list[*looker]);
}
Pass looker in by reference, so that you can access its value from the caller.
int looker;
...
for(i = 0; i < searchAmount; i++){
if(seqSearch(numbers, 100, searches[i], &where, &looker)){
searches[i] += looker;
searchSuccess++;
}else{
searchUnsuccess++;
}
}
bool seqSearch (int list[], int last, int target, int* locn, int *looker){
*looker = 0;
while(*looker < last && target != list[*looker]){
(*looker)++;
}
*locn = *looker;
return(target == list[*looker]);
}
By the way, you may wish to reconsider defining functions in your header file; this could cause problems with duplicate symbol when linking if you have more than one c file including this file.
Why not just pass looker in as an int*, use it essentially as you have been, look at the value after seqSearch(...) returns, and add it to a running total back in main()?
One problem is that the increment of looker in seqSearch is incrementing the pointer rather than the value. It should probably be:
(*looker)++;

Resources