Prime numbers in c language - c

I want to find prime numbers with multithreading and using Sieve of E. function.I write some piece of codes. If the program will run, the user enter a max number and thread number. The program should create threads that given thread number. The program find all prime numbers until the max number. Each thread must check one prime number.
My program doesn't find prime numbers. I write checkPrime function and crossout functions for finding prime numbers efficiently. But it doesn't work. So, I can't check my threads work correctly or not. How can I implement checkPrime function?
There are 3 functions. crossout is for Sieve E. method. checkPrime is for checking is a number prime or not. worker is for thread's function. Each thread must check one prime number.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#define MAX_N 100000000
#define MAX_THREADS 25
// global values
int threadNumber;
int largestNumber;
int isPrime;
int nthreads, // number of threads (not counting main())
prime[MAX_N + 1],
n, // in the end, prime[i] = 1 if i prime, else 0
nextbase; // next sieve multiplier to be used
// lock for the shared variable nextbase
pthread_mutex_t nextbaselock = PTHREAD_MUTEX_INITIALIZER;
void crossout(int a) {
int i, j, check;
for (i = 2; i < largestNumber; i++)
prime[i] = 1;
for (i = a; i < largestNumber;)
if (prime[i])
for (j = i; i * j < largestNumber; j++)
prime[i * j] = 0;
}
int checkPrime(int a) {
int i;
for (i = 2; i <= a; ++i) {
if (a % i == 0) {
isPrime = 1;
return isPrime;
break;
} else
isPrime = 2;
crossout(a);
return isPrime;
}
}
void* workerThread(void* t) {
int lim, base;
long i, j;
long tid;
tid = (long)t;
printf("Thread %ld starting...\n", tid);
while (1) {
pthread_mutex_lock(&nextbaselock);
base = nextbase;
nextbase++;
// unlock the lock
pthread_mutex_unlock(&nextbaselock);
if (base <= lim) {
if (prime[base]) {
checkPrime(base);
// log work done by this thread
}
}
if (checkPrime(base) == 2)
printf("Thread %ld done. Prime = %d\n", tid, base);
pthread_exit((void*) t);
}
return NULL;
}
//main function with two parameters :argc and argv
int main(int argc, char** argv) {
threadNumber = argv[3];
largestNumber = argv[1];
int i;
pthread_t thread[threadNumber];
int rc;
long t;
void* status;
for (t = 0; t < threadNumber; t++) {
printf("Main: creating thread %ld\n", t);
rc = pthread_create(&thread[t], NULL, workerThread, (void*)t);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
for (t = 0; t < threadNumber; t++) {
rc = pthread_join(thread[t], (void*)&t);
if (rc) {
printf("ERROR; return code from pthread_join() is %d\n", rc);
exit(-1);
}
printf("Main: completed join with thread %ld \n", t);
}
}

You are trying to mix two different methods for finding prime numbers. You don't need to use both the iterative division method and the sieve of Eratosthenes. This shows a way of implementing the sieve. Even numbers are ignored in the sieve but treated as special cases in isprime(). But it won't help you find a multi threaded solution, because you can't just hand over different numbers to different threads - each prime builds on the work of the previous prime, starting with the assumption that 3 is prime.
// Sieve of Eratosthenes
#include <stdio.h>
#include <stdlib.h>
#define LIMIT 200
char sieve[LIMIT] = { 1, 1, }; // 1 for not-prime
int isprime(unsigned n)
{
if(n <= 2) // special cases
return sieve[n] == 0;
if(n % 2 == 0) // even numbers are not prime
return 0;
if(n >= LIMIT) // test range
exit(1);
return sieve[n] == 0;
}
int main(void)
{
unsigned n, p;
for(n=3; n<LIMIT; n+=2) { // odd numbers only
if (sieve[n] == 0) { // if n is prime
for(p=n*n; p<LIMIT; p+=n*2) { // ignore even numbers
sieve[p] = 1; // not primne
}
}
}
printf("Prime numbers are:\n");
for(n=0; n<LIMIT; n++) { // check all numbers
if (isprime(n)) { // if n is prime
printf("%-4d", n);
}
}
printf("\n");
return 0;
}
Program output:
Prime numbers are:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199
I'll now show an iterative division method. Once again, even numbers are treated as special cases. I don't often write multi threaded C code, so I can't help you with that. But I hope you can build on this second example to make a multi threaded solution.
// iterative division
#include <stdio.h>
#include <math.h>
#define LIMIT 200
int isprime(unsigned n)
{
unsigned s, i;
if(n <= 1)
return 0;
if(n == 2)
return 1;
if(n % 2 == 0) // no even numbers
return 0;
s = (unsigned)sqrt(n); // limit the loop
for(i=3; i<=s; i+=2) // odd numbers only
if (n % i == 0)
return 0;
return 1;
}
int main(void)
{
unsigned n;
printf("Prime numbers are:\n");
for(n=0; n<LIMIT; n++) { // check all numbers
if (isprime(n)) { // if n is prime
printf("%-4d", n);
}
}
printf("\n");
return 0;
}
Program output:
Prime numbers are:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199
There are some pitfalls in both of the above examples when working with larger numbers, but I'll leave them for you to discover.

This is modified version of Sieve of Eratosthenes which is the very simple, interesting and fast. Understand its working as I have tried to explain it using comments. Actually try to understand the run-time allocation of array size to avoid defining a large MAX value and try to code simple by analyzing your algorithm and applying good mathematics along with smart coding knowledge.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main()
{
int *arr;
int count=0,i=3,j,n;
arr=(int*)malloc(count+1*sizeof(int)); //set array size to 1
arr[count++]=2; //stored 2 as array first element
printf("Find all prime numbers upto :: ");
scanf("%d",&n); //n is the number up to which prime numbers are required
here:
{
while(i<=n) //start with i=3
{
j=0;
while(arr[j]<=sqrt(i)) //till array element value is less than or equal to root of number under checking
{
if(i%arr[j]!=0) //if remainder is not zero check divisibility with next array element
j++;
else
{
i++; //if remainder is zero then start checking for another number
goto here;
}
}
printf("%d, ",arr[count-1]); //printing the number which was proved as prime last time
arr=(int *)realloc(arr,(count+1)*sizeof(int)); //increasing array size by 1
arr[count++]=i; //newly proved prime is stored as next array element
i++;
}
printf("%d, ",arr[count-1]); //print last number proved as prime
}

Related

Why is it returning 1? Generating all prime numbers in a range specified by the user in C

I have to complete the function prime in order to the function main generate all prime numbers in a range specified by the user, but when I run the code specifying 1 as minimum and 100 as maximum it returns 1 with all the prime numbers.
How can I get rid of 1, once, by definition, 1 is not a prime number?
#include <cs50.h>
#include <stdio.h>
bool prime(int number);
int main(void)
{
int min;
do
{
min = get_int("Minimum: ");
}
while (min < 1);
int max;
do
{
max = get_int("Maximum: ");
}
while (min >= max);
for (int i = min; i <= max; i++)
{
if (prime(i))
{
printf("%i\n", i);
}
}
}
bool prime(int number)
{
// TODO
int j;
for (j = 2; j <= number - 1; j++)
{
if (number % j == 0)
{
return false;
}
}
return number;
}
Minimum: 1
Maximum: 100
1
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97
I would say that the simplest solution would be to add a test at the beginning of your prime function to indicate that any value less than "2" would yield a "false" Boolean value. With that, here is a simple refactoring of the function.
bool prime(int number)
{
// TODO
if (number < 2) /* Exit gracefully if a minimum value of 1 or less is entered */
{
return false;
}
int j;
for (j = 2; j <= number - 1; j++)
{
if (number % j == 0)
{
return false;
}
}
return true; /* Technically returning a value greater than zero will equate to true, but it is better to return "true" */
}
Also, note the revision of the final return statement in the function. Technically, any integer value greater than zero will be treated as a Boolean "true" value, it would be best to return the Boolean "true" value there so to be clear to anyone reading the code.
See if that meets the spirit of your project.

Calculate maximum path cost for a matrix in C

I am learning c and encountered maximum cost path question in which
Rules:
matrix is n x n size
Starting from the cell (bottommost leftmost cell), you want to go to the topmost
rightmost cell in a sequence of steps. In each step, you can go either right or up from
your current location.
I tried to solve using dynamic programming and this is the function I have written
computecost(int *utr,int n)//utr is the input matrix
{
int *str;
int i,j;
str=(int *)malloc(n*n*sizeof(int));
for(j=0;j<n;j++)//intialization of bottom row
{
str[n*(n-1)+j]=utr[n*(n-1)+j];
}
for(i=n-2;i>=0;i--)
{
for(j=0;j<n;j++)
{
str[n*i+j]=utr[n*i+j]+max(str[n*(i+1)+j],str[n*(i+1)+(j+1)]);
}
}
printf("%d",str[n*0+0]);
return 0;
}
and this is the input
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&str[n*i+j]);
}
}
but
for the matrix 5 x5
1 4 8 2 9
32 67 18 42 1
4 86 12 7 1
8 4 12 17 44
1 43 11 45 2
the desired output is 272 but I am getting 211.
the output matrix for my case
1 43 11 45 2
51 47 57 62 46
55 143 74 69 47
175 210 92 111 52
211 214 119 113 64
Can anyone help me?
You don't need dynamic programming for this since there are no overlapping sub-problems. Just use a simple recursion.
const int n = 5;
int mat[n][n] = {
{1,4,8,2,9},
{32,67,18,42,1},
{4,86,12,7,1},
{8,4,12,17,44},
{1,43,11,45,2}
}; // input matrix
int f(int x, int y, int sum){
if(x == 0 && y == 4)
return sum;
int p = 0, q = 0;
if(x - 1 >= 0)
p = f(x-1, y, sum + mat[x-1][y]);
if(y + 1 <= 4)
q = f(x, y+1, sum+mat[x][y+1]);
return max(p,q);
}
int main(){
int maxSum = f(4,0, mat[4][0]);
printf("%d\n", maxSum);
}
You were not very far to succeed.
In practice, you did not initialize correctly the bottom row.
Moreover, there was a little mistake in the iteration calculation.
This is the corrected code.
As said in a comment, it could be further simplified, by avoiding the use of a new array, simply updating the input array.
#include <stdio.h>
#include <stdlib.h>
int max (int a, int b) {
return (a > b) ? a : b;
}
int computecost(int *utr,int n) { //utr is the input matrix
int *str;
str = malloc (n*n*sizeof(int));
str[n*n - 1] = utr[n*n - 1];
for (int j = n-2; j >= 0; j--) { //intialization of bottom row {
str[n*(n-1)+j] = utr[n*(n-1)+j] + str[n*(n-1)+j+1]; // corrected
}
for (int i=n-2; i>=0; i--) {
str[n*i+n-1] = utr[n*i+n-1] + str[n*(i+1)+n-1];
for(int j = n-2; j >= 0; j--) {
str[n*i+j] = utr[n*i+j] + max(str[n*(i+1)+j],str[n*i + j+1]); // corrected
}
}
int cost = str[0];
free (str);
return cost;
}
int main() {
int A[25] = {
1,43,11,45,2,
8,4,12,17,44,
4,86,12,7,1,
32,67,18,42,1,
1,4,8,2,9
};
int ans = computecost (A, 5);
printf ("%d\n", ans);
return 0;
}

