Move values down in a Matrix C - 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.

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 }

2D array - I want to find which columns have 1s in them in each row

My input looks like this :
15 5
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0
1 0 0 0 0
0 1 0 1 0
0 0 1 0 0
0 0 0 0 1
0 0 0 0 0
0 0 0 0 0
0 1 0 0 0
1 0 0 0 1
0 0 1 0 0
0 0 0 1 0
The first row contains the number of rows and columns of my array. And basically I want to find out where these 1s are in the array.
So in the first 3 rows i want to get 3, in the 7th 1, and in the 8th, i want to get 2 3 etc..
My code looks like this so far
#include <stdio.h>
int main() {
int row, column;
FILE* input;
FILE* output;
input = fopen("input.txt", "r");
if (input == 0) {
printf("ERROR couldn't open input.txt");
return 1;
}
if (! fscanf(input, "%d %d", &row, &column)) {
printf("ERROR not recognised value");
fclose(input);
return 2;
}
output = fopen("output.txt", "w");
int meteor[row][column];
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
fscanf(input, "%d", &meteor[i][j]);
}
}
int sum;
int loc[row];
for (int i = 0; i < row; i++) {
sum = 0;
for (int j = 0; j < column; j++) {
sum += meteor[i][j];
if (meteor[i][j] == 1) {
loc[i] = (j + 1);
}
}
printf("%d %d\n", loc[i], sum);
}
fclose(input);
fclose(output);
return 0;
}
My output is this :
3 1
3 1
3 1
0 0
-1 0
1 1
4 2
3 1
5 1
0 0
4214921 0
2 1
5 2
3 1
4 1
The first column shows some of the locations, the second shows how many 1s are in the row, but it all fails when there are only 0s in the row or there is more than one 1. And also I would like to store these values.
You need to initialize loc[].. If you look carefully at your code, you only populate it on the condition of if (meteor[i][j] == 1)... but you print it for every index of i. which would print uninitialized memory (i.e. unknown).
To answer the second part of your question, if you want to store the "sum". Simply make loc[] a 2d array just like meteor, but with 2 columns (row and sum). i.e. int loc[row][2].. making sure to initialize both columns of course :)

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));
}
}
}

iterative solution to permutation calculation in 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);
}

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

Resources