iterative solution to permutation calculation in C - c

I'm working on a problem dealing with iteration. I'm supposed to pass in two ints into a function, which represent a number of N objects and M values that I must find all permutations of. I am also given a sample of what the output is supposed to look like
void perm_iter(int N, int nr_values)
and the output this is supposed to print is :
Called : perm_iter(3, 2);
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
I understand the concept of recursion by using a swap function to change the orders of strings to find all permutations of a string, but I'm unsure of how to use iteration to get the same, or similar result. Is this a case where I need to use the stack and push/pop iteratively to get my answer? I was thinking I could use something like a set of nested loops to take the place of recursion and get something like this output but I'm unsure how to set the loops up to go through every permutation and not just iterate, missing some of the possible permutations.
Any help would be appreciated, and thank you for your time.

You just need to count up each "digit" until the max is reached, then reset and increment the next.
Imagine nr_values is 10 (with n=2):
0 0
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0 9
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
Looks familiar because it's just "regular" counting in this case.
Implement this just like you count up: In each step, increment the leftmost value. If max is reached, reset and increment the next value etc.
void perm_iter(int n, int nr_values) {
int[] counter = new int[n];
int i;
// Clear all values
for (i = 0; i < n; i++) {
counter[i] = 0;
}
do {
// Print the current set of values
for (i = 0; i < n; i++) {
printf("%n ", counter[i]);
}
printf("\n");
// Keep incrementing while the values overflow,
// starting at the rightmost counter
i = n - 1;
while (i >= 0) {
counter[i]++;
if (counter[i] < nr_values) {
break;
}
counter[i] = 0;
i--;
}
// We are done when the first value overflows
} while (i >= 0);
}

Related

logical multiplication of matrices A and B by the operation "AND" and "OR" in C

This is the question:
A logical matrix is a matrix in which all its elements are either 0 or
1.
We define logical multiplication of matrices A and B by the operation
defined below, where "·" is the logical AND operation, and "+" is the
logical OR operation.
In this assignment, you will create two 5x5 logical matrices and find
the corresponding matrix which will be created from "multiply" these 2
matrices
Define global SIZE equals to 5 (Already defined in the template)
Write a function that gets a matrix reference and reads the input
to the matrix from the user. If the input is non-zero replace it by 1.
If the user did not enter enough values before the end of the line,
the remaining cells in the matrix will be populated with zeros. Also
make sure if the user inputs too many characters, you only take what's
needed and discard the remaining input. (Eg: 1509 is a 2x2 matrix with
values 1101, and ‘1 5 ‘ is also a 2x2 matrix with values 1111, the
highlighted whitespace is taken as a 1 as discussed above.)
Function signature: void read_mat(int mat[][SIZE])
Write a function that multiplies, as defined above, two matrices
and enters the results into a third matrix with suitable dimensions.
Function signature: void mult_mat(int mat1[][SIZE],int mat2[][SIZE], int result_mat[][SIZE])
Write a function that prints a matrix into the screen. Please use
“%3d” for printing format to make it look nice as shown below.
Function signature: void print_mat(int mat[][SIZE])
Write the main program which uses the functions above. The program
reads the matrices values from the user, multiplies them and prints
the result matrix on the screen.
The function definitions given are intentional with the return
statements as void. Do not change them. Arrays are transferred between
functions as references rather as primitives like variables. So the
function definitions are perfectly valid. Also, there is no limit on
the input from the user. You can read only the required digits, and
then stop reading, and discard the remaining input.
Here is my code:
#include <stdio.h>
#define SIZE 5
void read_mat(int mat[][SIZE],int size)
{
int i = 0, j = 0, k = 0;
char c;
c=getchar();
while(c!='\n' && k<size*size){
if(c!='0'){
mat[i][j]=1;
j++;
}
else{
mat[i][j]=0;
j++;
}
if (j >= size){
j = 0;
i++;
}
if (i >= size){
return;
}
c=getchar();
k++;
}
}
void mult_mat(int mat1[][SIZE], int mat2[][SIZE], int result_mat[][SIZE])
{
int i,j,k;
for (i = 0; i <SIZE; ++i){
for (j = 0; j <SIZE; ++j)
{
result_mat[i][j] = 0;
for (k = 0; k < SIZE; ++k)
result_mat[i][j] += mat1[i][k] * mat2[k][j];
if(result_mat[i][j]!=0){
result_mat[i][j]=1;
}
}
}
}
void print_mat(int mat[][SIZE],int size)
{
int i, j;
for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE; j++)
printf("%3d", mat[i][j]);
printf("\n");
}
//Please use the "%3d" format to print for uniformity.
}
int main()
{
int mat1[][SIZE]={ 0 }, mat2[][SIZE]={ 0 }, res_mat[][SIZE]={0};
printf("Please Enter Values For Matrix 1\n");
read_mat(mat1,SIZE);
printf("Please Enter Values For Matrix 2\n");
read_mat(mat2,SIZE);
mult_mat(mat1,mat2,res_mat);
printf("The First Matrix Is :- \n");
print_mat(mat1,SIZE);
printf("The Second Matrix Is :- \n");
print_mat(mat2,SIZE);
printf("The Resultant Matrix Is :- \n");
print_mat(res_mat,SIZE);
return 0;
}
The input and output should be like this:
Please Enter Values For Matrix 1
111000654987010
Please Enter Values For Matrix 2
11 53
The First Matrix Is :-
1 1 1 0 0
0 1 1 1 1
1 1 0 1 0
0 0 0 0 0
0 0 0 0 0
The Second Matrix Is :-
1 1 1 1 1
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
The Resultant Matrix Is :-
1 1 1 1 1
1 0 0 0 0
1 1 1 1 1
0 0 0 0 0
0 0 0 0 0
But when I run the program, this message appears:
exception thrown: Run-Time Check Failure #2 - Stack around the variable 'mat2' was corrupted.
and the output isn't right and I am getting some elements has a junk values:
Please Enter Values For Matrix 1
111000654987010
Please Enter Values For Matrix 2
11 53
The First Matrix Is :-
1 1 1 0 0
0 1 1 1 1
1 1 1 1 1
1 1-858993460-858993460-858993460
-858993460-858993460-858993460-858993460 1
The Second Matrix Is :-
1 1 1 1 1
-858993460-858993460-858993460-858993460-858993460
-858993460-858993460 1 1 1
1 1 1 1 1
1 1 1 1 1
The Resultant Matrix Is :-
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
Another question:
if I entered to the mat1 a big string it's calculated directly without letting me enter a string to mat2 how do I solve this problem ?
int mat1[][SIZE]={ 0 }
will declare a 1x5 matrix. Change it to
int mat1[SIZE][SIZE]={ 0 }