How do I queue numbers in Numbers.txt? and if the tens digit is 0, how do I print 1 in the tens digit?

Random numbers are printed in "numbers.txt". "numbers.txt" exists as a single line. The values here will be taken as two digits and assigned to the queue. I'm having trouble with the while part.
When the numbers in the Numbers.txt file are separated by two digits, I want to make the 0 in the tens digit a 1.
Example
numbers.txt :
839186660286459132876040232609
Output:
two-digit
83 91 86 66 2 86 45 91 32 87 60 40 23 26 9.
As you can see 02 and 09 written as 2 and 9. i want to 12 and 19.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 30
typedef struct stack
{
int value;
} Stack;
int *first, *last, *queue;
void kuyrukList()
{
printf("\nKuyruktaki Elemeanlar\n");
int *temp = first;
while (temp < last)
{
printf("%d ", *temp);
temp++;
}
}
void insert(int value)
{
*last = value;
last++;
}
int main()
{
//Random number.
srand(time(NULL));
int text[30] = {0};
FILE *dosyaYaz = fopen("numbers.txt", "w");
printf("\nOlusturulan number degeri:\n");
for (int i = 0; i < SIZE; i++)
{
text[i] = (rand() % 10);
printf("%d", text[i]);
fprintf(dosyaYaz, "%d", text[i]);
}
fclose(dosyaYaz);
printf("\n ");
//***********************************
char ch;
int number = 0;
int counter = 1;
queue = (int *)malloc(sizeof(int) * SIZE);
first = queue;
last = queue;
FILE *dosyaAc = fopen("numbers.txt", "r");
if (dosyaAc == NULL)
{
printf("\nDosya bulunamadi.\n");
exit(0);
}
while ((ch = fgetc(dosyaAc)) != -1)
{
if (counter % 2 == 1)
{
number += (ch - '0') * 10;
}
if (counter % 2 == 0)
{
number += (ch - '0');
insert(number);
number = 0;
}
counter++;
}
fclose(dosyaAc);
kuyrukList();
return 0;
}
So you are creating random numbers, but afterwards you modify them when they are smaller than 10? The easiest solution is to create random numbers who only vary from 10 to 99. This can be done as follows:
Imagine that double rand() generates a random number from 0 to 1 (both never being generated).
Then, 90 * rand() generates a random number from 0 to 90 (both never being generated).
Then, 10 + 90 * rand() generates a random number from 10 to 100 (both never being generated).
Then, (int)(10 + 90 * rand()) generates a random natural number, from 10 to 99 (both might be generated because of the rounding mechanism).
It appears from your stated goals that an array of 15 numbers ranging from 10 - 99 is the need. If that is true, skip writing to a file, and reading them back as a intermediate step and just create an array of 15, two digit numbers directly.
To do this, consider using a function to accept range and offset parameters (upper and lower values) and an array sized for each of the values to use with configuring rand(),.
The following can serve as the core of what you are doing by generating an array of pseudo randoms in the range you specify:
//generate an array of pseudo random values between lower and upper values
void gen_rand(int lower, int upper, int count, int *arr)
{
int i;
for (i = 0; i < count; i++)
{
arr[i] = (rand() % (upper - lower + 1)) + lower;
}
}
int main(void)
{
int arr[15];
srand(time(NULL));
gen_rand(10, 99, 15, arr);
return 0;
}

