How do I rotate a matrix? C [closed] - c

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 3 years ago.
Improve this question
I want a matrix to rotate right. It's working for a square matrix, but i should also work for non square matrix.
I tried rotating it, but i couldn't think of a way to get it to work for non square matrix.
#include <stdio.h>
#define x 7
#define y 7
int build() {
int i = 0, k = 0;
int matrix[x][y];
for (i = 0; i < x; ++i) {
for (k = 0; k < y; ++k) {
matrix[i][k] = i;
}
}
for (i = 0; i < x; ++i) {
for (k = 0; k < y; ++k) {
printf("\t%d", matrix[k][i]);
}
printf("\n");
}
return matrix[i][k];
}
int turn()
{
int i = 0, k = 0;
int matrix[x][y];
for (i = 0; i < x; ++i) {
for (k = 0; k < y; ++k) {
matrix[i][k] = i;
}
}
for (i = 0; i < x; ++i) {
for (k = 0; k < y; ++k) {
printf("\t%d", matrix[i][k]);
}
printf("\n");
}
}
int main()
{
build();
printf("\t\n");
turn();
}
i want it to work for diffrent variables like x=5 and y=7.
My thought was to rotate the matrix by 90 degrees.
from
0 0 0 0
1 1 1 1
2 2 2 2
to
2 1 0
2 1 0
2 1 0
2 1 0

80% of work is declaring your functions and understanding what the declarations mean. You can start like this:
#define x 5
#define y 7
void build(int output[y][x]);
This declares a function build, which receives a matrix, and fills it with the needed data. Note: it doesn't return anything (i.e. returns void); instead of returning the data, it receives the pointer which it should write to. This is standard practice in C, because you cannot return arrays from functions.
I didn't write the code for it yet because it would distract you from understanding the flow of information in your program:
int main()
{
int matrix_before_rotation[y][x];
build(matrix_before_rotation);
}
This hypothetical program fills a matrix with values, using your function. It doesn't print it, but you could see the values if you used e.g. a debugger.
To declare a function which does the rotation:
void turn(int input[y][x], int output[x][y]);
Note the difference in dimensions, and the fact that the function receives two arguments - one for input, and one for output. You need to allocate two matrices in your main program:
int main()
{
int matrix_before_rotation[y][x];
int matrix_after_rotation[x][y];
build(matrix_before_rotation);
turn(matrix_before_rotation, matrix_after_rotation);
}
Given this code structure, it's easy to fill in the implementation details.
You might want to add a function for printing a matrix while you are debugging your program:
#define x 5
#define y 7
void build(int output[y][x]);
void turn(int input[y][x], int output[x][y]);
void print(int height, int width, int input[height][width]);
int main()
{
int matrix_before_rotation[y][x];
int matrix_after_rotation[x][y];
build(matrix_before_rotation);
print(y, x, matrix_before_rotation);
turn(matrix_before_rotation, matrix_after_rotation);
print(x, y, matrix_after_rotation);
}
Note: the printing function is more generic than the generating and the rotating functions - it knows how to work with matrices of any dimensions. You need it because you need at least two types of matrices in your new program - [7][5] and [5][7]. You can use this idea to generalize your rotating function so it could work with matrices of any dimensions.

Just a little modification to your code
#include <stdio.h>
#define x 3
#define y 4
int build() {
int i = 0, k = 0;
int matrix[x][y];
for (i = 0; i < x; ++i) {
for (k = 0; k < y; ++k) {
matrix[i][k] = i;
}
}
for (i = 0; i < x; ++i) {
for (k = 0; k < y; ++k) {
printf("\t%d", matrix[i][k]);
}
printf("\n");
}
return matrix[i][k];}
//for right turn you will have to modify the loop like this
int r_turn()
{
int i = 0, k = 0;
int matrix[x][y];
for(i=0; i<y; i++) //for outer loop, take y, because you're rotating
//loop , and y will come before x
{
for(k=x-1; k>=0; k--) //thereby, x goes after y
{
matrix[k][i] = k;
}
}
for(i=0; i<y; i++) //printing matrix in the same way we wrote
{
for(k=x-1; k>=0; k--) //here, k will start from k because
//index starts from 0
{
printf("\t%d", matrix[k][i]);
}
printf("\n");
}
}
int main()
{
build();
printf("\t\n");
r_turn();
}

Related

Am I initializing correctly the state of a matrix in C language?

