Odd behavior in my code for a certain test case - c

The program is supposed to swap neighbouring elements which don't have a common denominator, and an element can only be swapped once.
When i run the program, pretty much for any input works fine. Except for this one:
100 //input for number of elements
48 92 76 93 17 38 59 34 53 99 58 20 50 0 38 37 16 36 91 12 59 1 76 82 20 76 7 72 13 70 64 23 81 70 41 69 11 0 16 41 37 83 41 99 73 79 4 38 24 32 87 38 95 24 77 30 61 13 89 67 87 76 22 31 67 31 25 90 6 76 21 43 40 55 72 91 91 28 18 58 72 71 83 22 99 23 86 58 75 53 69 29 5 55 46 8 98 55 19 46 //the elements
For this input, the program hangs and prints nothing. Does someone know what is going on in this particular case?
#include <stdio.h>
int nzd(int a, int b)
{
if(a==b || b==0)
return a;
if(a>b)
return nzd(a-b, b);
return nzd(a, b-a);
}
int swap(int *niza, int i)
{
int temp;
temp=*(niza+i);
*(niza+i)=*(niza+i+1);
*(niza+i+1)=temp;
}
int main()
{
int a[100], n, i;
scanf("%d", &n);
for(i=0; i<n; i++)
{
scanf("%d", &a[i]);
}
for(i=0; i<n; i++)
{
if(i+1==n) continue;
if(nzd(a[i], a[i+1])==1)
{
swap(a, i);
i++;
}
}
for(i=0; i<n; i++)
{
printf("%d ", a[i]);
}
return 0;
}

Your gcd function checks for the case of b==0 but not the case for a==0. Because you skip that check, you end up calling nzd(0, b-0); which is exactly the same as the prior call. This puts you in an infinite recursion loop which will eventually cause a stack overflow.
Add the check for this case in your function:
if(a==b || b==0 || a == 0)
Also, a faster implementation of gcd, called Euclid's algorithm, is as follows:
int gcd(int a, int b)
{
if (b==0) {
return a;
} else {
return (b, a%b);
}
}

Your function nzd() fails to handle the case a == 0 correctly and gets stuck in an endless loop. You need to handle this case, too:
int nzd(int a, int b)
{
if(a==b || a==0 || b==0)
return a;
if(a>b)
return nzd(a-b, b);
return nzd(a, b-a);
}

Related

Sorting sides of n triangles according to the area

