Calculating primes using wiki algorithm - c

I have just started using C and I am currently working on calculating primes using the wikipedia algorithm here:
algorithm Sieve of Eratosthenes is
input: an integer n > 1.
output: all prime numbers from 2 through n.
let A be an array of Boolean values, indexed by integers 2 to n,
initially all set to true.
for i = 2, 3, 4, ..., not exceeding √n do
if A[i] is true
for j = i2, i2+i, i2+2i, i2+3i, ..., not exceeding n do
A[j] := false
return all i such that A[i] is true.
When I try implementing what I think turns out like the code above, I get what I believe is an 'infinite loop', where might I have gone wrong?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
//create empty array to store values
int isPrime[] = {};
//set a large number
int n = 1000;
//create for loop
for(int i = 2; i < n; i++){
///create another for loop taking the exponents
for(int j = i; j < pow(i, 2); j++){
//if i is equal to j is true then return those values true
if(isPrime[i] == isPrime[j]){
printf("%d", isPrime[i]);
}
}
}

There's many errors in your code including an empty array, use of pow (which is a floating-point function) and numerous logic errors that deviate from the wikipedia example code.
Here's a corrected, working version that follows the logic of the wikipedia version, with a loop afterwards to print out all the primes less than n:
#include <stdio.h>
int main(void) {
int n = 1000;
int isPrime[n];
for (int i = 0; i < n; i++) {
isPrime[i] = 1;
}
for (int i = 2; i * i < n; i++) {
if (isPrime[i]) {
for (int j = i * i; j < n; j += i) {
isPrime[j] = 0;
}
}
}
for (int i = 2; i < n; i++) {
if (isPrime[i]) {
printf("%d ", i);
}
}
printf("\n");
}
(Note that a small deviation from the wikipedia algorithm is that this prints primes less than n rather than primes less than or equal to n).

Related

Finding prime numbers with Sieve of Eratosthenes algorithm in c

I am trying to find the first 1000 prime numbers using an algorithm called "Sieve of Eratosthenes"
Basically, you have a list of ascending numbers 2,3,4 ... and this list represents potential prime numbers; Number 2 is prime so it is printed, then, we check the list for any multiples of 2. If we find any, we omit them. And keep going till we have our correct list.
I thought of using nested loops for this one, and although I don't feel like it's a perfect idea; I don't see why it won't work. Here is my code. It doesn't run at all
#include <stdio.h>
#include <stdlib.h>
int main()
{
int primelist[999];
int n = 2;
for (int i = 1; i <= 999; i++)
{
primelist[i] = i;
}
for (int i = 0; i <= 999; i++, n++)
{
while (primelist[i] != 0) {
for (int i = 0; i <= 999; i++)
{
if ( (primelist[n] % primelist[i]) == 0 )
{
primelist[i] = 0;
}
}
}
}
}

Sorting integers by sum of their digits

