Matrix Multiplication - C - c

I created a program that does matrix addition,subtraction, and multiplication. I have handled the addition and subtraction portions, but when I reached the multiplication I am having trouble outputting the correct values. I have only placed the code with the multiplication function below.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int *elements;
int rows;
int columns;
} matrix;
void main() {
matrix a, b, c;
void read_matrix(matrix *);
void deallocate(matrix *);
void print(matrix);
matrix add(matrix, matrix);
matrix subtract(matrix, matrix);
matrix multiply(matrix, matrix);
read_matrix(&a);
read_matrix(&b);
/*
c = add(a, b);
printf("The answer of Matrix (a + b) is \n\n");
print(a);
printf("\n +\n\n");
print(b);
printf("\n =\n\n");
print(c);
printf("\n");
deallocate(&c);
c = subtract(a, b);
printf("The answer of Matrix (a - b) is \n\n");
print(a);
printf("\n -\n\n");
print(b);
printf("\n =\n\n");
print(c);
printf("\n");
deallocate(&c);
*/
c = multiply(a, b);
printf("The answer of Matrix (a * b) is \n\n");
print(a);
printf("\n *\n\n");
print(b);
printf("\n =\n\n");
print(c);
printf("\n");
}
void read_matrix(matrix *z) {
int d1, d2, allc, i, x, y, j, val;
int res;
printf("\nWhat is the first dimension of the array? ");
res = scanf("%d", &d1);
if (res != 1) {
fprintf(stderr, "Something went wrong with your first dimension!");
return;
}
printf("What is the second dimension of the array? ");
res = scanf("%d", &d2);
if (res != 1) {
fprintf(stderr, "Something went wrong with your second dimension!");
return;
}
printf("Matrix Dimension is %dx%d\n", d1, d2);
allc = d1*d2;
(*z).elements = (int *)calloc(allc, sizeof(int));
(*z).rows = d1;
(*z).columns = d2;
x = 0;
j = 0;
printf("\n");
for (i = 0; i < d1; i++) {
x++;
for (y = 0; y < d2; y++) {
printf("Enter the value for row %d column %d: ", x, y + 1);
res = scanf("%d", &val);
if (res != 1) {
fprintf(stderr, "Something went wrong while reading value %d\n", x);
return;
}
(*z).elements[j++] = val;
}
}
}
void deallocate(matrix *c) {
free((*c).elements);
(*c).elements = NULL;
(*c).rows = 0;
(*c).columns = 0;
}
void print(matrix z) {
int i, j, x;
x = 0;
for (i = 0; i < z.rows; i++) {
printf("[ ");
for (j = 0; j < z.columns; j++) {
printf("%-4d", z.elements[x++]);
}
printf("]\n");
}
}
matrix multiply(matrix a, matrix b) {
matrix c;
int a1, a2, b1, b2, allc, i, j, x, y, z, alc, addval, val;
i = 0;
j = 0;
alc = 0;
val = 0;
addval = 0;
a1 = a.rows;
a2 = a.columns;
b1 = b.rows;
b2 = b.columns;
allc = (a1 * b2);
c.elements = (int *)calloc(allc, sizeof(int));
c.columns = a1;
c.rows = b2;
if (a2 != b1) {
printf("\n\nThe inner dimensions of your matrices do not match! Multiplication cannot be done!\n\n");
exit(1);
}
for (x = 0; x < c.rows; x++) {
for (y = 0; y < c.rows; y++) {
for (z = 0; z < c.rows; z++) {
i = (i * c.rows);
addval = (a.elements[j]) * (b.elements[i]);
val += addval;
j++;
i++;
}
c.elements[alc] = val;
printf("VAL IS: %d\n\n", val);
val = 0;
i = 0;
alc++;
}
}
printf("\n\n");
return c;
}
In the multiplication function, the triple nested for loop is supposed to go through enough times to print out the correct number of items for the dimension of the new array. I am aware how to do matrix multiplication, but I am not sure if I have represented it correctly here.
The output for an example is:
What is the first dimension of the array? 3
What is the second dimension of the array? 3
Matrix Dimension is 3x3
Enter the value for row 1 column 1: 1
Enter the value for row 1 column 2: 2
Enter the value for row 1 column 3: 3
Enter the value for row 2 column 1: 4
Enter the value for row 2 column 2: 5
Enter the value for row 2 column 3: 6
Enter the value for row 3 column 1: 7
Enter the value for row 3 column 2: 8
Enter the value for row 3 column 3: 9
What is the first dimension of the array? 3
What is the second dimension of the array? 3
Matrix Dimension is 3x3
Enter the value for row 1 column 1: 1
Enter the value for row 1 column 2: 2
Enter the value for row 1 column 3: 3
Enter the value for row 2 column 1: 4
Enter the value for row 2 column 2: 5
Enter the value for row 2 column 3: 6
Enter the value for row 3 column 1: 7
Enter the value for row 3 column 2: 8
Enter the value for row 3 column 3: 9
The answer of Matrix (a * b) is
[ 1 2 3 ]
[ 4 5 6 ]
[ 7 8 9 ]
*
[ 1 2 3 ]
[ 4 5 6 ]
[ 7 8 9 ]
=
[ 216847534336951265054271]
[ 1641572693-138635672036124672]
[ 1352368309-50514195286739134]
Press any key to continue . . .