Move values down in a Matrix C

I'm still a noob at programming and still don't know many of the functions that I'm able to use so I kept to the basics, I was trying to create the game 2048 in C, for that I decided to make a function to push numbers in certain directions, either upwards, downwards, left or right. My up function is working, but my down function isn't even though I did the opposite of what I did in my up function. In the push_down function the numbers actually do what they do in the push_up functions, they move up instead of down.
Would love to know why it isn't working if anyone can spot my mistake
//this one is working
void push_up(int game_size, int grid[game_size][game_size])
{
int replace;
int num=0;
for (int j = 0; j < game_size ; ++j)
{
for (int i = 0; i < game_size ; ++i)
{
replace = 100;
if(grid[i][j]==0)
{
for (int a = game_size - 1 ; a > 0 + i ; --a)
{
if(grid[a][j]!=0)
{
num=grid[a][j];
replace=a;
}
}
grid[i][j]=num;
num=0;
}
if(replace!=100){
grid[replace][j]=0;
}
}
}
}
// this one isn't working
void push_down(int game_size, int grid[game_size][game_size])
{
int replace;
int num=0;
for (int j = 0; j < game_size ; ++j)
{
for (int i = game_size - 1; i >= 0 ; --i)
{
replace = 100;
if(grid[i][j]==0)
{
for (int a = 0 ; a < game_size - i ; ++a)
{
if(grid[a][j]!=0)
{
num=grid[a][j];
replace=a;
}
}
grid[i][j]=num; //
num=0;
}
if(replace!=100){
grid[replace][j]=0;
}
}
}
}
What I did in both is mainly to run the column(either upwards or downwards depending on the function) trying to find a zero, lock the position of the zero and try to find the next number in that column by running the column in the opposite direction, the last number (if a number was even found) would be used to fill that zero and the position where the number was would be filled with 0.
So, let me give an example of what I wanted with these function:
In the first function (push_up) I wanted and was able to do a function that would transform this matrix :
4 2 4 0
0 0 0 0
0 4 2 2
2 0 4 2
into this one:
4 2 4 2
2 4 2 2
0 0 4 0
0 0 0 0
So, all the values would move to the highest position possible inside the column.
In the second function what I wanted was to transform this matrix:
4 2 4 0
0 0 0 0
0 4 2 2
2 0 4 2
into this one:
0 0 0 0
0 0 4 0
4 2 2 2
2 4 4 2
All the values would move to the lowest possible position inside the matrix. But I wasn't able to, by running the function what I get is:
This is the original matrix:
0 0 0 0
4 0 0 2
2 0 0 4
0 2 0 0
This is the matrix after using the function push_down:
2 2 0 4
4 0 0 2
0 0 0 0
0 0 0 0
There are probably easier ways to do this, I would love to hear them but I would also love to know where my logic went wrong in the push_down function since in the push_up function it's working fine.
Your example isn't reproducible and I'm not certain exactly what you're trying to do, but this is the obvious error:
for (int a = 0 ; a > game_size - i ; ++a)
{
if(grid[a][j]!=0)
{
num=grid[a][j];
replace=a;
}
}
This loop will never run, a is zero and will never be greater than game_size - 1.