I'm trying to write a program that will sort an array of 20 random numbers by the sums of their digits.
For example:
"5 > 11" because 5 > 1+1 (5 > 2).
I managed to sort the sums but is it possible to return to the original numbers or do it other way?
#include <stdio.h>
void sortujTab(int tab[], int size){
int sum,i;
for(int i=0;i<size;i++)
{
while(tab[i]>0){//sum as added digits of an integer
int p=tab[i]%10;
sum=sum+p;
tab[i]/=10;
}
tab[i]=sum;
sum=0;
}
for(int i=0;i<size;i++)//print of unsorted sums
{
printf("%d,",tab[i]);
}
printf("\n");
for(int i=0;i<size;i++)//sorting sums
for(int j=i+1;j<=size;j++)
{
if(tab[i]>tab[j]){
int temp=tab[j];
tab[j]=tab[i];
tab[i]=temp;
}
}
for(int i=0;i<20;i++)//print of sorted sums
{
printf("%d,",tab[i]);
}
}
int main()
{
int tab[20];
int size=sizeof(tab)/sizeof(*tab);
for(int i=0;i<=20;i++)
{
tab[i]=rand()%1000;// assamble the value
}
for(int i=0;i<20;i++)
{
printf("%d,",tab[i]);//print unsorted
}
printf("\n");
sortujTab(tab,size);
return 0;
}
There are two basic approach :
Create a function that return the sum for an integer, say sum(int a), then call it on comparison, so instead of tab[i] > tab [j] it becomes sum(tab[i]) > sum (tab[j])
Store the sum into a different array, compare with the new array, and on swapping, swap both the original and the new array
The first solution works well enough if the array is small and takes no extra memory, while the second solution didn't need to repeatedly calculate the sum. A caching approach is also possible with map but it's only worth it if there are enough identical numbers in the array.
Since your numbers are non-negative and less than 1000, you can encode the sum of the digits in the numbers itself. So, this formula will be true: encoded_number = original_number + 1000 * sum_of_the_digits. encoded_number/1000 will decode the sum of the digits, and encoded_number%1000 will decode the original number. Follow the modified code below. The numbers enclosed by parentheses in the output are original numbers. I've tried to modify minimally your code.
#include <stdio.h>
#include <stdlib.h>
void sortujTab(int tab[], int size)
{
for (int i = 0; i < size; i++) {
int sum = 0, n = tab[i];
while (n > 0) { //sum as added digits of an integer
int p = n % 10;
sum = sum + p;
n /= 10;
}
tab[i] += sum * 1000;
}
for (int i = 0; i < size; i++) { //print of unsorted sums
printf("%d%c", tab[i] / 1000, i < size - 1 ? ',' : '\n');
}
for (int i = 0; i < size; i++) { //sorting sums
for (int j = i + 1; j < size; j++) {
if (tab[i] / 1000 > tab[j] / 1000) {
int temp = tab[j];
tab[j] = tab[i];
tab[i] = temp;
}
}
}
for (int i = 0; i < size; i++) { //print of sorted sums
printf("%d(%d)%c", tab[i] / 1000, tab[i] % 1000, i < size - 1 ? ',' : '\n');
}
}
int main(void)
{
int tab[20];
int size = sizeof(tab) / sizeof(*tab);
for (int i = 0; i < size; i++) {
tab[i] = rand() % 1000; // assamble the value
}
for (int i = 0; i < size; i++) {
printf("%d%c", tab[i], i < size - 1 ? ',' : '\n'); //print unsorted
}
sortujTab(tab, size);
return 0;
}
If the range of numbers doesn't allow such an encoding, then you can declare a structure with two integer elements (one for the original number and one for the sum of its digits), allocate an array for size elements of this structure, and initialize and sort the array using the digit sums as the keys.
You can sort an array of indexes rather than the array with data.
#include <stdio.h>
//poor man's interpretation of sumofdigits() :-)
int sod(int n) {
switch (n) {
default: return 0;
case 5: return 5;
case 11: return 2;
case 1000: return 1;
case 9: return 9;
}
}
void sortbyindex(int *data, int *ndx, int size) {
//setup default indexes
for (int k = 0; k < size; k++) ndx[k] = k;
//sort the indexes
for (int lo = 0; lo < size; lo++) {
for (int hi = lo + 1; hi < size; hi++) {
if (sod(data[ndx[lo]]) > sod(data[ndx[hi]])) {
//swap indexes
int tmp = ndx[lo];
ndx[lo] = ndx[hi];
ndx[hi] = tmp;
}
}
}
}
int main(void) {
int data[4] = {5, 11, 1000, 9};
int ndx[sizeof data / sizeof *data];
sortbyindex(data, ndx, 4);
for (int k = 0; k < sizeof data / sizeof *data; k++) {
printf("%d\n", data[ndx[k]]);
}
return 0;
}

Pascal Triangle in C

