There are many implementations of the Sieve of Eratosthenes online. Through searching Google, I found this implementation in C.
#include <stdio.h>
#include <stdlib.h>
#define limit 100 /*size of integers array*/
int main(){
unsigned long long int i,j;
int *primes;
int z = 1;
primes = malloc(sizeof(int) * limit);
for (i = 2;i < limit; i++)
primes[i] = 1;
for (i = 2;i < limit; i++)
if (primes[i])
for (j = i;i * j < limit; j++)
primes[i * j] = 0;
printf("\nPrime numbers in range 1 to 100 are: \n");
for (i = 2;i < limit; i++)
if (primes[i])
printf("%d\n", i);
return 0;
}
I then attempted to update the existing code so that the C program would follow what is described by Scott Ridgway in Parallel Scientific Computing. In the first chapter, the author describes what is known as the Prime number sieve. Instead of finding the primes up to a number k, the modified sieve searches for primes between k <= n <= k^2. Ridgway provides the psuedocode to write this algorithm.
To match the psuedocode provided by the author, I modified the original program above and wrote
#include <stdio.h>
#include <stdlib.h>
#define limit 10 /*size of integers array*/
int main(){
unsigned long long int i,j,k;
int *primes;
int *arr[100];
int z = 1;
primes = malloc(sizeof(int) * limit);
for (i = 2;i < limit; i++)
primes[i] = 1;
for (i = 2;i < limit; i++)
if (primes[i])
for (j = i;i * j < limit; j++)
primes[i * j] = 0;
/* Code which prints out primes for Sieve of Eratosthenes */
/*printf("\nPrime numbers in range 1 to 100 are: \n");
for (i = 2;i < limit; i++)
if (primes[i])
//printf("Element[%d] = %d\n", i, primes[i]);*/
for (k=limit; k < limit*limit; k++)
for (j = primes[0]; j = arr[sizeof(arr)/sizeof(arr[0]) - 1]; j++)
if ((k % j) == 0)
arr[k]=0;
arr[k] = 1;
printf("\nPrime numbers in range k to k^2 are: \n");
for (k=limit; k < limit*limit; k++)
if (arr[k])
printf("Element[%d] = %d\n", k, k);
return 0;
}
which returns
Prime numbers in range k to k^2 are:
Element[10] = 10
Element[14] = 14
Element[15] = 15
Element[16] = 16
Element[17] = 17
Element[18] = 18
Element[19] = 19
.
.
.
This is clearly wrong. I think that my mistake is in my interpretation of the psuedocode
as
for (k=limit; k < limit*limit; k++)
for (j = primes[0]; j = arr[sizeof(arr)/sizeof(arr[0]) - 1]; j++)
if ((k % j) == 0)
arr[k]=0;
arr[k] = 1;
As I am new to C, I likely made an elementary mistake. I'm not sure what is wrong with the five lines of code above and have therefore asked a question on Stack Overflow.
You have some problem with your loop statement, j variable should use for index of primes that is pointer to array of int with 0 or 1 values. You can use primes array in this case is S(k) in algorithm.
for (k=limit; k < limit*limit; k++)
for (j = primes[0]; j = arr[sizeof(arr)/sizeof(arr[0]) - 1]; j++)
if ((k % j) == 0)
arr[k]=0;
arr[k] = 1;
So the for loop with j should be
for (j = 2; j < limit; j++)
And condition IN if statement should be
if (primes[j] && (k % j) == 0)
{
arr[k] = 0;
break;
}
And if this condition is true, we should exit inner for loop with j variable. Outside for loop with j, should check value of j variable to check if the inner loop is completed or not (j == limit).
if (j == limit) arr[k] = 1;
So here is the entire for loop (outer and inner loop) the I modified.
for (k = limit; k < limit*limit; k++)
{
for (j = 2; j < limit; j++)
{
if (primes[j] && (k % j) == 0)
{
arr[k] = 0;
break;
}
}
if (j == limit) arr[k] = 1;
}
And here is entire solution:
#include <stdio.h>
#include <stdlib.h>
#define limit 10 /*size of integers array*/
int main() {
unsigned long long int i, j, k;
int *primes;
int arr[limit*limit];
int z = 1;
primes = (int*)malloc(sizeof(int) * limit);
for (i = 2; i < limit; i++)
primes[i] = 1;
for (i = 2; i < limit; i++)
if (primes[i])
for (j = i; i * j < limit; j++)
primes[i * j] = 0;
/* Code which prints out primes for Sieve of Eratosthenes */
/*printf("\nPrime numbers in range 1 to 100 are: \n");
for (i = 2;i < limit; i++)
if (primes[i])
//printf("Element[%d] = %d\n", i, primes[i]);*/
for (k = limit; k < limit*limit; k++)
{
for (j = 2; j < limit; j++)
{
if (primes[j] && (k % j) == 0)
{
arr[k] = 0;
break;
}
}
if (j == limit) arr[k] = 1;
}
printf("\nPrime numbers in range k to k^2 are: \n");
for (k = limit; k < limit*limit; k++)
if (arr[k] == 1)
printf("Element %d\n", k);
return 0;
}
Related
Im trying to sort a matrix by the sum of its row's digits, from highest to lowest. I dont know if i explained that correctly so here's some photos explaining it.
This is what my code outputs. Basically, it asks you for m and n, which are the dimensions of the matrix. In this example it's a 3x4, 3 rows and 4 columns. Then, the matrix should be sorted by rows, by the sum of row's digits. Which means, instead of what's being outputted in the picture above, the correct result should be this:
I have no idea how to sort this from highest to lowest, i have been trying for hours to no avail.
Here's my code:
#include <stdio.h>
#define N 30
void main(){
double a[N][N], s[N], p;
int i, j, m, n, max;
while(1){
printf("\nm, n? ");
scanf("%d%d", &m, &n);
if(m <= 0 || m > N || n <=0 || n > N)
break;
for(i = 0; i < m; i++){
printf("%2d. row? ", i+1);
for(j = 0; j < n; scanf("%lf", &a[i][j++]));
}
for(i = 0; i < m; i++)
for(s[i] = j = 0; j < n; s[i] += a[i][j++]);
for(j = 0; j < n - 1; j++){
for(max = i, j = i+1; j < n; j++)
if(s[j] > s[max])
max = i;
if(max != j){
p = s[j];
s[j] = s[max];
s[max] = p;
for(j = 0; j < m; j++){
p = a[j][i];
a[j][i] = a[j][max];
a[j][max] = p;
}
}
}
printf("New matrix: \n");
for(i = 0; i < m; i++){
for(j = 0; j < n; printf("%8.2lf", a[i][j++]));
printf("\n");
}
for(j = 0; j < m; j++)
printf("-------------");
printf("\n");
for(j = 0; j < m; printf("%8.2f \n", s[j++]));
printf("\n");
}
}
You can sort the rows of the matrix from highest to lowest, using a simple bubble sort algorithm.Your code modified below:
int main() {
double a[N][N], s[N], p;
int i, j, m, n, max;
while (1) {
printf("\nm, n? ");
scanf("%d%d", & m, & n);
if (m <= 0 || m > N || n <= 0 || n > N)
break;
for (i = 0; i < m; i++) {
printf("%2d. row? ", i + 1);
for (j = 0; j < n; scanf("%lf", & a[i][j++]));
}
for (i = 0; i < m; i++)
for (s[i] = j = 0; j < n; s[i] += a[i][j++]);
for (i = 0; i < m - 1; i++) { // modified here
for (j = i + 1; j < m; j++) { // modified here
if (s[j] > s[i]) { // modified here
p = s[i];
s[i] = s[j];
s[j] = p;
for (int k = 0; k < n; k++) {
p = a[i][k];
a[i][k] = a[j][k];
a[j][k] = p;
}
}
}
}
printf("New matrix: \n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; printf("%8.2lf", a[i][j++]));
printf("\n");
}
for (j = 0; j < m; j++)
printf("-------------");
printf("\n");
for (j = 0; j < m; printf("%8.2f \n", s[j++]));
printf("\n");
}
return 0;
}
Here's how i modified your code to achieve that:
Initialize a loop variable i to 0.
In the outer loop, run the inner loop j from i+1 to m-1.
In the inner loop, compare the sum of the row i with the sum of row
j. If the sum of row j is greater than the sum of row i, swap the
rows using a temporary variable.
After the inner loop finishes, increment the value of i by 1. Repeat
the outer loop until i becomes equal to m-1.
Output:
You can just use qsort to let it handle the sorting and item swapping. Then you only need to write the code for comparing two rows with each other.
Given something like this:
int matrix[3][4] =
{
{1,2,3,4},
{5,6,7,8},
{9,1,2,3},
};
You'd call qsort as:
qsort(matrix, 3, sizeof(int[4]), compare);
The only complexity is implementing the comparison callback function. There's two things to consider there:
We've told qsort that we have an array of 3 items, each of type int[4]. So the void pointers it passes along to us will actually be pointers to type int[4]. That is: int(*)[4].
qsort sorts in ascending order by default, where the item considered "less" ends up first. So we need to tweak that to get the largest item first.
Example:
int compare (const void* obj1, const void* obj2)
{
const int (*ptr1)[4] = obj1;
const int (*ptr2)[4] = obj2;
size_t sum1=0;
size_t sum2=0;
for(size_t i=0; i<4; i++)
{
sum1 += (*ptr1)[i];
sum2 += (*ptr2)[i];
}
if(sum1 > sum2) // largest sum considered "less" for qsort
return -1;
else
return 1;
return 0;
}
sum1 < sum2 would have placed the smallest row first.
Full example:
#include <stdio.h>
#include <stdlib.h>
int compare (const void* obj1, const void* obj2)
{
const int (*ptr1)[4] = obj1;
const int (*ptr2)[4] = obj2;
size_t sum1=0;
size_t sum2=0;
for(size_t i=0; i<4; i++)
{
sum1 += (*ptr1)[i];
sum2 += (*ptr2)[i];
}
if(sum1 > sum2) // largest sum considered "less" for qsort
return -1;
else
return 1;
return 0;
}
void print_matrix(size_t col, size_t row, int matrix[col][row])
{
for(size_t i=0; i<col; i++)
{
for(size_t j=0; j<row; j++)
{
printf("%d,", matrix[i][j]);
}
puts("");
}
}
int main (void)
{
int matrix[3][4] =
{
{1,2,3,4},
{5,6,7,8},
{9,1,2,3},
};
print_matrix(3,4,matrix);
puts("");
qsort(matrix, 3, sizeof(int[4]), compare);
print_matrix(3,4,matrix);
}
I am doing the following problem:
Giving the sequence a consisting of n integer numbers and the sequence b consisting of m integer numbers, two sequences are arranged in increasing order. Combining two above sequences into a new sequence c such that c is also an increasing sequence. Printing c.
Input:
3
1 3 4
4
1 2 3 5
Output:
1 1 2 3 3 4 5
My idea is first combining two sequences into sequence c, then sorting sequence c in increasing order. This is my code:
#include <stdio.h>
int main() {
//Inputting sequence a and b
int n, m;
int a[1001], b[1001];
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
scanf("%d", &m);
for (int i = 0; i < m; i++) {
scanf("%d", &b[i]);
}
//Combine two sequence into c
int c[1001];
for (int i = 0; i < n; i++) {
c[i] = a[i];
}
for (int i = 0; i < m; i++) {
c[i + n] = b[i];
}
//Arrange sequence c in increasing order
int mid;
for (int i = 0; i < (n + m - 1); i++) {
for (int j = 1; j < (n + m); j++) {
if (c[i] > c[j]) {
mid = c[i];
c[i] = c[j];
c[j] = mid;
}
}
}
//Printing c
for (int i = 0; i < (n + m); i++) {
printf("%d ", c[i]);
}
return 0;
}
However, when I test with the test case [1,2,4],[1,2,5], the result is 1 4 2 2 1 5. Can anyone point out the error in my code? I truly appreciate that.
It is wrong to search for the minimum value in the range of 1 to n+m-1 regardless of the value i. This may move the minimum value to the latter part of the array.
The line
for (int j = 1; j < (n+m); j++)
should be
for (int j = i + 1; j < (n+m); j++)
To merge 2 sorted arrays, you can write 3 loops as in the classic implementation of mergesort:
#include <stdio.h>
int main() {
//Inputting sequence a and b
int a[1000], b[1000], c[2000];
int n, m, i, j, k;
if (scanf("%d", &n) != 1 || n <= 0 || n > 1000)
return 1;
for (i = 0; i < n; i++) {
if (scanf("%d", &a[i]) != 1)
return 1;
}
if (scanf("%d", &m) != 1 || m <= 0 || m > 1000)
return 1;
for (i = 0; i < m; i++) {
if (scanf("%d", &b[i]) != 1)
return 1;
}
//Combine both sequences into c
i = 0, j = 0, k = 0;
while (i < n && j < m) {
if (a[i] <= b[j])
c[k++] = a[i++];
else
c[k++] = b[j++];
}
while (i < n) {
c[k++] = a[i++];
}
while (j < m) {
c[k++] = a[j++];
}
//Printing c
for (i = 0; i < n + m; i++) {
printf("%d ", c[i]);
}
printf("\n");
return 0;
}
I want to do generate 7 different number (0-9) - first digit should not be 0- and put them into an array. Every number should be unique. I know what I did wrong but I dont know what should I do.
int arr[7], j, i;
srand(time(NULL));
for (i = 0; i < 7; i++)
{
arr[i] = rand() % 10;
if (arr[0] == 0)
arr[0] = rand() % 10;
}
for (i = 0; i < 7; i++)
{
for (j = 0; j < 7; j++)
{
if (i == j) {
j++;
}
if (arr[i] == arr[j])
arr[j] = rand() % 10;
}
}
printf("\n");
for(j=0;j<7;j++)
printf("\n%d ", arr[j]);
You can use rand() % 9 + 1 to produce random number between 1 and 9.
arr[j] may be out-of-range after j++;.
Try this:
int arr[7], j, i;
srand(time(NULL));
arr[0] = rand() % 9 + 1; /* decide first number with special formula */
for (i = 1; i < 7; i++) /* decide the rest numbers */
{
int dupe = 0;
arr[i] = rand() % 10;
for (j = 0; j < i; j++) /* check against numbers that already decided */
{
if (arr[i] == arr[j])
dupe = 1; /* ouch, this number is already used! */
}
if (dupe)
i--; /* if the number is already used, try again */
}
printf("\n");
for(j=0;j<7;j++)
printf("\n%d ", arr[j]);
I'm coding a function in C to check if an array has any duplicate value, and if so replace it by any of the non-present ones. The array consists of numbers shuffled from 1 to Nmax:
unsigned char * NotRepeated (unsigned char *arr){
unsigned char i, j, count, k, notrepeated[Nmax];
k = 0;
for (i = 0; i < Nmax ; i++){
count = 0;
for (j = 0; j < Nmax; j++){
if (arr[j] != i + 1){
count++;
}
if (count == Nmax){
notrepeated[k] = i + 1;
k++;
}
}
}
k = 0;
for (i = 0; i < Nmax - 1; i++){
for (j = i + 1; j < Nmax; j++){
if (arr[i] == arr[j]){
arr[j] = notrepeated[k];
k++;
}
}
}
return arr
}
If I print the array notrepeated[k] I get almost all the array filled when the original array arr[j] seldomly has more than 2 repeated figures.
What am I doing wrong?
Thanks!
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
#include <stdio.h>
main()
{
int x, y;
scanf("%d", &x);
int a[x][x];
int i, j, low = 0, top = x - 1, n = 1;
for (i = 0; i < x / 2; i++, low++, top--)
{
for (j = low; j <= top; j++, n++)
a[i][j] = n;
for (j = low + 1; j <= top; j++, n++)
a[j][top] = n;
for (j = top - 1; j >= low; j--, n++)
a[top][j] = n;
for (j = top - 1; j > low; j--, n++)
a[j][low] = n;
}
for (i = 0; i < x; i++)
{
for (j = 0; j < x; j++)
{
printf("%d", a[i][j]);
}
printf("\n");
}
}
i want to write a number pattern and this is the code but i wanted to write it without arrays.how can i rewrite this without using any arrays?
and of course x can be both even and odd.
thanks for ur help!]1
#include <stdio.h>
int get(int x, int y, int lt, int n)
{
if(x == 0)
return lt+y;
else if(y == 0)
return lt+4*(n-1)-x;
else if(y == n-1)
return lt+n+x-1;
else if(x == n-1)
return lt+3*(n-1)-y;
else
return get(x-1, y-1, lt+4*(n-1), n-2);
}
int main(void)
{
int n, i, j;
scanf("%d", &n);
for(i = 0; i < n; ++i) {
for(j = 0; j < n; ++j)
printf("%2d ", get(i, j, 1, n));
putchar('\n');
}
return 0;
}
I must agree that this code is incredible difficult for me to understand. I have no clue what is happening here. But I will try to answer it irrespective of the logic/pattern.
So you have a bunch of loops that fill in an array and then another loop that prints it in order. But you don't want to use arrays.
So the value should be calculated when it is to be printed. Let us try it this way -
First I will move your calculating code to a separate function for sake for clarity -
int value_at(int I, int J, int x) {
int i, j, low = 0, top = x - 1, n = 1;
int a = 0;
for (i = 0; i < x / 2; i++, low++, top--) {
for (j = low; j <= top; j++, n++)
if ( i == I && j == J)
a = n;
for (j = low + 1; j <= top; j++, n++)
if ( I == j && J == top)
a = n;
for (j = top - 1; j >= low; j--, n++)
if ( top == I && j == J)
a = n
for (j = top - 1; j > low; j--, n++)
if (j == I && low == J)
a = n;
}
return a;
}
Now this function calculates the value of a for any i or j
Now we can just print the values in a loop -
for (i = 0; i < x; i++)
{
for (j = 0; j < x; j++)
{
printf("%d", value_at(i, j, x));
}
printf("\n");
}
This must do the task :
int min(int a, int b)
{
return a<b ? a:b;
}
void printSpiral(int n)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
int x;
x = min(min(i, j), min(n-1-i, n-1-j));
// For upper right half
if (i <= j)
printf("%d ", ((n*n) - ((n-2*x)*(n-2*x) - (i-x)
- (j-x)))+1);
// for lower left half
else
printf("%d ", ((n*n) - ((n-2*x-2)*(n-2*x-2) + (i-x)
+ (j-x)))+1);
}
printf("\n");
}
}
Just call printSpiral() and pass your x as argument