Minesweeper algorithm for finding neighbours?

Im programming in c the minesweeper game.
im pretty at the end.
I have only problem with the last part.
in the game (see picture) when I click on the upper left field, the fields where no mine is are turned around and at the border there are numbers.
how is the algorithm for finding this field and turn them around or to show them .... I mean algorithm for the field in the green circle?
I am doing a design from scratch, I hope it helps you.
If my game arena is nxn matrix of integers,
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
I can model placing a bomb in that matrix by applying such a 3x3 matrix:
1 1 1
1 9 1
1 1 1
Here 9 denotes a bomb, you probably need to use a bigger integer. And when I say apply, I pick the location and increment it by the numbers in that 3x3 matrix. So let's place 1 bomb:
0 1 1 1 0
0 1 9 1 0
0 1 1 1 0
0 0 0 0 0
0 0 0 0 0
Let's place another bomb, just next to the first one. And let's be a bit clever and not increment the location when the initial value in a cell is 9.
0 1 2 2 1
0 1 9 9 1
0 1 2 2 1
0 0 0 0 0
0 0 0 0 0
Let's place another one this time somewhere below.
0 1 2 2 1
0 1 9 9 1
0 1 3 3 2
0 0 1 9 1
0 0 1 1 1
So if I try to start revealing numbers from bottom right. What should be my algorithm? Here is my take:
function revealCell(location)
{
if(cellValueIsRevealed(location)) {
return;
}
var value = revealValueOfCell(location);
if(value > 0)
{
return;
}
foreach(neighbor in neighbors)
{
revealCell(neighbor);
}
}
To implement cellValueIsRevealed method, one way would be to implement a matrix of booleans.
Might be a little late to answer the question, but I'll do it anyway so that if someone sees this in the future it might help them out. This is also written in C# but the general idea should be the same.
The idea is to have a Queue of cells to visit, and a unique collection for visited cells. Start by queueing the current position and then evaluate the whole queue until it's empty. Dequeue the current cell and check if it's already visited. If it's not then check all the surrounding cells and enqueue them if they are empty cells. When you have finished the queue the hashset contains all the empty cells.
public void AsQueue(Queue<(int i, int j)> toVisit, HashSet<(int i, int j)> visited, Cell[] grid, int i, int j)
{
List<(int i, int j)> neighbours = new();
toVisit.Enqueue((i, j));
while (toVisit.Count != 0)
{
var temp = toVisit.Dequeue();
if (!visited.Contains(temp))
{
Neighbours(neighbours, i, j, grid.GetLength(0), grid.GetLength(1));
for (int k = 0; k < neighbours.Count; k++)
{
if (grid[neighbours[k].i, neighbours[k].j].Type == BoxType.Empty &&
!(neighbours[k].i == i && neighbours[k].j == j) &&
!visited.Contains(neighbours[k]))
{
toVisit.Enqueue(neighbours[k]);
}
}
}
visited.Add(temp);
}
}
private void Neighbours(List<(int i, int j)> neighbours, int i, int j, int maxh, int maxw)
{
int[] iOffsets = new int[] { -1, 0, 1 }, jOffsets = new int[] { -1, 0, 1 };
if (i == 0) iOffsets = new int[] { 0, 1 };
else if (i == maxh - 1) iOffsets = new int[] { -1, 0 };
if (j == 0) jOffsets = new int[] { 0, 1 };
else if (j == maxw - 1) jOffsets = new int[] { -1, 0 };
neighbours.Clear();
foreach (var ip in iOffsets)
{
foreach (var jp in jOffsets)
{
neighbours.Add((i + ip, j + jp));
}
}
}