So I implemented this Pascal Triangle program in C, and it works well up until the 13th line, where the values onwards are no longer correct. I believe the combination function is correct, a k combination of n elements can be written with factorials, and it says so on the combination Wikipedia page hehe. Here's the code:
#include <stdio.h>
int factorial(int number);
int combination(int n, int k);
int main() {
int lines;
int i, j;
printf("Number of Pascal Triangle lines: ");
scanf("%d", &lines);
for (i = 0; i <= lines; i++) {
for (j = 0; j <= i; j++)
printf("%d ", combination(i, j));
printf("\n");
}
}
int combination(int n, int k) {
int comb;
comb = (factorial(n)) / (factorial(k) * factorial(n - k));
return comb;
}
int factorial(int number) {
int factorial = 1;
int i;
for (i = 1; i <= number; i++)
factorial = factorial * i;
return factorial;
}
Computing Pascal's triangle straight from the binomial formula is a bad idea because
the computation of the factorial in the numerator is overflow-prone,
every computation requires the evaluation of about n products (k + n - k) and a division (plus n! computed once), for a total of n² per row.
A much more efficient solution is by means of Pascal's rule (every element is the sum of the two elements above it). If you store a row, the next row is obtained with just n additions. And this only overflows when the element value is too large to be representable.
In case you only need the n-th row, you can use the recurrence
C(n,k) = C(n,k-1).(n-k+1)/k
This involves 2n additions, n multiplications and n divisions, and can overflow even for representable values. Due to the high cost of divisions, for moderate n it is probably better to evaluate the whole triangle ! (Or just hard-code it.)
If you need a single element, this recurrence is attractive. Use symmetry for k above n/2 (C(n,k) = C(n,n-k)).
Your implementation cannot handle even moderately large values of n because factorial(n) causes an arithmetic overflow for n >= 13.
Here is a simplistic recursive implementation that can handle larger values, albeit very slowly:
#include <stdio.h>
int combination(int n, int k) {
if (n < 0 || k < 0 || k > n)
return 0;
if (k == 0 || k == n)
return 1;
return combination(n - 1, k - 1) + combination(n - 1, k);
}
int main() {
int lines, i, j;
printf("Number of Pascal Triangle lines: ");
if (scanf("%d", &lines) != 1)
return 1;
for (i = 0; i <= lines; i++) {
for (j = 0; j <= i; j++) {
printf("%d ", combination(i, j));
}
printf("\n");
}
return 0;
}
Notes:
This implementation illustrates how vastly inefficient recursive implementations can become.
Since you are printing a complete triangle, you should store intermediary results and compute one full line at a time from the previous line very efficiently, but still limited by the range of unsigned long long, 67 lines.
Here is a faster alternative:
#include <stdio.h>
int main() {
int lines, i, j;
printf("Number of Pascal Triangle lines: ");
if (scanf("%d", &lines) != 1 || lines < 0 || lines > 67)
return 1;
unsigned long long comb[lines + 1];
for (i = 0; i <= lines; i++) {
comb[i] = 0;
}
comb[0] = 1;
for (i = 0; i <= lines; i++) {
for (j = i; j > 0; j--) {
comb[j] += comb[j - 1];
}
for (j = 0; j <= i; j++) {
printf("%llu ", comb[j]);
}
printf("\n");
}
return 0;
}
Hope the following code might help ::
/*elements of the pascal's trianlge for 10 rows*/
#include<stdio.h>
int main()
{
int p[11][11];
int i,j,k;
for(i=1;i<=10;i++)
{
/*creating whitespaces*/
for(k=i;k<=10;k++)
{
printf(" ");
}
for(j=1;j<=i;j++)
{
/*printing the boundary elements i.e. 1*/
if(j==1 || i==j)
{
p[i][j]=1;
printf("%3d ",p[i][j]);
}
/*printing the rest elements*/
else
{
p[i][j]=p[i-1][j-1]+p[i-1][j];
printf("%3d ",p[i][j]);
}
}
printf("\n");
}
}
Thanks

Optimise a code of random number with no repetition in C