I'm simulating a square surface that "traps" molecules in C and, I don't know if it's correctly initialized. I want in the beginning of the whole simulation that the grid is totally empty (without any molecule on it) so that it can start to trap the mentioned molecules.
But, when I generate randomly the coordinates of an entry and start checking if the lattice is empty ( to attempt adding molecules to it later on), it seems that every entry the program choose is already "occupied" and I can't see why since I haven't added anything so far.
The following is my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//define the dimensions of the latice
#define xmax 2
#define ymax 2
//Define parameters to obtain both the x and y coordinates of a site in the lattice at random
#define LOWER 0
#define UPPER xmax-1
#define ALTO ymax-1
#define CONTAR 1
//we define the Monte Carlo steps
#define MCSS 100
//define the "empty" and "occupied" states
#define empty 0
#define occupied 1
//define the grid or lattice we will working with
int grid[xmax][ymax];
//Function that selects the x-coordinate of the chosen site randomly
int printrandomx(int lower, int upper, int cuenta)
{
int m, num1;
for (m = 0; m < cuenta ; m++) {
num1 = (rand() % (upper - lower + 1)) + lower;
}
return num1;
}
//Function that selects the y-coordinate of the chosen site randomly
int printrandomy(int bajo, int alto, int contar)
{
int n,num2;
for (n = 0; n < contar; n++) {
num2 = (rand() % (alto - bajo + 1)) + bajo;
}
return num2;
}
//Function that generates the random coordinates of a site in the lattice
int generate_coords(int red[xmax][ymax]){
int x_coord, y_coord;
int count = 1;
for (int i = 0; i < xmax; i++) {
for (int j = 0; j < ymax; j++) {
red[i][j] = count++;
printf("%d ", red[i][j]);
}
printf("\n");
}
x_coord = printrandomx(LOWER, UPPER, CONTAR);
y_coord = printrandomy(LOWER, ALTO, CONTAR);
printf("(x,y)=(%d,%d)\n\n", y_coord, x_coord);
for (int i = 0; i < xmax; i++)
{
for (int j = 0; j < ymax; j++ )
{
if(x_coord == i && y_coord == j){
red[y_coord][x_coord] == count;
}
}
}
printf("The coordinates are (%d,%d) and the solicited matrix entry is: %d\n\n", y_coord, x_coord, grid[y_coord][x_coord]);
if (x_coord > xmax || x_coord < 0 || y_coord > ymax || y_coord < 0) {
printf ("Invalid coordinates given\n");
return 1;
}
}
//Here starts the main function
int main(){
srand(time(0));
int N = xmax*ymax;
int x = 0, y = 0;
// Initialize lattice to be empty
for (int i = 0; i < xmax; i++) {
for (int j = 0; j < ymax; j++) {
grid[j][i] = empty;
}
}
//LOCATE AN ENTRY OF THE MATRIX RANDOMLY
generate_coords(grid);
//EVALUATE IF THE CHOSEN SITE IS EITHER EMPTY OR OCCUPIED
printf("IS IT OCCUPIED???\n\n");
if (grid[y][x] == empty){
printf("It's empty. Let's fill it with a molecule\n\n");
printf("Here I will specify other conditions :)\n\n");
}else{
printf("It's occupied, the trial ends. Choose another site again\n\n");
generate_coords(grid);
}
return 0;
}
The chunk of the code that must set the initial array as empty is the following:
// Initialize lattice to be empty
for (int i = 0; i < xmax; i++) {
for (int j = 0; j < ymax; j++) {
grid[j][i] = empty;
}
}
However, it seems doesn't work and I don't know why.
Yes, you are doing it right. In this case it's a global variable so it's already initializes and you overwrite all the values in generate_coords() so it doesn't really matter.
As grid is a global variable it's implicitly zero initialized. You don't have to do anything. I recommend you avoid global variables, though, it makes your code harder to change.
If grid was a local variable (recommended) you can zero initialize it because xmax and ymax are constants:
int grid[xmax][ymax] = { 0 };
If grid xmax and ymax are variables (opposed to constants), grid would be a vla, and you now assign values to it with memset() (or memcpy() etc):
memset(grid, 0, sizeof grid);
Or, as you did, an double loop. Consider using more descriptive index variables, in this case, perhaps x and y?
for (size_t x = 0; x < xmax; x++) {
for (size_t y = 0; y < ymax; y++) {
grid[x][y] = empty;
}
}
That answers the question you asked, however, I don't know wat question you meant to ask.
I refactored your code which will probably be surprising to you. Left out most of the printf() calls as they x and y when accessing the grid. Also left out the 2nd call to generate_corrds() as it seems like you wanted to run part of main() in a loop anyways.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define xmax 2
#define ymax 2
int rand_min_max(int min, int max) {
return rand() % (max - min) + min;
}
void grid_print(int grid[xmax][ymax]) {
for (int x = 0; x < xmax; x++)
for (int y = 0; y < ymax; y++)
printf("%d%s", grid[x][y], y + 1 < ymax ? " " : "\n");
}
void generate_coords(int grid[xmax][ymax]) {
memcpy(grid, (int [xmax][ymax]) {{1,2}, {3,4}}, sizeof(int [xmax][ymax]));
int x = rand_min_max(0, xmax);
int y = rand_min_max(0, ymax);
grid[x][y] = xmax + ymax + 1; // x and y swapped in original code, doesn't matter here but if xmax != ymax it would matter.
}
int main() {
srand(time(0));
int grid[xmax][ymax];
generate_coords(grid);
grid_print(grid);
printf("IS IT OCCUPIED???\n\n");
printf("It's occupied, the trial ends. Choose another site again\n\n");
}
and here is sample output:
1 5
3 4
IS IT OCCUPIED???
It's occupied, the trial ends. Choose another site again