Segfault while allotting 2D array using double dimensional pointer

I'm currently working on a codechef practice problem http://www.codechef.com/problems/STEPUP#
I'm trying to set up a 2D array using pointers to accept the data and enter in into the 2D array as i receive it using scanf.
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char **argv)
{
int m,n,i,k,j;
int ex;
scanf("%d",&ex);
for(i=0;i<ex;i++)
{
int **edgegraph=NULL,temp1,temp2;
scanf("%d %d",&n,&m);
edgegraph=malloc(m*sizeof(int));
for(k=0;k<m;k++)
{
*(edgegraph+k)=malloc(m*sizeof(int));
if(!*(edgegraph+k))
exit(0);
}
for(k=0;k<m;k++)
{
scanf("%d %d",&temp1,&temp2);
*(*(edgegraph+m*temp1)+temp2)=1;
}
for(i=0;i<m;i++)
{
for(j=0;j<m;j++)
printf("%d ",*(*(edgegraph+m*i)+j));
printf("\n");
}
}
}
The error i get is
(gdb) run
Starting program: /home/vishwa/codechef/valid
2
2 2
1 2
Program received signal SIGSEGV, Segmentation fault.
0x000000000040079d in main (argc=1, argv=0x7fffffffded8) at validedge.c:24
24 *(*(edgegraph+m*temp1)+temp2)=1;
(gdb) quit
What I intend to do is create an m*m matrix, set all valid edges to 1 and then sort in ascending order of number of edges. I'm unsure if this will solve the problem, but would like to know where I'm messing up.
You malloc the wrong number of bytes: edgegraph=malloc(m*sizeof(int)); should have malloc(m * sizeof(int *)); . To avoid this sort of error you can use the following pattern:
ptr = malloc( N * sizeof *ptr );
which always allocates N of whatever ptr is a pointer to.
Next, the syntax x[y] is much simpler to read than *(x+y) especially when the expressions get complicated. Using that syntax would have avoided the mistake dconman points outs. You seem to have put an extra m * into your calculation where it is not required.
Also you mix up m and n later in your code. To avoid this sort of error, use more descriptive variable names.
So a fixed version of your allocation code could look like:
if ( 2 != scanf("%d %d",&num_edges, &num_vertices) )
exit(EXIT_FAILURE);
edgegraph = malloc( num_vertices * sizeof *edgegraph );
for (int vertex = 0; vertex < num_vertices; ++vertex)
{
edgegraph[vertex] = malloc( num_vertices * sizeof **edgegraph );
if ( edgegraph[vertex] == NULL )
exit(EXIT_FAILURE);
}
Note that it is possible to replace that malloc series with a single allocation:
int (*edgegraph)[num_vertices] = malloc( num_vertices * sizeof *edgegraph );
Moving onto your code to read edges. You wrote for(k=0;k<m;k++) however I think you meant n there. Using more descriptive variable names and the x[y] syntax:
for(int edge = 0; edge < num_edges; ++edge)
{
if ( 2 != scanf("%d %d",&temp1,&temp2) )
exit(EXIT_FAILURE);
if ( temp1 < 0 || temp1 >= num_vertices || temp2 < 0 || temp2 >= num_vertices )
exit(EXIT_FAILURE); // maybe display an error message
edgegraph[temp1][temp2] = 1;
edgegraph[temp2][temp1] = 1; // add this if undirected graph!
}
Now the final loop, for(i=0;i<m;i++). You have used the same variable i as control variable for this loop and for your outer loop. To avoid this sort of error, use scoped control variables:
for (int i = 0; i < num_edges; ++i)
Finally you will need to free the memory you malloc'd at the end of each time around the outer loop.
You are so close: lose the m* in your expressions to access an array element. Remember, you set up your 2d array as an array of rows, each with its own pointer (you allocated each independently).
*(*(edgegraph+m*temp1)+temp2)=1;
should be
*(*(edgegraph+temp1)+temp2)=1;
And the same change where you do that later in your code.
Is there a reason you are not using array indices?
EDIT
here is my input
2
10
10
4 3
4 9
7 3
3 7
4 3
4 5
7 4
3 5
9 0
5 2
And I got this output
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 1 0 0
0 0 0 1 0 1 0 0 0 1
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0