Below is my rework of your code that does matrix multiplication. The problem was with your multiply() function. You can see that it is doomed with it walking the a matrix by just incrementing the variable j - in a working solution every element of matrix a participates in the multiplication multiple times.
I also changed your routines to all pass pointers to matrix structures rather than your mix of passing pointers and passing/returning matrix structures directly by value. I think this is more consistent and easier to follow but it means you'll need to change your other matrix math routines to work the same, if you keep it this way.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int *elements;
int rows;
int columns;
} matrix;
void read_matrix(matrix *z) {
int d1, d2, val;
printf("\nWhat is the first dimension of the array? ");
int result = scanf("%d", &d1);
if (result != 1) {
fprintf(stderr, "Something went wrong with your first dimension!\n");
exit(1);
}
printf("What is the second dimension of the array? ");
result = scanf("%d", &d2);
if (result != 1) {
fprintf(stderr, "Something went wrong with your second dimension!\n");
exit(1);
}
printf("Matrix Dimension is %dx%d\n", d1, d2);
z->elements = calloc(d1 * d2, sizeof(int));
z->rows = d1;
z->columns = d2;
int x = 0;
int j = 0;
printf("\n");
for (int i = 0; i < d1; i++) {
x++;
for (int y = 0; y < d2; y++) {
printf("Enter the value for row %d column %d: ", x, y + 1);
result = scanf("%d", &val);
if (result != 1) {
fprintf(stderr, "Something went wrong while reading value (%d, %d)\n", x, y + 1);
exit(1);
}
z->elements[j++] = val;
}
}
}
void deallocate(matrix *c) {
free(c->elements);
c->elements = NULL;
c->rows = 0;
c->columns = 0;
}
void print(matrix *z) {
int x = 0;
for (int i = 0; i < z->rows; i++) {
printf("[ ");
for (int j = 0; j < z->columns; j++) {
printf("%-4d", z->elements[x++]);
}
printf("]\n");
}
}
void multiply(matrix *a, matrix *b, matrix *c) {
if (a->columns != b->rows) {
fprintf(stderr, "The inner dimensions of your matrices do not match! Multiplication cannot be done!\n");
exit(1);
}
c->elements = calloc(a->rows * b->columns, sizeof(int));
c->columns = b->columns;
c->rows = a->rows;
int alc = 0;
for (int x = 0; x < a->rows; x++) {
for (int y = 0; y < b->columns; y++) {
int value = 0;
for (int z = 0; z < b->rows; z++) {
value += a->elements[z + x * a->columns] * b->elements[y + z * b->columns];
}
c->elements[alc++] = value;
}
}
}
int main() {
matrix a, b, c;
read_matrix(&a);
read_matrix(&b);
multiply(&a, &b, &c);
printf("The answer of Matrix (a * b) is \n\n");
print(&a);
printf("\n *\n\n");
print(&b);
printf("\n =\n\n");
print(&c);
printf("\n");
deallocate(&a);
deallocate(&b);
deallocate(&c);
return 0;
}

Related

Concentric square matrix