Automatically filling an array

I want to define two variables called x and y.
Depending on that the program shall fill the array from 0 to x and from 0 to y.
I tried filling it with a for and it's kind of working, but I can't print it out properly.
#include <stdio.h>
#define x 4
#define y 4
void build(){
int i=0, k=0;
int matrix[x][y];
for (i = 0; i < x; ++i) {
for (k = 0; k < y; ++k) {
matrix[i][k] = i;
matrix[i][k] = k;
}
}
printf("\t\n%d\n", matrix[x][y]);
}
I expect an array looking like this in the console.
0 1 2 3
0 1 2 3
0 1 2 3
0 1 2 3
You see, in order to print an array you will have to loop over the whole data. You can't print an array in that simple a way in C.
What your code is printing is a garbage value, because at index 4,4 your array has no value. Its indexes go from 0,1..3 in both x and y direction.
Hope it helps.
#include <stdio.h>
#define x 4
#define y 4
void main(){
int i=0, k=0;
int matrix[x][y];
for (i = 0; i < x; ++i) {
for (k = 0; k < y; ++k) {
matrix[i][k] = i ;
}
}
for (i = 0; i < x; ++i) {
for (k = 0; k < y; ++k) {
printf("\t%d", matrix[i][k]);
}
printf("\n");
}
}
In C there is no way to print an array in one go. You have to loop through each element of the array and print it.
for(int i = 0; i < x; ++i){
for(int j = 0; j < y; ++j){
printf("%d ", matrix[i][j]);
}
printf("\n");
}
I have tried to guess at your misunderstandings and commented and edited your code to make an explanation of how it works and what you need to understand.
#include <stdio.h>
#define x 4
#define y 4
void build(){
int i=0, k=0;
int matrix[x][y]; // top allowed indexes are x-1 and y-1
for (i = 0; i < x; ++i) {
for (k = 0; k < y; ++k) {
matrix[i][k] = i; // first write getting ignored/overridden by next
matrix[i][k] = k;
// printing here gets you many values, note the removed \n
printf("\t%d", matrix[i][k]);
}
// printing line break here gets you lines instead of single values
printf("\n");
}
// not inside any loop, so only one %d value gets printed
// printf("\t\n%d\n", matrix[x][y]); // accessing beyond both dimension
// also your attempt to let printf figure out how to print the whole 2D array,
// at least that is what I think you try, does not work in C
}

Issues involving a function with an array (For task calculating matrix determinants)