Read numbers in file and find Median C

I am constructing a C program which prints Fibonacci numbers into a file and finds the median.
The output I am getting is a very large and incorrect number. Any insight would be great.
Median Function C
int findMedian(FILE *file, int size)
{
int medianPos, medianVal, readVal, count;
medianPos = (size / 2);
count = 0;
while(fscanf(file,"%d", &readVal)==1)
{
if(medianPos == count)
{
medianVal = readVal;
}
if ((medianPos += 1) == count)
{
if(size % 2) //This means that it is even
{
}
else
{
medianVal += readVal;
medianVal /= 2;
}
}
count++;
}
return medianVal;
}
File
1 1 2 3
5 8 13 21
34 55 89 144
233 377 610 987
1597 2584 4181 6765
Output
The Fibonacci median: -1576638118
Function Call
median = findMedian(Fibonacci, size);
Your 'count' variable is not initialized. So it is possible that your if conditions will not be met and your medianVal remain uninitialized too.

How to make a copy of an array in this code and use it

So I have this code that randomly generates an integer array based on user input, and puts the elements in ascending and descending order. However, currently, the code only prints the descending order twice. So I would like to know how to make a copy of the array ascd and use the copy in the piece of code that organizes the descending order. I am just a beginner, so I apologize if this is a silly question, and appreciate all the guidance I can get. Here is my code:
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
int main (){
int x;
printf("Enter the size of your array\n");//User is entering number of elements
scanf("%d", &x);
int ascd[x]; //Array
int c;
int d;
int e;
int kk = 0;
int temp;
int tempother;
int turtle;
for(c = 0; c<x; c++){//Randomly generating elements
srand(time(0));
ascd[kk] = (rand() %100) + 1;
}
for(c = 0; c<x; c++){ //Ascending order
for(d = 0; d<(x-c-1); d++){
if(ascd[d] > ascd[d+1]){
temp = ascd[d];
ascd[d] = ascd[d+1];
ascd[d+1] = temp;
}
}
}
for(turtle = 0; turtle<x; turtle++){//Descending order
for(e = 0; e<(x-turtle-1); e++){
if(ascd[e] < ascd[e+1]){
tempother = ascd[e];
ascd[e] = ascd[e+1];
ascd[e+1] = tempother;
}
}
}
printf("The ascending order is\n\n");
for(c = 0; c<x; c++){
printf("%d\n", ascd[c]);
}
printf("\n\nThe descending order is\n\n");
for(turtle = 0; turtle<x; turtle++){
printf("%d\n", ascd[turtle]);
}
}
There are a number of additional issues you need to consider. First always, always, validate user input. If nothing else, with the scanf family of functions, make sure the expected number of conversions were successfully performed. e.g.
int x = 0;
printf ("\n enter the number of elements for your array: ");
if (scanf ("%d", &x) != 1) { /* always validate user input */
fprintf (stderr, "error: invalid input, integer required.\n");
return 1;
}
int ascd[x], desc[x];
Next, you only need to seed the random number generator once. Move srand (time (NULL)); out of the loop.
While not a requirement, it is good practice to initialize your VLA's to all zero (or some number, since you cannot provide an initializer) to eliminate the chance of an inadvertent read from an uninitialized value when iterating over the array (you can consider your filling in this case an initialization, making the memset optional here, but you won't immediately loop and fill in all cases. Something as simple as the following is sufficient if you are not immediately filling the array, e.g.
memset (ascd, 0, x * sizeof *ascd); /* good idea to zero your VLA */
After filling your array, a simple memcpy will duplicate the array if you wish to preserve both ascending and descending sorts, e.g.
for (int i = 0; i < x; i++) /* x random values 1 - 100 */
ascd[i] = (rand () % 100) + 1;
memcpy (desc, ascd, x * sizeof *ascd); /* copy ascd to desc */
The remainder is just a bit of cleanup. Resist the urge to create a (variable next) for every value in your code. That quickly becomes unreadable. While I prefer the C89 declarations, the C99/C11 declarations inside the for block are convenient, e.g.:
for (int i = 0; i < x; i++) /* ascending order */
for (int j = 0; j < (x - i - 1); j++)
if (ascd[j] > ascd[j + 1]) {
int temp = ascd[j];
ascd[j] = ascd[j + 1];
ascd[j + 1] = temp;
}
Putting all the pieces together, and noting that main() is type int and therefore will return a value, you could tidy things up as follows. Your style is completely up to you, but the goal should be readability. e.g.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main (void) {
int x = 0;
printf ("\n enter the number of elements for your array: ");
if (scanf ("%d", &x) != 1) { /* always validate user input */
fprintf (stderr, "error: invalid input, integer required.\n");
return 1;
}
int ascd[x], desc[x];
srand (time (NULL)); /* you only need do this once */
memset (ascd, 0, x * sizeof *ascd); /* good idea to zero your VLA */
for (int i = 0; i < x; i++) /* x random values 1 - 100 */
ascd[i] = (rand () % 100) + 1;
memcpy (desc, ascd, x * sizeof *ascd); /* copy ascd to desc */
for (int i = 0; i < x; i++) /* ascending order */
for (int j = 0; j < (x - i - 1); j++)
if (ascd[j] > ascd[j + 1]) {
int temp = ascd[j];
ascd[j] = ascd[j + 1];
ascd[j + 1] = temp;
}
for (int i = 0; i < x; i++) /* descending order */
for (int j = 0; j < (x - i - 1); j++)
if (desc[j] < desc[j + 1]) {
int temp = desc[j];
desc[j] = desc[j + 1];
desc[j + 1] = temp;
}
printf ("\n the ascending order is\n\n");
for (int i = 0; i < x; i++) {
if (i && !(i % 10)) putchar ('\n');
printf (" %3d", ascd[i]);
}
printf ("\n\n the descending order is\n\n");
for (int i = 0; i < x; i++) {
if (i && !(i % 10)) putchar ('\n');
printf (" %3d", desc[i]);
}
putchar ('\n');
return 0;
}
Example Use/Output
$ ./bin/sort_copy
enter the number of elements for your array: 100
the ascending order is
1 1 4 4 5 5 7 8 8 9
10 13 16 16 17 20 22 22 22 23
24 24 25 27 29 29 33 35 35 35
37 38 40 41 41 41 41 42 44 45
46 48 48 48 49 50 53 54 56 57
58 59 61 61 63 64 65 65 66 66
67 68 68 70 71 73 74 74 74 75
76 80 80 80 80 82 84 84 85 85
85 85 86 88 88 89 89 90 91 91
91 92 92 93 93 93 96 99 100 100
the descending order is
100 100 99 96 93 93 93 92 92 91
91 91 90 89 89 88 88 86 85 85
85 85 84 84 82 80 80 80 80 76
75 74 74 74 73 71 70 68 68 67
66 66 65 65 64 63 61 61 59 58
57 56 54 53 50 49 48 48 48 46
45 44 42 41 41 41 41 40 38 37
35 35 35 33 29 29 27 25 24 24
23 22 22 22 20 17 16 16 13 10
9 8 8 7 5 5 4 4 1 1
Look things over and let me know if you have any questions.
Sorting with qsort
Continuing for the comment, qsort is an optimized sorting routine that is part of the C standard library (in stdlib.h) and is the go-to sort function regardless of the type of data you have to sort. The only requirement that generally catches new C programmers is the need to write a comparison function to pass to qsort so that qsort knows how you want the collection of objects sorted. qsort will compare two elements by passing a pointer to the values to the compare function you write. The declaration for the comparison is the same regardless of what you are sorting, e.g.
int compare (const void *a, const void *b);
You know you are sorting integer values, so all you need to do to sort ascending is to write a function that returns a positive value if a > b, returns zero if they are equal, and finally returns a negative value if b > a. The simple way, is to write
int compare (const void *a, const void *b) {
int x = *(int *)a;
int y = *(int *)b;
return x - y;
}
That satisfies the sort requirement for ascending order, and to sort in descending order return y - x; -- but there is a problem. If x and y happen to be large positive and large negative values, there is a potential that x - y will exceed the maximum (or minimum) value for an integer (e.g. overflow, because the result will not fit in an integer value).
The solution is simple. You can perform the same comparison, but using the results of an inequality, e.g. returning (a > b) - (a < b) for the ascending comparison, and (a < b) - (a > b) for the descending comparison. (this scheme will work for all numeric types, you just need to adjust the cast). Step though the inequality. In the ascending case, if a > b the return is 1 (e.g. return 1 - 0;). If they are equal, the inequality returns 0 (0 - 0 ), and finally if a < b, the value returned is -1 ( 0 - 1 ).
While you are free to continue to explicitly declare the x and y variables, you will generally see it written with the cast in the comparison, eliminating the need for the x and y variables altogether, e.g.
/* integer comparison ascending (prevents overflow) */
int cmpascd (const void *a, const void *b)
{
/* (a > b) - (a < b) */
return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b);
}
Putting those pieces together, the same program can be written using qsort instead of the inefficient nested loops (and moving the print array routine to a function of its own) as follows,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define ROW 10
int cmpascd (const void *a, const void *b);
int cmpdesc (const void *a, const void *b);
void prnarr (int *a, int n, int row);
int main (void) {
int x = 0;
printf ("\n enter the number of elements for your array: ");
if (scanf ("%d", &x) != 1) { /* always validate user input */
fprintf (stderr, "error: invalid input, integer required.\n");
return 1;
}
int ascd[x], desc[x];
srand (time (NULL)); /* you only need do this once */
memset (ascd, 0, x * sizeof *ascd); /* good idea to zero your VLA */
for (int i = 0; i < x; i++) /* x random values 1 - 100 */
ascd[i] = (rand () % 100) + 1;
memcpy (desc, ascd, x * sizeof *ascd); /* copy ascd to desc */
qsort (ascd, x, sizeof *ascd, cmpascd); /* qsort ascending */
qsort (desc, x, sizeof *desc, cmpdesc); /* qsort descending */
printf ("\n the ascending order is\n\n");
prnarr (ascd, x, ROW);
printf ("\n\n the descending order is\n\n");
prnarr (desc, x, ROW);
putchar ('\n');
return 0;
}
/* integer comparison ascending (prevents overflow) */
int cmpascd (const void *a, const void *b)
{
/* (a > b) - (a < b) */
return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b);
}
/* integer comparison descending */
int cmpdesc (const void *a, const void *b)
{
/* (a < b) - (a > b) */
return (*(int *)a < *(int *)b) - (*(int *)a > *(int *)b);
}
void prnarr (int *a, int n, int row)
{
for (int i = 0; i < n; i++) {
printf (" %3d", a[i]);
if (i && !((i + 1) % row))
putchar ('\n');
}
}
As with the first answer, give it a try and let me know if you have any questions. (And remember to always compile with a minimum -Wall -Wextra to enable most compiler warnings -- and fix any warnings generated before you consider your code reliable -- you won't run into any circumstance where warnings can be understood and safely ignored anytime soon) Add -pedantic to see virtually all warnings that can be generated. (if you look up pedantic in Websters, you will see why that name is apt.) Just FYI, the gcc compiler string I used to compile the code was:
$ gcc -Wall -Wextra -pedantic -std=c11 -Ofast -o bin/sort_copy sort_copy.c
You print the final array twice, you can have your ascending array output by printing the values of the array right after you have done the ascending operation.
Create an another array to store descending items. You can reverse the ascending array to create the descending array. Try this code.
#include
#include
#include
#include
int main (){
int x;
printf("Enter the size of your array\n");//User is entering number of elements
scanf("%d", &x);
int ascd[x]; //Array
int desc[x];
int c;
int d;
int e;
int kk = 0;
int temp;
int tempother;
int turtle;
int z=0;
for(c = 0; c<x; c++){//Randomly generating elements
srand(time(0));
ascd[kk] = (rand() %100) + 1;
}
for(c = 0; c<x; c++){ //Ascending order
for(d = 0; d<(x-c-1); d++){
if(ascd[d] > ascd[d+1]){
temp = ascd[d];
ascd[d] = ascd[d+1];
ascd[d+1] = temp;
}
}
}
for(turtle = x-1; turtle>=0; turtle--){//Descending order
desc[z]=ascd[turtle];
z++;
}
printf("The ascending order is\n\n");
for(c = 0; c<x; c++){
printf("%d\n", ascd[c]);
}
printf("\n\nThe descending order is\n\n");
for(turtle = 0; turtle<x; turtle++){
printf("%d\n", desc[turtle]);
}
}

Resources