I have coding problem to write concentric square matrix (biggest number is in the middle) For example user needs to write an matrix For example:
5 5 5 5 5
5 6 6 6 5
5 6 7 6 5
5 6 6 6 5
5 5 5 5 5
My program has to output "Yes" because this is, by my program's rules, a concentric square matrix.
5 5 5 5 5
5 6 6 6 5
5 6 7 8 5
5 6 6 6 5
5 5 5 5 5
This is not a concentric square matrix because 8 is in 4th column and 3rd row.
This is my code:
#include <stdio.h>
int main() {
int mat[100][100];
int i,j;
int n;
scanf("%d",&n);
printf("Unesite matricu; ");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&mat[i][j]);
}
}
}
I don't know how to do the rest of it so if someone can help me, I would be happy :))
Comment::
I forgot to say that only odd numbers can be the dimension of the matrix (1,3,11,27). The only final output of the program has to be "YES (if the matrix is a concentric square matrix) or "NO" (if it's not). I know how to make a concentric square matrix when the user inputs a number (for example, 4) and the matrix has 2*n-1 dimensions. And through the loops, the program automatically makes the matrix (if you know what I mean). But for my matrix, the user has to input all the elements of the matrix and the program has to check if the matrix is concentric or not.
Would you please try the following:
#include <stdio.h>
int main() {
int mat[100][100];
int ii[] = {0, 1, 0, -1}; // incremental numbers of i
int jj[] = {1, 0, -1, 0}; // incremental numbers of j
int i, j;
int n;
int u, v, w; // variables to walk on edges
int val; // value of the element
int prev; // previous value in one outer edge
int length; // length of the edge
// read matrix size and values
printf("Enter the number:\n");
scanf("%d", &n);
printf("Enter the matrix:\n");
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
scanf("%d", &mat[i][j]);
}
}
// loop on the edges
for (u = 0; u < n / 2; u++) { // from outmost edge to inner
i = u; j = u; // index of the north west corner
val = mat[u][u]; // initial value to compare
for (v = 0; v < 4; v++) { // four sides
length = n - u * 2 - 1; // length of the edge
for (w = 0; w < length; w++) {
i += ii[v]; // one step ahead on the edge
j += jj[v]; // same as above
if (mat[i][j] != val || (u > 0 && mat[i][j] <= prev)) {
// if u == 0, skip the comparison with prev
printf("No at [%d][%d] (val=%d)\n", i, j, mat[i][j]);
return 1;
}
}
}
prev = mat[i][j];
}
// finally examine the center value (if n is odd number)
if (n % 2) {
if (mat[u][u] <= prev) {
printf("No at [%d][%d] (val=%d)\n", u, u, mat[u][u]);
return 1;
}
}
printf("Yes\n");
return 0;
}
The basic concept is to generate a series of indexes of the edge
such as:
[0, 1], [0, 2], [0, 3], [0, 4],
[1, 4], [2, 4], [3, 4], [4, 4],
[4, 3], [4, 2], [4, 1], [4, 0],
[3, 0], [2, 0], [1, 0], [0, 0]
by using the variables i, j and the arrays ii[], jj[].
The example above is the indexes for the outermost edge and go into
the inner edge in the next iteration. Then the values of the index
is compared with the other value in the same edge and the previous
value in the outer edge.
[Edit]
Here is an alternative which does not use an array other than mat[100][100]:
#include <stdio.h>
int main() {
int mat[100][100];
int i, j;
int ii, jj; // incremental values for i and j
int n;
int u, v, w; // variables to walk on edges
int val; // value of the element
int prev; // previous value in one outer edge
int length; // length of the edge
// read matrix size and values
printf("Enter the number:\n");
scanf("%d", &n);
printf("Enter the matrix:\n");
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
scanf("%d", &mat[i][j]);
}
}
// loop on the edges
for (u = 0; u < n / 2; u++) { // from outmost edge to inner
i = u; j = u; // index of the north west corner
val = mat[u][u]; // initial value to compare
for (v = 0; v < 4; v++) { // four sides
ii = (v & 1) * ((v & 1) - (v & 2));
// assigned to {0, 1, 0, -1} in order
jj = ((v + 1) & 1) * (((v + 1) & 1) - ((v + 1) & 2));
// assigned to {1, 0, -1, 0} in order
length = n - u * 2 - 1; // length of the edge
for (w = 0; w < length; w++) {
i += ii; // one step ahead on the edge
j += jj; // same as above
if (mat[i][j] != val || (u > 0 && mat[i][j] <= prev)) {
// if u == 0, skip the comparison with prev
printf("No at [%d][%d] (val=%d)\n", i, j, mat[i][j]);
return 1;
}
}
}
prev = mat[i][j];
}
// finally examine the center value (if n is odd number)
if (n % 2) {
if (mat[u][u] <= prev) {
printf("No at [%d][%d] (val=%d)\n", u, u, mat[u][u]);
return 1;
}
}
printf("Yes\n");
return 0;
}
I created an answer using more functions than just main(). It is more verbose than what is required for your homework — it prints out the matrix it reads and diagnoses the first problem it comes across. It works with both positive and negative numbers, and with matrices with odd or even numbers of elements.
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
enum { MAT_SIZE = 100 };
static int err_error(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
exit(EXIT_FAILURE);
}
static int err_shell(int r, int c, int a_val, int e_val)
{
printf("Element M[%d][%d] = %d vs expected value %d\n", r, c, a_val, e_val);
return 0;
}
static int check_shell(int shell, int n, int matrix[MAT_SIZE][MAT_SIZE])
{
int lb = shell;
int ub = n - shell - 1;
int val = matrix[lb][lb];
/* Check the horizontals */
for (int c = lb; c <= ub; c++)
{
if (matrix[lb][c] != val)
return err_shell(lb, c, matrix[lb][c], val);
if (matrix[ub][c] != val)
return err_shell(ub, c, matrix[ub][c], val);
}
/* Check the verticals */
for (int r = lb; r <= ub; r++)
{
if (matrix[r][lb] != val)
return err_shell(r, lb, matrix[r][lb], val);
if (matrix[r][ub] != val)
return err_shell(r, ub, matrix[r][ub], val);
}
return 1;
}
static int check_matrix(int n, int matrix[MAT_SIZE][MAT_SIZE])
{
for (int i = 0; i <= n / 2; i++)
{
if (check_shell(i, n, matrix) == 0)
return 0;
}
for (int i = 0; i < (n - 1) / 2; i++)
{
if (matrix[i][i] >= matrix[i+1][i+1])
{
printf("Shell %d has value %d but inner shell %d has value %d\n",
i, matrix[i][i], i+1, matrix[i+1][i+1]);
return 0;
}
}
return 1;
}
static int read_size(void)
{
int n;
if (scanf("%d", &n) != 1)
err_error("failed to read an integer\n");
if (n <= 0 || n > MAT_SIZE)
err_error("matrix size %d is not in the range 1..%d\n", n, MAT_SIZE);
return n;
}
static void read_matrix(int n, int matrix[n][n])
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (scanf("%d", &matrix[i][j]) != 1)
err_error("failed to read M[%d][%d]\n", i, j);
}
}
}
static int max_field_width(int n, int matrix[MAT_SIZE][MAT_SIZE])
{
int min_val = matrix[0][0];
int max_val = matrix[0][0];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (matrix[i][j] < min_val)
min_val = matrix[i][j];
if (matrix[i][j] > max_val)
max_val = matrix[i][j];
}
}
int fld_width = snprintf(0, 0, "%d", max_val);
if (min_val < 0)
{
int min_width = snprintf(0, 0, "%d", min_val);
if (min_width > fld_width)
fld_width = min_width;
}
return fld_width;
}
static void print_matrix(const char *tag, int n, int matrix[MAT_SIZE][MAT_SIZE])
{
printf("%s (%d):\n", tag, n);
int w = max_field_width(n, matrix) + 1;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
printf("%*d", w, matrix[i][j]);
}
putchar('\n');
}
}
int main(void)
{
int matrix[MAT_SIZE][MAT_SIZE];
int n = read_size();
read_matrix(n, matrix);
print_matrix("Input", n, matrix);
if (check_matrix(n, matrix))
printf("YES: Matrix is a valid concentric matrix\n");
else
printf("NO: Matrix is not a valid concentric matrix\n");
return 0;
}
One detail is that this code can be made to use a VLA (variable-length array) by simply replacing MAT_SIZE by n in each function definition and modifying main() to read:
static int check_shell(int shell, int n, int matrix[n][n]) { … }
static int check_matrix(int n, int matrix[n][n]) { … }
static void read_matrix(int n, int matrix[n][n]) { … }
static int max_field_width(int n, int matrix[n][n]) { … }
static void print_matrix(const char *tag, int n, int matrix[n][n]) { … }
int main(void)
{
int n = read_size();
int matrix[n][n];
read_matrix(n, matrix);
print_matrix("Input", n, matrix);
if (check_matrix(n, matrix))
printf("YES: Matrix is a valid concentric matrix\n");
else
printf("NO: Matrix is not a valid concentric matrix\n");
return 0;
}
This reads the matrix size before allocating the matrix, instead of allocating a fixed size matrix first.
The read_size() function enables this change — that input must be done separately from the main matrix scanning code.