I do a code that will display to the screen 10 random numbers with no repetitions. I want to know if we can optimize the code or if you have a better and simple way in order to do this request.
Thanks !!
int main(){
int nbr = 0; srand(time(NULL));
int arr[10], i, j, flag;
for (i = 0; i < 10; i++)
{
do
{
nbr = rand() % 10 + 1;
flag = 1;
for (j = 0; j < i; j ++)
{
if (nbr == arr[j])
{
flag = 0;
break;
}
}
} while (!flag);
arr[i] = nbr;
}
for (i = 0; i < 10; i++)
{
printf("%5d", arr[i]);
}
system("PAUSE");
return 0;
}
So if i get what you're trying to do here it is:
generate an array of numbers between 1 and 10, in a random order (given rand() % 10 + 1)
instead of trial and error I'd suggest the following algorithm:
fill arr with 1...10
shuffle arr
this will run a lot faster
While I agree with the solution provided by Work of Artiz, this will result in the hard question to answer of when to stop shuffling.
To solve this you can use the following solution (which will use more memory, but less clock time):
1 Create an array temp having values 1..10 (ordered, not random)
2 Keep track of the length length of the array (10)
3 Generate a random index rand_i between 0 and length - 1
4 Copy temp[rand_i] to next position in your final array
5 Overwrite temp[rand_i] by temp[length-1]
6 Decrement length
7 Iterate Steps 3 - 6 until your array is filled (10 times)
This will both eliminate your excessive looping, and the problem of when to stop shuffling your array
EDIT: including code
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main(){
int nbr = 0; srand(time(NULL));
int arr[10], i, j, flag;
int temp[10] = {1,2,3,4,5,6,7,8,9,10};
int length = 10;
for (i = 0; i < 10; i++)
{
nbr = rand() % length; // Generate random index between 0 and length - 1
arr[i] = temp[nbr]; // Copy value from random index in temp to next index in arr
// Now since temp[nbr] is already taken (copied to arr) we should replace it by last available value in temp (temp[lenght])
// and in the next iteration we will create a value between 0 and length -1. This will keep values not yet taken from temp in
// contiguous order
temp[nbr] = temp[length-1];
length--;
}
for (i = 0; i < 10; i++)
{
printf("%5d", arr[i]);
}
return 0;
}

c programming - printing sequence of sum of squared digits (as an array) for a potential happy number

I have this assignment for my intro to C programming class and part of my code has to find the sequence of the sum of square digits of a number in order to determine after if the given number is a happy number (sum of square digits = 1)
Here's part of my code:
#include <stdio.h>
#include <math.h>
// The sum of square digits function
int sqd (int x) {
int sum = 0;
while (x > 0) {
sum = sum + pow(x%10, 2);
x = x/10;
}
return sum;
}
// The search function
int search (int a[], int val, int size) {
int i;
for (i = 0; i < size; i++) {
if (a[i] == val) {
return 1;
}
}
return 0;
}
// The main program
void main () {
int a [1000] = {0};
int N;
int count = 1;
int j;
printf("Please enter the potential happy number:\n", N);
scanf ("%d", &N);
a[0] = N;
a[count] = sqd (N);
do {
a[count] = sqd (a[count-1]);
count++;
} while (search (a, a[count], count));
for ( j = 0; j <= count; j++) {
printf("%d\n", a[j]);
}
}
It only prints the first three sums in the sequence. I really don't know how to make it work.
Thank you in advance
This line
while (search (a, a[count], count));
makes sure that you break out of the loop after one round since a[1] is not equal toa[0]. You can change that line to be:
while (a[count-1] != 1);
You also need to add a clause to make sure that you stop when the limit of the array is reached. Update that line to be:
while (a[count-1] != 1 && count < 1000 );
And then, change the printing loop to use i < count, not i <= count. Using <= will result in accessing the array out of bounds when the user enters a sad number.
for ( j = 0; j < count; j++){
printf("%d\n", a[j]);
}
Update
After a bit of reading on happy numbers at Wikipedia, I understand why you had call to search in the conditional of the while. The following also works.
} while ( ! (a[count-1] == 1 || search(a, a[count-1], count-1)) );
That will search for the last number in the array but only up to the previous index.

Resources