I'm having issues getting a function to work which should find the determinant of an upper triangular matrix. My code seems to return clearly incorrect values, usually zero and I'm pretty certain that this is caused by me defining the function incorrectly some how. I suspect it is a basic error on my part but after staring at it for sometime I havent managed to figure it out. Here is the function and printing code:
int Determinant(int mat[20][20],int N)
{
int X=0,Det=0;
if (N==2){
Det=mat[0][0]*mat[1][1]-mat[0][1]*mat[1][0];
return(Det);
}
else {
for(X = 0; X < N; X++){
Det *= mat[X][X];
}
}
return (Det);
}
and the print function :
determinant=Determinant(matrix,n);
printf("Determinant = %d",determinant);
I'll include the full code that I've written so far to provide more detail. It's basic application at the moment is to define and n by n matrix (2
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int determinant(int mat[20][20],int N);
int Determinant(int mat[20][20],int N)
{
int X=0,Det=0;
if (N==2){
Det=mat[0][0]*mat[1][1]-mat[0][1]*mat[1][0];
return(Det);
}
else {
for(X = 0; X < N; X++){
Det *= mat[X][X];
}
}
return (Det);
}
int main()
{
int n=0,i=1;
printf("Please enter a number (n) between 2 and 4 to determine the dimensions of an (nxn) matrix \n");
scanf("%d",&n);
while(n<2||n>4){
printf("The value %d does not lie within the required range of 2-4, please re-enter \n",n);
scanf("%d",&n);
i++;
if (i>=3){
printf("\nYou have entered invalid values 3 times. The programme has been terminated");
exit(0);
}
}
printf("\n(%dx%d) matrix selected\n",n,n);
int matrix[n][n];
int f,g=0;
printf("Please enter matrix elements\n");
for(f=0;f<n;f++){
for(g=0;g<n;g++){
printf("Element[%d][%d] = ",f,g);
scanf("%d",&matrix[f][g]);
}
}
int k,j;
printf("\nThe matrix is\n");
for(k=0;k<n;k++){
printf("\n");
for(j=0;j<n;j++){
printf("%d\t",matrix[k][j]);
}
}
int temp=0,c=0,determinant=0;
float factor=0;
k=0;
/* Transform matrix into upper triangular */
for(i = 0; i < n - 1; i++)
{
/* Elementary Row Operation I */
if(matrix[i][i] == 0)
{
for(k = i; k < n; k++)
{
if(matrix[k][i] != 0)
{
for(j = 0; j < n; j++)
{
temp = matrix[i][j];
matrix[i][j] = matrix[k][j];
matrix[k][j] = temp;
}
k = n;
}
}
c++;
}
/* Elementary Row Operation III */
if(matrix[i][i] != 0)
{
for(k = i + 1; k < n; k++)
{
factor = -1.0 * matrix[k][i] / matrix[i][i];
for(j = i; j < n; j++)
{
matrix[k][j] = matrix[k][j] + (factor * matrix[i][j]);
}
}
}
}
printf("\nThe Upper triangular is\n");
for(k=0;k<n;k++){
printf("\n");
for(j=0;j<n;j++){
printf("%d\t",matrix[k][j]);
}
}
determinant=Determinant(matrix,n);
printf("Determinant = %d",determinant);
/*
*/
return 0;
}
The problem is basically the way you pass the matrix as a parameter. To see what I mean, change the definition of the function to read:
int Determinant(int mat[5][5],int N);
and instruct the function body to print the full 5x5 matrix passed:
int Determinant(int mat[5][5],int N)
{
printf("\n");
int a,b;
for(a = 0; a < 5; a++)
{
for(b = 0; b < 5; b++)
{
printf("%d\t", mat[a][b]);
}
printf("\n");
}
int X=0,Det=0;
Det = 1; // Add this too!
for(X = 0; X < N; X++) {
Det *= mat[X][X];
}
return (Det);
}
Now enter n=3 for the matrix dimension and pass the already upper triangular matrix
1 2 3
0 4 5
0 0 6
Observe the printout of the matrix passed in the Determinant() function, it will be something like this:
1 2 3 0 4
5 0 0 6 0
4196432 0 -163754450 0 -1253168992
32764 3 0 0 0
3 0 0 0 3
This means that your array has been "reshaped", and your actual data are stored in consecutive places in memory, unlike the original array.
TLDR: Although I am not very proficient with C, I think that you should define your 2d array as a dynamic one (for example using a double pointer).
PS: Don't forget to initialize Det variable to 1 instead of 0 in the function body, otherwise the product will always equal 0.