Count number of occurrences of each unique number: algorithm almost works

I am trying to work my way up from the beginning in C and making sure I understand every little thing before moving on. Today, my goal was to write a program that would take in a list of integers (assume less than 50 integers) and would print a table with the list of unique integers in one side and the number of times it appeared in the other. I have a copy of my function which takes care of counting the number of times it appears.
Quick summary of my function: takes in 2 pointers to arrays, and one integer of how many integers to iterate over. Assumption: we are checking for repeats of some number x. Somewhere in the array, we hit another x. It increments the count for x and turns x into 0 for later purposes.
Sample trials
input: 1 2 1 2 2 1 2
output: 1 appears 3 times. 2 appears 4 times.
input: 1 2 3 1 2 3 1 2 3
output: 1 appears 3 times. 2 appears 3 times. 3 appears 3 times.
input: 1 2 1 3 1 2 3
output: 1 appears 3 times. 2 appears 2 times. 3 appears 1 times.
Although the program is working for the most part, I want to make sure it works completely. Thus, my issue is that last trial. Why is 3 being read only once when it works for other 2 input sets?
void countOccurrences(int *list, int size, int *uniques){
for (int i = 0, t = 0; i < size; i++){
int temp = list[i];
if (temp == 0){ //If the number was a repeat of another previous number
continue; //skip over it and go to the next element in list
}
uniques[t] = 1;
for (int j = i+1; j <= size; j++){ //this iterates through list for any repeats of temp
if (temp == list[j]){ //All repeats of temp turn to 0
uniques[i]++;
list[j] = 0;
}
}
t++;
}
}
It is because, 3 comes as last number and you reset the count of occurrence to 1
uniques[t] = 1;
and for loop doesn't run at all since thats the last number, you are not looking back in the array.
I would simply write this program as below.Given list has values >=0
for (int i = 0; i < size; i++){ //this iterates through list for any repeats of temp
uniques[list[i]]++;
}
For a list with any values, use a hash table data structure
I wouldn't go stomping over the original data.
High level view:
for each element
if it apeared before
increment it's count
else
record it's first occurence
Say you need to count the contents of an N element array, it can't contain more than N different elements. One simple way of representing the counts is to have an array of values and counts, and a number of used entries (different values seen). This would be along the lines:
#define N ...
struct {
int value, cnt;
} count[N];
int entries = 0;
Your check to see if the value v is already there is:
for(k = 0; k < entries && count[k].value != v; k++)
;
if(k == entries) {
/* Not found */
count[k].value = v;
count[k].cnt = 1;
entries++;
}
else {
/* Found it */
count[k].value++;
}
Just need to wrap this up with the code to comb your data array...
(Yes, this is quite inefficient; for serious use a smarter/faster structure to keep the values would be needed).
There are several problems with this code that we can illustrate with some more complete testing. Here's a short, self-contained, compilable (in C99) example (see SSCCE) with some tests and some additional diagnostic results:
#include <stdio.h>
void printArray(char *name, int *list, int size) {
printf ("%s = {",name);
for (int i = 0; i < size; i++) {
printf ("%d ",list[i]);
}
printf ("}\n");
}
void countOccurrences(int *list, int size, int *uniques, int *values) {
for (int i = 0, t = 0; i < size; i++) {
int temp = list[i];
if (temp == 0) {
//If the number was a repeat of another previous number
continue;
//skip over it and go to the next element in list
}
uniques[t] = 1;
values[t] = temp;
for (int j = i+1; j <= size; j++) {
//this iterates through list for any repeats of temp
if (temp == list[j]) {
//All repeats of temp turn to 0
uniques[i]++;
list[j] = 0;
}
}
t++;
}
}
void test(int *x, int size) {
const int n = 10;
int uniques[n],values[n];
for (int i = 0; i < n; i++) {uniques[i] = 0; values[i] = -1; }
countOccurrences (x,size,uniques,values);
printArray ("uniques",uniques,sizeof(uniques)/sizeof(*uniques));
printArray ("values ",values,sizeof(values)/sizeof(*uniques));
}
int main (int argc, char* argv[]) {
int x1[] = {1, 2, 1, 2, 2, 1, 2};
int x2[] = {1, 2, 3, 1, 2, 3, 1, 2, 3};
int x3[] = {1, 2, 1, 3, 1, 2, 3};
int x4[] = {3, 2, 1, 3, 1, 2, 3};
test(x1,sizeof(x1)/sizeof(*x1));
test(x2,sizeof(x2)/sizeof(*x2));
test(x3,sizeof(x3)/sizeof(*x3));
test(x4,sizeof(x4)/sizeof(*x4));
return 0;
}
(EDITED thanks to #Matt McNabb's advice, by refactoring common code into the test() function)
... for which the output is:
uniques = {3 4 0 0 0 0 0 0 0 0 }
values = {1 2 -1 -1 -1 -1 -1 -1 -1 -1 }
uniques = {4 3 3 0 0 0 0 0 0 0 }
values = {1 2 3 -1 -1 -1 -1 -1 -1 -1 }
uniques = {4 2 1 1 0 0 0 0 0 0 }
values = {1 2 3 -1 -1 -1 -1 -1 -1 -1 }
uniques = {3 2 3 0 0 0 0 0 0 0 }
values = {3 2 1 -1 -1 -1 -1 -1 -1 -1 }
The first test gives you the expected output. The second test shows that there is an extra count for the first item in the list. This can be fixed by changing:
for (int j = i+1; j <= size; j++){
to
for (int j = i+1; j < size; j++){
... because the code is counting one space beyond the end of the data. The output with this bug fixed is:
uniques = {3 4 0 0 0 0 0 0 0 0 }
values = {1 2 -1 -1 -1 -1 -1 -1 -1 -1 }
uniques = {3 3 3 0 0 0 0 0 0 0 }
values = {1 2 3 -1 -1 -1 -1 -1 -1 -1 }
uniques = {3 2 1 1 0 0 0 0 0 0 }
values = {1 2 3 -1 -1 -1 -1 -1 -1 -1 }
uniques = {3 2 2 0 0 0 0 0 0 0 }
values = {3 2 1 -1 -1 -1 -1 -1 -1 -1 }
The third and fourth test results are harder to interpret because it isn't so obvious what the intended output should be. The counting function appears to be intended to report counts of unique numbers in the order in which it finds those numbers in list. With the third test, however, the first appearance of "3" is at the fourth item in the list. Changing:
uniques[i]++;
to
uniques[t]++;
... means that the count is output as the tth item in the count list, giving the output:
uniques = {3 4 0 0 0 0 0 0 0 0 }
values = {1 2 -1 -1 -1 -1 -1 -1 -1 -1 }
uniques = {3 3 3 0 0 0 0 0 0 0 }
values = {1 2 3 -1 -1 -1 -1 -1 -1 -1 }
uniques = {3 2 2 0 0 0 0 0 0 0 }
values = {1 2 3 -1 -1 -1 -1 -1 -1 -1 }
uniques = {3 2 2 0 0 0 0 0 0 0 }
values = {3 2 1 -1 -1 -1 -1 -1 -1 -1 }
This output is correct now, but it is difficult to interpret the counts found in uniques without the values array that I've added to the code. See that, in the last test case, the first count is the number of 3s in list, not the number of 1s, for instance.
Finally, it is generally poor practice to modify a parameter to a function at all. It is necessary to do so in C because you can't return an array from a function but modifying the arrays pointed to by uniques and values is generally tolerable because they are explicitly available to return results outwards from the function. Modifying a parameter used to supply input data to a function, though, as countOccurrences() does with list is generally unwise because that means the code that uses countOccurrences() has to make a copy of list before passing the pointer to that list to countOccurrences(), if it wants to use the original content of list for some other purpose as well.
If we know that the integers to be counted are all less than or equal to than the size of the uniques array, the function suggested by #Saravana Kumar is both quicker to run and easier to make correct:
// Requirements:
// uniques initially contains all zeros
// no integer in list is less than zero or greater than sizeof(uniques)/sizeof(int)-1
//
void countOccurrences2 (int *list, int size; int *uniques) {
for (int i = 0; i < size; i++) {
uniques[list[i]]++;
}
}

Resources