Why isn't the code coming out of recursion?

The problem is to find the number of times a word occurs in a given N x N matrix of alphabets. We can move from any cell to other adjacent cell. The first line has one integer N and then a N x N matrix. Next line has M (size of the word) and then a string to be found in the matrix.
Input:
4
ABCD
ABCD
ABCD
ABCD
2
BC
Expected output:
10
I have written the following code for the same and used recursion for solving the problem. The function adj checks if the character is adjacent in the matrix with the previous character using their indexes. The function check increases the count whenever the string is completed. The 2-d array keeps a check on the visited and unvisited elements.
I am getting the output as
OUPUT
1
EDIT 1: This output is just because of the debugging print statement, so the if statement is being visited only once. It does not mean that the count variable is 1 after many recursion calls.
EDIT 2: There shouldn't be & in the scanf statement for word. But still the output is not the desired one.
EDIT 3:
Another input
7
SHELDON
HSTYUPQ
EHGXBAJ
LMNNQQI
DTYUIOP
OZXCVBN
NQWERTY
7
SHELDON
Expected output:
5
My output - 1
EDIT 4(Solved!): So the problem was in writing the no. of columns as 500 for the grid matrix, changing it to 5 did the job! Thanks to #gsamaras
Code
#include <stdio.h>
int vis[500][500], count;
int adj(int a, int b, int c, int d) {
if((c == a - 1) && (d == b - 1)) {
return 1;
}
else if((c == a - 1) && (d == b)) {
return 1;
}
else if((c == a) && (d == b - 1)) {
return 1;
}
else if((c == a - 1) && (d == b + 1)) {
return 1;
}
else if((c == a + 1) && (d == b)) {
return 1;
}
else if((c == a + 1) && (d == b + 1)) {
return 1;
}
else if((c == a) && (d == b + 1)) {
return 1;
}
else if((c == a + 1) && (d == b - 1)) {
return 1;
}
else {
return 0;
}
}
void check(char grid[][500],int i, int j, int id, char word[], int n, int m) {
if(id == m) {
count++;
printf("%d\n", count); // just to debug
}
else {
for(int p = 0; p < n; p++) {
for(int q = 0;q < n; q++) {
if((grid[p][q] == word[id]) && (adj(i, j, p, q)) && (vis[p][q] != 1)) {
vis[p][q] = 1;
check(grid, p, q, id + 1, word, n, m);
vis[p][q] = 0;
}
}
}
}
}
int main() {
int n, m, id = 0;
char blank;
scanf("%d", &n);
scanf("%c", &blank);
char grid[n][n+1];
for(int i = 0; i < n; i++) {
scanf("%s", grid[i]);
grid[i][n] = '\0';
}
scanf("%d", &m);
char word[m+1];
scanf("%s", &word);
for(int i = 0; i < n; i++) {
for(int j = 0;j < n; j++) {
if(grid[i][j] == word[id]) {
vis[i][j] = 1;
check(grid, i, j, id + 1, word, n, m);
vis[i][j] = 0;
}
}
}
printf("%d\n", count);
return 0;
}
Change this:
void check(char grid[][500], ......
to this:
void check(char grid[][5], ....... // that should be equal to N + 1 (5 in your case)
since your grid is of size N x N + 1. With the 500 as the dimension, you distorted the grid, and when trying to search into it recursively, you wouldn't traverse the grid that you would expect to traverse..
As you see this is not flexible, since N can vary. You cannot declare grid as global, since its dimensions are not fixed. Dynamic memory allocation should be used instead.
Change this:
scanf("%s", &word);
to this:
scanf("%s", word);
since word is an array of characters.
Complete example with Dynamic Memory Allocation:
#include <stdio.h>
#include <stdlib.h>
int vis[500][500], count;
char **get(int N, int M) { /* Allocate the array */
int i;
char **p;
p = malloc(N*sizeof(char *));
for(i = 0 ; i < N ; i++)
p[i] = malloc( M*sizeof(char) );
return p;
}
void free2Darray(char** p, int N) {
int i;
for(i = 0 ; i < N ; i++)
free(p[i]);
free(p);
}
int adj(int a, int b, int c, int d) {
// Same as in your question
}
void check(char** grid, int i, int j, int id, char word[], int n, int m) {
if(id == m) {
count++;
printf("count = %d\n", count); // just to debug
}
else {
for(int p = 0; p < n; p++) {
for(int q = 0;q < 499; q++) {
//printf("p = %d, q = %d, id = %d, grid[p][q] = %c, word[id] = %c\n", p, q, id, grid[p][q], word[id]);
if((grid[p][q] == word[id]) && (adj(i, j, p, q)) && (vis[p][q] != 1)) {
vis[p][q] = 1;
check(grid, p, q, id + 1, word, n, m);
vis[p][q] = 0;
}
}
}
}
}
int main() {
int n, m, id = 0;
char blank;
scanf("%d", &n);
scanf("%c", &blank);
char** grid = get(n, n + 1);
for(int i = 0; i < n; i++) {
scanf("%s", grid[i]);
grid[i][n] = '\0';
}
scanf("%d", &m);
char word[m+1];
scanf("%s", word);
for(int i = 0; i < n; i++) {
for(int j = 0;j < n; j++) {
//printf("i = %d, j = %d, id = %d\n", i, j, id);
if(grid[i][j] == word[id]) {
vis[i][j] = 1;
check(grid, i, j, id + 1, word, n, m);
vis[i][j] = 0;
}
}
}
printf("%d\n", count);
free2Darray(grid, n);
return 0;
}
Output (for your 1st input):
count = 1
count = 2
count = 3
count = 4
count = 5
count = 6
count = 7
count = 8
count = 9
count = 10
10
PS: Not a problem, just a suggestion about readability: count is initialized to 0, because it's a global variable, but it's always best to explicitly initialize your variables, when it matters.

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.

“Fun with Rotation” - Codechef September Long Challenge

Whatz wrong with that answer?Plz help me
question is:
You are given an array A of N integers. You are to fulfill M queries. Each query has one of the following three types:
C d : Rotate the array A clockwise by d units.
A d : Rotate the array A anticlockwise by d units.
R d : Query for the value of the element, currently being the d-th in the array A.
Input
The first line contains two numbers - N and M respectively.
The next line contains N space separated Integers, denoting the array A.
Each of the following M lines contains a query in the one of the forms described above.
Output
For each query of type R output the answer on a separate line.
Constraints
1 ≤ N ≤ 100000
1 ≤ M ≤ 100000
1 ≤ d ≤ N, in all the queries
1 ≤ elements of A ≤ 1000000
The array A and the queries of the type R are 1-based.
Example
Input:
5 5
5 4 3 3 9
R 1
C 4
R 5
A 3
R 2
Output:
5
3
3
Solution:
#include<stdio.h>
//#include<iostream>
//using namespace std;
int a[100001];
int index=0,n;
void clock(int);
void ant_clock(int);
void display(int);
int main()
{
unsigned int i,m;
char x;
int y;
scanf("%d %d",&n,&m);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
while(m--)
{
scanf(" %c%d",&x,&y);
if(1 <= y <= n)
{
if(x=='R')
display(y);
else if(x=='A')
ant_clock(y);
else if(x=='C')
clock(y);
}
else
return 0;
}
return 0;
}
void display(int y)
{
int j=index,x=0;
while(1)
{
if(x==y-1)
break;
j++;
x++;
if(j==n)
j=0;
}
printf("%d",a[j]);
}
void ant_clock(int y)
{
int j;
for(j=0;j<y;j++)
{
index--;
if(index==-1)
index=n-1;
}
}
void clock(int y)
{
int j;
for(j=0;j<y;j++)
{
index++;
if(index==n)
index=0;
}
}
It seems to be a problem with the query indices being 1-based. And your code has unnecessary loops in it.
#include <stdio.h>
int arr[100000];
int main() {
int base = 0, size, i, m;
char x;
scanf("%d%d", &size, &m);
for (i = 0; i < size; i++)
scanf("%d", &arr[i]);
while (m-- > 0) {
scanf(" %c%d", &x, &i);
if (x == 'R') {
printf("%d\n", arr[(base + i - 1) % size]);
} else if (x == 'A') {
if ((base -= i) < 0)
base += size;
} else if (x == 'C') {
base = (base + i) % size;
}
}
return 0;
}

Finding submatrix in one dimensional array - C

Good day,
I need a help. We get a homework to write a programme in C which should generate and print bigger and smaller matrix made from "X" and ".". And after that find if the smaller 3x3 matrix is in the bigger one. I tried to make it by one dimensional field, but my programme finds matrix only sometimes. I am not able to find it out where is my mistake and how to fix it. I read some threads on forum, but none of it was helpfull to me. Thanks for any help.
P.S. Forgive me language mistakes, I am not a native english speaker.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* Generates matrix of given dimensions */
void initMatrix(char *Matrix, int rows, int cols)
{
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols; j++)
{
Matrix[i*cols+j]= "X.." [rand () % 3]; // 2/3 that X will be generated
}
}
}
/* Prints given matrix */
void printMatrix(char *Matrix, int rows, int cols)
{
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols; j++)
{
printf("%c", Matrix[i * cols + j]);
}
printf("\n");
}
}
int main(void)
{
int rowM1, colM1; // Dimensions of primary (bigger) matrix
int rowM2 = 3, colM2 = 3; // Dimensions of secondary (smaller) matrix
int first, second; // Position of the begginng of matrix 2 in matrix 1
int rel_pos;
int i, j, k, l;
char *M1 = NULL; // Pointer to matrix 1
char *M2 = NULL; // Pointer to matrix 2
printf("Enter the matrix dimensions separated by a space ([rows] [columns]) : ");
if (scanf("%d %d", &rowM1, &colM1) != 2) // Bad parameters
{
printf("Wrong parameters.");
return 1; // End program
}
if (rowM1 < rowM2 || colM1 < colM2)
{
printf("Matrix 2 can not be found because is bigger than Matrix 1.");
return 1;
}
srand(time(NULL)); // Randomly generates numbers
M1 = malloc(rowM1 * colM1 * sizeof(char)); // M1 points to matrix 1
M2 = malloc(rowM2 * colM2 * sizeof(char)); // M2 points to matrix 2
initMatrix(M1, rowM1, colM1); // Initializes matrix 1
initMatrix(M2, rowM2, colM2); // Initializes matrix 2
printf("\nMatrix 1:\n");
printMatrix(M1, rowM1, colM1); // Prints matrix 1
printf("\nMatrix 2:\n");
printMatrix(M2, rowM2, colM2); // Prints matrix 2
putchar('\n');
for (i = 0; i < rowM1; i++)
{
for(j = 0; j < colM1; j++){
{
for (k = 0; k < rowM2 * colM2; k++) // checking the smaller matrix
{
if(M1[i*rowM1+j] == M2[k])
{
first = i*rowM1;
rel_pos = i+1;
}
if(j % colM2 == 0) // Matrix 2 has ended on this line, move on next one.
rel_pos += colM1 - colM2;
if(M1[rel_pos] == M2[j]) // If character are same, keep searching
rel_pos++;
else // else this is not the matrix I'm searching for
break;
}
if(k == rowM2*colM2) // if all k cykle went to the end I found the matrix
{
printf("Matrix found at [%d][%d]", first, second);
return 0;
}
}
}
if(i*colM1 > i*colM1-colM2) // matrix cannot be found
printf("Matrix not found");
break;
}
free(M1); // frees memory of matrix 1
free(M2); // frees memory of matrix 2
return 0;
}
Your inner loop for (k = 0; k < rowM2 * colM2; k++) iterates over the contents of the small matrix, and should compare each entry of the small matrix to the corresponding entry in the large matrix (as defined by the start point given by i and j).
The comparison if(M1[i*rowM1+j] == M2[k]), however, compares all entries of the small matrix with the same entry in the large matrix (the array index of M1 is independent of k).
To fix this, you need to make a fourdimensional loop
for(y0 = 0; y0 < colM1 - colM2 + 1; y0++) {
for(x0 = 0; x0 < rowM1 - rowM2 + 1; x0++) {
for(dy = 0; dy < colM2; dy++) {
for(dx = 0; dx < rowM2; dx++) {
if(M1[(y0 + dy)*rowM1 + (x0 + dx)] == M2[dy*rowM2 + dx]) {
...
}
}
}
}
}

Resources