How do I figure out what is wrong with my code when the output is correct? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am new to programming and I am trying to solve 929-Number Maze on UVA-online judge and I wrote this code and it is working fine in code blocks but when I submit this code on uva-online judge it shows Runtime error and I just can't figure out what I am doing wrong.
#include <stdio.h>
#include <stdlib.h>
int min(int x, int y);
int minCost(int **cost, int m, int n) {
int i, j;
int tc[m][n];
tc[0][0] = cost[0][0];
for (i = 1; i < m; i++) {
tc[i][0] = tc[i - 1][0] + cost[i][0];
}
for (j = 1; j < n; j++) {
tc[0][j] = tc[0][j - 1] + cost[0][j];
}
for (i = 1; i < m; i++) {
for (j = 1; j < n; j++) {
tc[i][j] = min(tc[i - 1][j], tc[i][j - 1]) + cost[i][j];
}
}
return tc[m - 1][n - 1];
}
int min(int x, int y) {
if (x < y)
return x;
else
return y;
}
int main() {
int t, a, b, M, N, k;
scanf("%d", &t);
while (t--) {
scanf("%d", &M);
scanf("%d", &N);
int **c = (int **)malloc(sizeof(int*) * M);
for (k = 0; k < N; k++)
*(c + k) = (int *)malloc(sizeof(int) * M);
for (a = 0; a < M; a++) {
for (b = 0; b < N; b++) {
scanf("%d", &c[a][b]);
}
}
int res = minCost(c, M, N);
printf("%d", res);
}
return 0;
}
input:
2
4
5
0 3 1 2 9
7 3 4 9 9
1 7 5 5 3
2 3 4 2 5
1
6
0 1 2 3 4 5
output:
24
15
*(c+k) = (int*)malloc(sizeof(int)*N);
This should be N
One issue is in
*(c+k) = (int*)malloc(sizeof(int)*M);
It should be
*(c+k) = malloc(sizeof(int)*N); //N instead of M
Welcome to the wonderful world of programming.
A careful code review shows this error:
The initialization loop is incorrect in both the loop test and the malloc argument, it should read:
for (k = 0; k < M; k++) {
c[k] = malloc(sizeof(int) * N);
}
As posted, your program invokes undefined behavior. It may produce the expected results by chance (as observed on your system), but it may also produce a runtime error when you access the arrays beyond the allocated size (as observed on the uva-online judge site).

Extending inner for loop calls indefinitely [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
The following code snippet will print every 4 character long combination (without repetition) of the elements of an array.
for (int i = 0; i < len; i++)
for (int j = i + 1; j < len; j++)
for (int k = j + 1; k < len; k++)
for (int l = k + 1; l < len; l++)
printf("%c%c%c%c\n", arr[i], arr[j], arr[k], arr[l]);
My problem is I don't know how to extend this to a general function (ie print every N character long combination). How can I make a function do the same thing but be called like this:
combinationPrint(array, numberOfForLoops); // With other params if needed
The recursive version of your function would work like this:
void recur (char* arr, int i, int len, char *x, int k, int n) {
if (k==n) { // the last inner loop
x[k]=0;
printf ("%s\n", x);
}
else {
for (int j=i+1; j<len; j++) { // recursive loop
x[k]=arr[j];
recur (arr, j, len, x, k+1, n); // call recursion for an inner loop
}
}
}
In this recursion, arr and len correspond to your definition and n is the depth of the loops you want to achieve (4 in your non recursive version).
The trick is to use a null terminated array of n+1 chars, that you keep across the recursion and build the string that you want to print at the last level. i is then the starting position of the loop and k is the current level of recursion.
You would call this:
recur (arr, -1, len, out, 0, 4 );
Online demo
Without recursion, you can use this (len = length of the array) :
int i, j, w, x;
for(i=0; i<pow(len,len); i++){ //n^n possibilities / combinaisons
w = i;
for(j=0; j<len; j++){ //Show the combinaison
x = w%len; //We have juste to calculate the correct position with some modulos
printf("%c", array[x]);
w = w/len;
}
printf("\n");
}
For exemple with this implementation :
#include <stdio.h>
#include <math.h>
int main(){
int array[] = {1,2,3};
int len = 3;
int i, j, w, x;
for(i=0; i<pow(len,len); i++){
w = i;
for(j=0; j<len; j++){
x = w%len;
printf("%d", array[x]);
w = w/len;
}
printf("\n%d\n", i);
}
}
You should have :
111
211
311
121
221 [...]
133
233
333
Well, instead of N loops - you just need one. Within this main loop you have to have just two inner loops for incrementing array of indices and for printing values:
int increment(int* index, int N, int len)
{
for (int i = N - 1; i >= 0; --i)
{
++index[i];
if (index[i] < len)
return 1;
index[i] = 0;
}
return 0;
}
So - the main loop:
int index[N] = {};
do
{
// print
for (int i = 0; i < N; ++i)
printf("%c", arr[index[i]]);
printf("\n");
} while (increment(index, N, len));

Resources