Given n triangles, with sides a,b,c print them in the same style by sorting them from the smallest to the largest.
Complete problem: https://www.hackerrank.com/challenges/small-triangles-large-triangles/problem
In the solution, we have a structure named as Triangle. It has 3 integers a,b,c. An array of Triangle is made, named as tr and the input is passed to the function sort_by_area.
My approach is to apply bubble sort on this array.But instead of comparing tr[j] > tr[j+1] like we do in normal bubble sort, I'm comparing the areas of tr[j] and tr[j+1]. Now, if area of tr[j] > tr[j+1]: Swap.
The problem: In the end the results are wrong. The array doesn't sort properly. First I thought it's a typo somewhere so I rewrite the code but the problem persists.
double area (int a, int b, int c)
{
double p = (a+b+c)/2;
return sqrt(p*(p-a)*(p-b)*(p-c));
}
void sort_by_area(triangle* tr, int n) {
/**
* Sort an array a of the length n
*/
int i,j;
double area1, area2;
triangle temp;
for(i = 0; i < n-1;++i)
{
for(j = 0; j < n-i-1; ++j)
{
area1 = area(tr[j].a , tr[j].b, tr[j].c);
area2 = area(tr[j+1].a , tr[j+1].b, tr[j+1].c);
if(area1 > area2)
{
temp = tr[j];
tr[j] = tr[j+1];
tr[j+1] = temp;
}
}
}
}
input: 20
23 37 47
22 18 5
58 31 31
28 36 40
54 62 11
31 41 14
53 18 54
41 38 55
55 44 44
44 48 18
26 41 65
20 23 21
58 61 50
28 56 56
20 39 32
33 45 49
26 41 62
31 46 39
48 49 67
57 33 45
expected output:
22 18 5
31 41 14
20 23 21
54 62 11
26 41 65
58 31 31
20 39 32
26 41 62
44 48 18
23 37 47
53 18 54
28 36 40
31 46 39
33 45 49
57 33 45
28 56 56
41 38 55
55 44 44
48 49 67
58 61 50
actual output:
22 18 5
54 62 11
31 41 14
20 23 21
26 41 65
20 39 32
58 31 31
26 41 62
23 37 47
44 48 18
53 18 54
28 36 40
31 46 39
33 45 49
57 33 45
28 56 56
41 38 55
55 44 44
48 49 67
58 61 50
This is my solution for this challenge:
double area(triangle t){
double p = (t.a+t.b+t.c)/2.0;
return sqrt(p*(p-t.a)*(p-t.b)*(p-t.c));
}
void sort_by_area(triangle* tr, int n) {
int i,j;
for(i=0;i<n-1;i++){
for(j=i+1;j<n;j++){
if(area(tr[j]) < area(tr[i])){
triangle temp = tr[i];
tr[i]=tr[j];
tr[j]=temp;
}
}
}
}
Your usage of the 'for' loop for comparing triangles is this (by triangle, I mean triangle's area):
for(i = 0; i < n - 1; ++i){
...
...
for(j = 0; j < n - i - 1; ++j){
...
}
}
Observe carefully: The loop you used fails to compare the last elements of the arrays.
I just improvised your code and it works:
#include < stdio.h >
#include < stdlib.h >
#include < math.h >
struct triangle
{
int a;
int b;
int c;
};
typedef struct triangle triangle;
float area(int a, int b, int c)
{
float p;
p = (float)(a + b + c) / 2;
return sqrt(p * (p - a) * (p - b) * (p - c));
}
void sort_by_area(triangle* tr, int n)
{
int i, j;
float area1, area2;
triangle temp[5];
for (i = 0; i < n - 1; i++)
{
for (j = 0; j < n - i - 1; j++)
{
area1 = area(tr[j].a, tr[j].b, tr[j].c);
area2 = area(tr[j + 1].a, tr[j + 1].b, tr[j + 1].c);
if (area1 > area2)
{
temp[0] = tr[j];
tr[j] = tr[j + 1];
tr[j + 1] = temp[0];
}
}
}
}
int main()
{
int n;
scanf("%d", &n);
triangle* tr = malloc(n * sizeof(triangle));
for (int i = 0; i < n; i++)
{
scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
}
sort_by_area(tr, n);
for (int i = 0; i < n; i++)
{
printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
}
return 0;
}
An edit of #Zümrüd-ü Anka's answer to match the bubble sorts you'll find elsewhere. Your loops actually should work fine, both for loops here are the same as yours. This passes the test cases for HackerRank. I think it was actually just the integer division that was giving you an issue.
double area(triangle t){
double p = (t.a+t.b+t.c)/2.0;
return sqrt(p*(p-t.a)*(p-t.b)*(p-t.c));
}
void sort_by_area(triangle* tr, int n) {
int i,j;
for(i=0;i<n-1;i++){
for(j=0;j<n-i-1;j++){
if(area(tr[j]) > area(tr[j+1])){
triangle temp = tr[j+1];
tr[j+1]=tr[j];
tr[j]=temp;
}
}
}
}

Could somebody help me with my Code (C language)?

I am a beginner in C language and I have been asked to: write a whole program printing in separate lines odd numbers from 100 to 0, and marking with "!!!" those numbers that are multiplications of 7.
I tried to do that but unfortunately iam printing numbers which are duplications for example (91 and 91!!!). How can I avoid this situation?
Here is my code maybe someone can help me with this task?
#include <stdio.h>
int main ()
{
int i;
for (i=100;i>=0;i--)
{
if(i%2)
{
printf("%d\n",i);
}
if (i%7==0 && i%2!=0)
{
printf("%d!!!\n",i);
}
}
}
This is a solution based on Aditi Rawat comment.
#include "stdio.h"
int main ()
{
int i;
for (i=100; i>=0; i--)
{
if (i%7==0 && i%2!= 0)
{
printf("%d!!!\n",i);
}
else
{
if(i%2 != 0)
printf("%d\n",i);
}
}
return 0;
}
OUTPUT:
99
97
95
93
91!!!
89
87
85
83
81
79
77!!!
75
73
71
69
67
65
63!!!
61
59
57
55
53
51
49!!!
47
45
43
41
39
37
35!!!
33
31
29
27
25
23
21!!!
19
17
15
13
1

What's wrong with the matrix?

What's wrong with this code?
My task is: Create a square matrix of integers with a size of 9x9. Fill the matrix with random numbers. Display the main and side diagonal symmetrically with respect to the vertical axis. The example of expected result is here: matrix
Matrix :
20 20 76 65 93 76 16 2 85
6 87 78 43 48 81 71 90 38
10 12 35 77 48 88 24 53 7
12 66 51 35 74 7 30 22 49
58 14 71 46 68 68 10 81 51
98 16 74 47 64 25 17 30 37
2 44 44 74 34 54 86 73 28
85 4 57 75 18 28 51 76 2
35 17 53 76 15 91 83 85 72
The main and side diagonal:
85 20 76 65 93 76 16 2 20
6 90 78 43 48 81 71 87 38
10 12 24 77 48 88 35 53 7
12 66 51 7 74 35 30 22 49
58 14 71 46 68 68 10 81 51
98 16 74 25 64 47 17 30 37
2 44 86 74 34 54 44 73 28
85 76 57 75 18 29 51 4 2
72 17 53 76 15 91 83 85 35
But in fact the program prints only the main matrix with random numbers and after that stops.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <Windows.h>
int main()
{
int a = 9;
int matrix[a][a];
int temp;
int i, j, n;
srand((unsigned)time(NULL));
printf("Matrix : \n\n");
for (i = 0; i < a; ++i) {
for (j = 0; j < a; ++j) {
matrix[i][j] = rand() % 100;
printf("%d\t", matrix[i][j]);
}
printf("\n\n");
}
printf("The main and side diagonal:\n\n");
for (i = 0; i < a; ++i) {
temp = matrix[i][i];
matrix[i][i] = matrix[i][(a - 1) - i];
matrix[i][(a - 1) - i] = temp;
}
for (i = 0; i < a; ++i) {
for (j = 0; j < a; ++j) {
printf("Result:", matrix[i][j]);
printf("\n\n\n");
system("pause");
return 0;
}
}
}
You are returning where you are not supposed to. (in middle of the calculation). You should return after you end up working on the for loops.
for (i = 0; i < a; ++i) {
for (j = 0; j < a; ++j) {
printf("Result:", matrix[i][j]); <--- Not printing element
printf("\n\n\n");
system("pause");
return 0; <-----
}
}
It should be
for (i = 0; i < a; ++i) {
for (j = 0; j < a; ++j) {
printf("Result: %d ", matrix[i][j]); <----You forgot the
//format specifier
printf("\n\n\n");
system("pause");
}
}
return 0;<-----
Readability is hampered when the indentation is like this. You implemented wrong logic out of it.
OP asks that it stops after printing "Result" that is because you forgot to put the format specifier in the code. That's why none of the element is printed.
Op wants to print the main and side diagonal symmetrically with respect to the vertical axis.
Now this is everything to with the print part.
Now we have to find a way that will let us distinguish which one is diagonal element and which one is not.
Suprisingly the answer should be known to someone who is writing the previous swapping logic. (Though it is not clear why OP swapped it).
Now all element matrix[p][q] will be from either diagonal if p=q or p+q=a-1. (Note that matrix is a square matrix).
But OP meant to print the matrix
for (i = 0; i < a; ++i) {
if( i == 0) printf("The main and side diagonal : \n");
for (j = 0; j < a; ++j) {
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
}
Use functions. You print the matrix twice; you should have a function to print the matrix which you call twice.
With such a function, you'd not make the mistakes in the tail end of your code. For example, you could use this:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
static void print_matrix(const char *tag, int size, int matrix[size][size])
{
printf("%s (%dx%d):\n\n", tag, size, size);
for (int i = 0; i < size; ++i)
{
const char *pad = "";
for (int j = 0; j < size; ++j)
{
printf("%s%-2d", pad, matrix[i][j]);
pad = " ";
}
printf("\n\n");
}
}
int main(int argc, char **argv)
{
unsigned seed = time(0);
int a = 9;
int matrix[a][a];
if (argc == 2)
seed = atoi(argv[1]);
srand(seed);
printf("Seed: %u\n", seed);
for (int i = 0; i < a; ++i)
{
for (int j = 0; j < a; ++j)
matrix[i][j] = rand() % 100;
}
print_matrix("Matrix", a, matrix);
for (int i = 0, j = a - 1; i < a; ++i, --j)
{
int temp = matrix[i][i];
matrix[i][i] = matrix[i][j];
matrix[i][j] = temp;
}
print_matrix("The main and side diagonal", a, matrix);
return 0;
}
The code reports the seed it uses; that allows you to reproduce any run by specifying the seed to use as a command line argument.
Example output:
Seed: 1511470282
Matrix (9x9):
11 39 3 88 98 63 75 81 76
93 9 60 22 45 50 46 58 65
13 99 25 43 14 57 44 70 65
30 57 55 0 37 84 47 49 40
60 28 46 1 96 78 33 20 9
93 61 11 38 84 16 91 26 15
43 85 66 72 85 39 96 45 45
45 25 33 3 78 90 61 65 62
88 84 56 34 74 8 78 57 74
The main and side diagonal (9x9):
76 39 3 88 98 63 75 81 11
93 58 60 22 45 50 46 9 65
13 99 44 43 14 57 25 70 65
30 57 55 84 37 0 47 49 40
60 28 46 1 96 78 33 20 9
93 61 11 16 84 38 91 26 15
43 85 96 72 85 39 66 45 45
45 65 33 3 78 90 61 25 62
74 84 56 34 74 8 78 57 88
The swapping process, in case it isn't obvious, swaps the first and last elements of the first row, the second and last but one element in the second row, and so on, forming an X of swapped elements.

Suggestion about unique values generation

I want to generate a series of "random" unique numbers, for use at a card game! These numbers should be between 0 and 81.
I don't care about security or speed at this stage, i just want something simple to have the work done.
In my code below, i have managed to create 2 unique random numbers in the array that holds them, but the rest 10 numbers don't change but stay -1 that was the initial value..
I have found more accurate ways for random number generation, but i will check them out at a later stage!
#include <stdio.h>
#include <stdlib.h>
int getRandomNumber(int Min, int Max)
{
double rnd= (double)rand()/((double)RAND_MAX+1);
return (int)(rnd*(Max-Min+1))+Min;
}
int main()
{
int j,counter,temp,deck[13];
srand(time(NULL));
int i;
counter=1;
for (i=0;i<12;i++)
{deck[i]=-1;
temp = getRandomNumber(0,81);
for (j=0;j<=i;j++)
{if (temp==deck[j])
{counter=0;}
if (counter!=0)
deck[i]=temp;
}
}
for(i=0;i<12;i++)
printf("%d ",deck[i]);
}
Your code has one of the weirder indentation and brace layout schemes I've ever seen:
#include <stdio.h>
#include <stdlib.h>
int getRandomNumber(int Min, int Max)
{
double rnd= (double)rand()/((double)RAND_MAX+1);
return (int)(rnd*(Max-Min+1))+Min;
}
int main()
{
int j,counter,temp,deck[13];
srand(time(NULL));
int i;
counter=1;
for (i=0;i<12;i++)
{deck[i]=-1;
temp = getRandomNumber(0,81);
for (j=0;j<=i;j++)
{if (temp==deck[j])
{counter=0;}
if (counter!=0)
deck[i]=temp;
}
}
for(i=0;i<12;i++)
printf("%d ",deck[i]);
}
Converted to a more orthodox style (Allman, more or less — see Wikipedia on Indent style), you get:
#include <stdio.h>
#include <stdlib.h>
static int getRandomNumber(int Min, int Max)
{
double rnd = (double)rand() / ((double)RAND_MAX + 1);
return (int)(rnd * (Max - Min + 1)) + Min;
}
int main(void)
{
int j, counter, temp, deck[13];
srand(time(NULL));
int i;
counter = 1;
for (i = 0; i < 12; i++)
{
deck[i] = -1;
temp = getRandomNumber(0, 81);
for (j = 0; j <= i; j++)
{
if (temp == deck[j])
{
counter = 0;
}
if (counter != 0)
deck[i] = temp;
}
}
for (i = 0; i < 12; i++)
printf("%d ", deck[i]);
}
The static and int main(void) are needed to get the code past my default compilation options; otherwise, they're cosmetic.
Now we can see some problems. The counter is set to 1 once, outside the outer loop; it is set to 0 sometimes inside the loop, but once that happens, it is never reset to 1, so no further numbers are added to the deck. You need to rework the inner loop, maybe like this:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
static int getRandomNumber(int Min, int Max)
{
double rnd = (double)rand() / ((double)RAND_MAX + 1);
return (int)(rnd * (Max - Min + 1)) + Min;
}
int main(void)
{
int deck[13];
srand(time(NULL));
for (int i = 0; i < 12; i++)
{
int temp = getRandomNumber(0, 81);
deck[i] = -1;
int counter = 1;
for (int j = 0; j <= i; j++)
{
if (temp == deck[j])
{
counter = 0;
break;
}
}
if (counter != 0)
deck[i] = temp;
else
i--; // Try again with a new random choice for the same i
}
const char *pad = "";
for (int i = 0; i < 12; i++)
{
printf("%s%d", pad, deck[i]);
pad = " ";
}
putchar('\n');
return 0;
}
I dislike trailing blanks, so the printing loop takes care to ensure there aren't any.
Sample output with getRandomNumber() — on macOS Sierra 10.12.2 with GCC 6.3.0:
7 73 38 61 11 13 41 66 29 39 72 20
7 2 18 17 54 31 45 40 34 22 63 16
7 13 80 54 16 49 14 58 28 53 23 26
7 24 60 10 67 53 69 32 23 2 66 12
7 34 40 48 21 3 57 43 6 18 27 80
7 45 20 3 65 21 61 17 12 69 66 27
7 67 62 78 70 57 68 46 9 2 72 39
7 77 41 34 32 75 72 20 64 78 33 25
7 6 21 72 76 11 75 38 73 27 64 33
7 17 1 27 37 28 80 49 12 67 59 36
That first number isn't very random — shortly after that sequence of tests, it changed from 7 to 8, but was equally non-random. An alternative
way of generating random numbers is:
static int getRandomNumber(int Min, int Max)
{
int rnd;
int range = (Max - Min + 1);
while ((rnd = rand()) > RAND_MAX - (RAND_MAX % range))
;
return (rnd % range) + Min;
}
This avoids the bias from that fact that 82 doesn't divide RAND_MAX exactly, which would weight the distribution of the lower numbers slightly higher than the upper numbers in the range 0..81. It also avoids the unexpectedly consistent first number, though the new first number is also semi-predictable when the tests are run at 1-second intervals.
Sample results:
48 33 28 78 14 2 81 13 23 75 38 40
45 42 74 1 11 68 17 33 78 49 23 80
42 51 38 3 5 52 35 56 54 23 59 41
39 60 2 8 36 53 79 30 72 75 62 37
36 69 45 10 78 20 71 17 6 53 54 30
33 78 9 15 75 7 40 61 27 36 70 68
30 5 55 17 69 73 25 63 37 1 21 71
27 14 19 66 57 43 1 13 3 65 71 21
24 26 62 63 41 61 68 28 67 20 74 17
21 35 26 57 28 79 47 44 2 52 60 77
Notice that the first number decreases by 3; the second seems to increase by 9; ugh — the randomness isn't all that good. It's well known that rand() is often not a high quality PRNG (pseudo-random number generator), but I'm a little surprised by this apparently systematic behaviour with seeds that differ by 1 each time.
On my Mac, when I changed srand() to srandom() and rand() to random(), I got better (as in, more unpredictable) results:
29 1 7 11 25 52 63 15 26 55 75 64
40 4 64 18 8 57 73 27 38 15 60 28
43 3 27 17 1 58 26 72 73 18 20 7
76 16 27 43 64 20 63 30 35 17 33 57
79 47 32 33 6 30 35 7 38 55 25 61
69 57 79 75 15 54 5 35 21 46 65 61
30 79 66 14 56 39 19 8 50 47 76 33
62 65 81 44 52 39 25 30 54 12 24 68
27 49 60 72 53 35 14 41 63 46 45 65
67 39 9 11 60 19 64 73 43 17 21 26
And the Mac man page for random() still suggests using arc4random() instead, but this is a lot better than plain rand(). What you find on other systems will depend on the facilities provided by the system — rand() may not be as awful as it seems to be on Mac. Basically, be cautious with your choice of PRNG — especially if you're going to use systematically generated seeds (such as the current time).
For the purpose you propose (generating a random sequence of numbers ranging from 0 through 81, where each item differs from the others), you will need a particular kind of random number generator (RNG), one that can generate all possible permutations of 82 items (expressed as 82!, or 82 factorial). However, only a limited selection of RNGs can do this. In particular the C rand() function's implementation is unspecified, so is not guaranteed to generate that many permutations.
A pseudorandom number generator (PRNG, a kind of RNG as used here) can't generate more random number sequences than its period. For 82! permutations, no PRNG with a period less than 82! can do this (the next highest power of 2 is 2408, meaning the generator needs to takes a seed at least 408 bits, or 51 bytes, long for it to possibly do so -- and 51 bytes is much bigger than srand can usually take). Alternatively, for this purpose, you would be well advised to use an RNG that generates "unpredictable" numbers, which neither the C language nor the C library includes as standard. See "Shuffling" and "Unpredictable RNGs" in my article on randomness for more information.

Partial Threaded Sorting in C

I'm trying to do a partial sort with a threads,
my current output it
27 12 21 48 15 28 82 69 35 91
13 82 33 35 46 5 35 28 87 95
0 10 20 22 23 30 52 80 86 96
3 8 42 53 67 70 70 71 75 79
5 8 8 18 41 43 70 79 86 88
10 51 56 60 65 84 87 91 94 99
23 25 38 39 40 44 51 56 69 75
20 21 25 29 29 38 66 71 73 96
33 50 9 6 13 27 97 21 70 22
3 4 6 6 7 15 34 59 63 70
As you can see I am getting it partially sorted I want my output to be this (no merging at the end)
12 15 21 27 28 35 48 69 82 91
5 13 28 33 35 35 46 82 87 95
0 10 20 22 23 30 52 80 86 96
3 8 42 53 67 70 70 71 75 79
5 8 8 18 41 43 70 79 86 88
10 51 56 60 65 84 87 91 94 99
23 25 38 39 40 44 51 56 69 75
20 21 25 29 29 38 66 71 73 96
6 9 13 21 22 27 33 50 70 97
3 4 6 6 7 15 34 59 63 70
I can get the right output if instead of using a struct I use &array[i] and manually input the length
This is the code I have so far:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <pthread.h>
int cmpfunc(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
struct values {
int *arrayptr;
int length;
};
void *thread_fn(void *a) {
struct values *start = a;
qsort(start->arrayptr, start->length, sizeof(int), cmpfunc);
return (void*)a;
}
int main(int argc, const char *argv[]) {
FILE *fp = fopen(argv[3], "r");
FILE *fp1 = fopen("numS1.dat", "w+");
//amount of threads
int threadAmount = atoi(argv[1]);
//size of input
int numberAmount = atoi(argv[2]);
//multidimensional array
int array[threadAmount][numberAmount / threadAmount];
for (int i = 0; i < threadAmount; i++)
for (int j = 0; j < numberAmount / threadAmount; j++)
fscanf(fp, "%d", &array[i][j]);
pthread_t threadid[threadAmount];
for (int i = 0; i < threadAmount; ++i) {
struct values a = { array[i], numberAmount / threadAmount };
pthread_create(&threadid[i], NULL, thread_fn, &a);
}
for (int i = 0; i < threadAmount; ++i)
pthread_join(threadid[i], NULL);
for (int i = 0; i < threadAmount; i++) {
if (i != 0)
fprintf(fp1, "\n");
for (int j = 0; j < numberAmount / threadAmount; j++)
fprintf(fp1 ,"%d ", array[i][j]);
}
return 0;
}
Do you know where I am going wrong?
I think its the struct but everything I see online does what I'm doing.
You are passing a pointer to automatic storage to newly created threads: the struct values object becomes invalid as soon as the calling scope is exited, thus it cannot be reliably accessed by the new thread. You should allocate the struct values and pass the pointer to the allocated object as a parameter to pthread_create:
for (int i = 0; i < threadAmount; ++i) {
struct values *a = malloc(sizeof(*a));
a->arrayptr = array[i];
a->length = numberAmount / threadAmount;
pthread_create(&threadid[i], NULL, thread_fn, a);
}
The structure can be freed by the thread function before exiting.
Notes:
the way you split the array into chunks only works if the length is a multiple of the number of threads.
the comparison function does not work for large int values, you should use this instead:
int cmpfunc(const void *a, const void *b) {
return (*(int*)b < *(int*)a) - (*(int*)a < *(int*)b);
}

Resources