what is the better way to loop this problem? - c

#include <stdio.h>
int main()
{
int arr[9][9];
int i = 0, x = 10;
for (int i = 0, j = 0; j <= 8; j++) {
x++;
arr[i][j] = x;
}
for (int j = 8, i = 1; i <= 8; i++) {
x++;
arr[i][j] = x;
}
for (int i = 8, j = 7; j >= 0; j--) {
x++;
arr[i][j] = x;
}
for (int j = 0, i = 7; i >= 1; i--) {
x++;
arr[i][j] = x;
}
for (int i = 1, j = 1; j <= 7; j++) {
x++;
arr[i][j] = x;
}
for (int j = 7, i = 2; i <= 7; i++) {
x++;
arr[i][j] = x;
}
for (int i = 7, j = 6; j >= 1; j--) {
x++;
arr[i][j] = x;
}
for (int j = 1, i = 6; i >= 2; i--) {
x++;
arr[i][j] = x;
}
...
arr[4][4] = x + 1;
for (int i = 0; i <= 8; i++) {
for (int j = 0; j <= 8; j++)
printf("%d ", arr[i][j]);
printf("\n");
}
getch();
}
so I have this program, and I know you can loop it but how ? been sitting for an hour thinking and nothing came to my mind. By the way, the task is to append a matrix like on picture. Does anyone know to do it ? Maybe use some complex for loop

Here's one way to do it:
int arr[9][9] = {0};
int x = 0, i = 0, j = 0, vi = 0, vj = 1;
do {
++x;
arr[i][j] = x;
{
int ii = i+vi;
int jj = j+vj;
if (ii < 0 || ii >= 9 || jj < 0 || jj >= 9 || arr[ii][jj] != 0) {
if (vi != 0) {
vj = -vi;
vi = 0;
} else {
vi = vj;
vj = 0;
}
}
}
i = i+vi;
j = j+vj;
} while (arr[i][j] == 0);
Live on Coliru
Here's another way:
int arr[9][9] = {0};
int x = 0, i = 0, j = 0, vi = 0, vj = 1, lk = 8;
while (lk > 0) {
for (int k = 0; k < lk; ++k) {
++x;
arr[i][j] = x;
i += vi;
j += vj;
}
vi = vj;
vj = 0;
for (int k = 0; k < lk; ++k) {
++x;
arr[i][j] = x;
i += vi;
j += vj;
}
vj = -vi;
vi = 0;
if (vj > 0) {
++i;
++j;
lk -= 2;
}
}
arr[9/2][9/2] = x+1; // Only if odd dimensions
Live on Coliru
And here is yet another:
int arr[9][9] = {0};
int i = 0, lk = 8, x = 1;
while (lk > 0) {
for (int k = 0; k < lk; ++k) {
arr[i][i+k] = x + k;
arr[i+k][lk+i] = x + lk + k;
arr[lk+i][lk+i-k] = x + 2*lk + k;
arr[lk+i-k][i] = x + 3*lk + k;
}
x += 4*lk;
lk -= 2;
++i;
}
arr[9/2][9/2] = x; // Only if odd dimensions
Live on Coliru

Here is the "straight forward" option with for loops:
#include <stdio.h>
#define N 5
int main(void) {
int i,j,dim;
int matrix[N][N];
// init and print the matrix
for (i=0; i < N; i++)
{
for (j=0; j< N; j++)
{
matrix[i][j] = i*N + j;
printf("%2d ", matrix[i][j]);
}
printf("\n");
}
printf("\n");
// perform spiral print
for (dim = 0; dim < (N+1)/2; dim++)
{
// set initial i and go till the "last column"
i = dim;
for (j = dim; j < N - dim; j++)
{
printf("%2d ", matrix[i][j]);
}
printf("\n");
// bring back i and j to the proper coordinate
// and move down to the "last row"
j--;i++;
for (; i < N - dim; i++)
{
printf("%2d ", matrix[i][j]);
}
printf("\n");
// bring back i and j to the proper coordinate
// and move back to the "first column"
i--;j--;
for (; j >= dim; j--)
{
printf("%2d ", matrix[i][j]);
}
printf("\n");
// bring back i and j to the proper coordinate
// and move up to the "first row"
j++;i--;
for (; i > dim; i--)
{
printf("%2d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
The output, as can be seen here is
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
0 1 2 3 4
9 14 19 24
23 22 21 20
15 10 5
6 7 8
13 18
17 16
11
12
==========================================================================
Looks like I misunderstood the question but the step from "printing" clockwise to "setting" clockwise is really small. Here is the setting flow:
#include <stdio.h>
#define N 5
int main(void) {
int i,j,dim, val = 1;
int matrix[N][N];
// perform spiral print
for (dim = 0; dim < (N+1)/2; dim++)
{
// set initial i and go till the "last column"
i = dim;
for (j = dim; j < N - dim; j++)
{
matrix[i][j] = val++;
}
// bring back i and j to the proper coordinate
// and move down to the "last row"
j--;i++;
for (; i < N - dim; i++)
{
matrix[i][j] = val++;
}
// bring back i and j to the proper coordinate
// and move back to the "first column"
i--;j--;
for (; j >= dim; j--)
{
matrix[i][j] = val++;
}
// bring back i and j to the proper coordinate
// and move up to the "first row"
j++;i--;
for (; i > dim; i--)
{
matrix[i][j] = val++;
}
}
// print the matrix
for (i=0; i < N; i++)
{
for (j=0; j< N; j++)
{
printf("%2d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
The output as shown here is
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

My solution. Using an "object" struct strangeite_s (from strange ite-rator). It allows ease reusing on different arrays and probably could be even rescaled to support n-dimensional arrays.
The strangeite is initialized using _init function with specified dimensions sizes of an 2d array. Each time _loop is evaluated, the x and y positions are updated and the condition for loop end is checked (and returned). The _inc function should be called on each increment of the iterator.
#include <stdio.h>
#include <limits.h>
#include <stddef.h>
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
struct strangeite_s {
size_t steplen[2];
size_t idx[2];
size_t cursteplen;
int direction;
};
void strangeite_init(struct strangeite_s *t, size_t max_x, size_t max_y)
{
assert(t != NULL);
t->steplen[0] = max_y;
t->steplen[1] = max_x;
memset(t->idx, 0, sizeof(t->idx));
t->direction = 0;
t->cursteplen = t->steplen[0];
}
bool strangeite_loop(const struct strangeite_s *t, size_t *x, size_t *y)
{
if (x) *x = t->idx[0];
if (y) *y = t->idx[1];
for (size_t i = 0; i < sizeof(t->steplen)/sizeof(t->steplen[0]); ++i) {
if (t->steplen[i] == 0) {
return false;
}
}
return true;
}
void strangeite_inc(struct strangeite_s *t)
{
if (t->cursteplen != 1) {
--t->cursteplen;
} else {
t->direction = ++t->direction % (2 * 2);
t->cursteplen = --t->steplen[t->direction % 2];
}
const size_t idx_to_change = t->direction % 2;
t->idx[idx_to_change] = t->idx[idx_to_change] + ( t->direction < 2 ? +1 : -1 );
}
int main()
{
int var[5][5];
struct strangeite_s i;
strangeite_init(&i, 5, 5);
int idx = 0;
for (size_t x, y; strangeite_loop(&i, &x, &y); strangeite_inc(&i)) {
var[y][x] = ++idx;
}
for (size_t i = 0; i < 5; ++i) {
for (size_t j = 0; j < 5; ++j) {
printf("%d ", var[i][j]);
}
printf("\n");
}
return 0;
}
Produces the following output:
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
Live version at onlinegdb.

It's possible to deterministically compute any one entry in the array A_{i,j} as a function only given the array size N, and i, j, in O(1), on-line, without any state, noticing the radius is a geometric progression. The space requirement is O(1) since one doesn't actually need the array to store the values; we can scan the array sequentially. However, like ray-tracing, it probably is slower, (up to a constant, it's still O(N^2).)
#include <stdio.h>
/* N: The size of the (simulated) array. */
#define N (16)
/* i, j: The array indices, as if, a[i][j]. */
static int a(const int i, const int j) {
/* (x,y) translation of (i,-j) to the centre, scaled up 2x for int math. */
const int x = 2 * i + 1 - N, y = -2 * j - 1 + N;
/* Geometric series and an offset +fiddling to get the directionality. */
return N*N - ((x < -y) ?
(-x > -y) ? (x+1)*(x+1) - (y+x)/2 - 1: y*y + (x+y)/2 :
(x > y) ? x*x + (x+y)/2 : (y+1)*y + (-x+y)/2);
}
int main(void) {
int i, j;
for(j = 0; j < N; j++) {
for(i = 0; i < N; i++) {
printf("%3d ", a(i, j));
}
printf("\n");
}
return 0;
}

Related

Why is the multiplication doubling in this C loop?

The code is supposed to take inputs to form a 3x3 Matrix and then multiply each term by the diagonal element of that line, but, for some reason that i don't know, it multiplies two times by the diagonal when the column index is bigger than the row index.
#include <stdio.h>
#define R 3
int a[R][R], i, j;
int main(void) {
for (i = 0; i < R; i++) {
for (j = 0; j < R; j++) {
printf("\nInsira o n%i%i ", i, j);
scanf("%i", &a[i][j]);
}
}
for (i = 0; i < R; i++) {
for (j = 0; j < R; j++) {
a[i][j] = a[i][j] * a[i][i];
}
}
for (i = 0; i < R; i++) {
printf("\n");
for (j = 0; j < R; j++) {
printf("%i ", a[i][j]);
}
}
}
input:
9 8 7
6 5 4
3 2 1
output:
81 648 567
30 25 100
3 2 1
The diagonal value for a given row is being changed before that row has been fully multiplied, so once the column goes past the diagonal, the multiplies are using the new value of that diagonal rather than the old value.
You can fix it (and improve the speed) as follows:
for (i = 0; i < R; i++) {
int tmp = a[i][i];
for (j = 0; j < R; j++) {
a[i][j] *= tmp;
}
}
Also, as mentioned, both i and j should be local variables.

Delete duplicate rows and columns of matrix

I need to delete (not skip while printing) the rows and columns of a matrix that appear more than once in program, and I should print only first row from the top that appears more than once or the first column from the left that appears more than once.
Example input:
1 2 3 2
4 5 6 5
1 2 3 2
7 8 9 8
After deleting:
1 2 3
4 5 6
7 8 9
Here's my code:
#include <stdio.h>
int main() {
int i, j, m, n,row,col, mat[200][200];
scanf("%d %d", &m, &n);
row = m; col = n;
for (i = 0; i < m; i++)
for (j = 0; j < m; j++)
scanf("%d", &mat[i][j]);
for (i = 0; i < m; i++)
for (j = 0; j < m; j++) {
if (mat[i][j] == mat[i++][j++])
row--;
if (mat[j][i] == mat[j++][i++])
col--;
}
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
return 0;
}
Do you have any idea how to make the algorithm work for this task? Mine has mistakes.
Would you please try the following:
#include <stdio.h>
#define ROWS 200
#define COLS 200
#define TRUE 1
#define FALSE 0
/*
* delete k'th row from the m x n matrix
*/
void deleterow(int mat[ROWS][COLS], int m, int n, int k)
{
int i, j;
for (i = k; i < m - 1; i++) {
for (j = 0; j < n; j++) {
mat[i][j] = mat[i + 1][j];
}
}
}
/*
* delete k'th columns from the m x n matrix
*/
void deletecol(int mat[ROWS][COLS], int m, int n, int k)
{
int i, j;
for (j = k; j < n - 1; j++) {
for (i = 0; i < m; i++) {
mat[i][j] = mat[i][j + 1];
}
}
}
int main() {
int i, j, m, n,row,col, mat[ROWS][COLS];
int iref, jref; // reference indexes to compare
int match; // flag to show if the row/col duplicates
// read input matrix
scanf("%d %d", &m, &n);
row = m; col = n;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &mat[i][j]);
// examine row by row
for (iref = 0; iref < m; iref++) {
// compare rows below iref and remove the row if duplicates
for (i = iref + 1; i < m; i++) {
match = TRUE;
for (j = 0; j < n; j++) {
if (mat[i][j] != mat[iref][j]) {
match = FALSE;
break;
}
}
if (match) {
deleterow(mat, m, n, i);
m--;
}
}
}
// examine column by column
for (jref = 0; jref < n; jref++) {
// compare columns more right than jref and remove the col if duplicates
for (j = jref + 1; j < n; j++) {
match = TRUE;
for (i = 0; i < m; i++) {
if (mat[i][j] != mat[i][jref]) {
match = FALSE;
break;
}
}
if (match) {
deletecol(mat, m, n, j);
n--;
}
}
}
// see the result
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("%2d%s", mat[i][j], j == n - 1 ? "\n" : " ");
}
}
return 0;
}
Output with the provided example:
1 2 3
4 5 6
7 8 9
[Explanation]
As for the operations of rows:
First, focus on the top row as a "reference". The row is indexed by
the variable iref which is assigned to 0 at first.
Then compare the remaining rows with the reference, changing
the row index i from iref+1 (just below the reference row) to n-1
(the bottom row).
If a row duplicates with the reference, remove the row with the
deleterow() function and decrement the row size m by one.
The modification of m affects the for loops which compare the
loop variables with m, meaning the matrix size is updated immediately.
This is a preferable nature of the for loop (IMHO).
If the comparizon reaches the bottom row, increment iref and repeat
the comparisons again.
Finally every row has been compared to each other and the duplicates have
been deleted.
Then perform the similar operations with columns.

The pointer variables overflows when they store integers larger than 1024 and some adresses seem to be locked.in C

How do I get to write to 2D pointers where I have pnumber[2%4][2%4] and how can I get pnumber with more than 3 ciphers to be displayed?
I'm making a program to write pascals triangle in C.
When the pointer pnumbers[i][j] have both i and j = 2 mod 4, except for when i and j = 2, then my program won't write to the address and give the error message:
pascals triangle: malloc.c:2406: sysmalloc: Assertion '{old_top == initial_top (av) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
Aborted.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int factorial(int p) {
if (p>=1) {
return p*factorial(p-1);
}
else {
return 1;
}
}
int NchooseM(int n, int m) {
return factorial(n)/(factorial(n-m)*factorial(m));
}
int main() {
int n =7;
int x = n-2;
int i, j, k;
/*
printf("How many rows of Pascals triangle do you want to write?\n");
scanf("%d", &n);
*/
int **pnumbers;
pnumbers = (int **) malloc(n *sizeof(int *));
/* Allocate memory for storing the individual elements in a row */
for (i = 0; i < n; i++) {
pnumbers[i] = (int *) malloc(i * sizeof(int));
}
pnumbers[0][1] = 1;
/* Calculating the value of pnumbers[k][l] */
for (i = 0; i < n; i++) {
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
/*
if (!(i % 4 == 2 && i != 2))
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
} else if (i > 2) {
for (j = 0; j <= i-1; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
}
*/
}
/* Writing out the triangle */
for (i = 0; i < n; i++) {
for (k = 0; k <= x; k++){
printf(" ");
}
for (j = 0; j <= i; j++) {
printf("%d ", pnumbers[i][j]);
}
x = x-1;
printf("\n");
}
for (i = 0; i < n; i++) {
free(pnumbers[i]);
}
free(pnumbers);
return 0;
}
When I avoid writing to these addresses and just print them out I get some seemingly random integer at these memory addresses.
Also when avoid these addresses and just print out so many rows that I get some spots with a higher integer with more than 3 siphers, it seems to overflow - and I don't see the logic behind it.
The result of running the second code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int factorial(int p) {
if (p>=1) {
return p*factorial(p-1);
}
else {
return 1;
}
}
int NchooseM(int n, int m) {
return factorial(n)/(factorial(n-m)*factorial(m));
}
int main() {
int n =20;
int x = n-2;
int i, j, k;
/*
printf("How many rows of Pascals triangle do you want to write?\n");
scanf("%d", &n);
*/
int **pnumbers;
pnumbers = (int **) malloc(n *sizeof(int *));
/* Allocate memory for storing the individual elements in a row */
for (i = 0; i < n; i++) {
pnumbers[i] = (int *) malloc(i * sizeof(int));
}
pnumbers[0][1] = 1;
/* Calculating the value of pnumbers[k][l] */
for (i = 0; i < n; i++) {
/*
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
*/
if (!(i % 4 == 2 && i != 2))
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
} else if (i > 2) {
for (j = 0; j <= i-1; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
}
}
/* Writing out the triangle */
for (i = 0; i < n; i++) {
for (k = 0; k <= x; k++){
printf(" ");
}
for (j = 0; j <= i; j++) {
printf("%d ", pnumbers[i][j]);
}
x = x-1;
printf("\n");
}
for (i = 0; i < n; i++) {
free(pnumbers[i]);
}
free(pnumbers);
return 0;
}
But row number 13 is still quite messed up.
Code is experiencing int overflow and thus undefined behavior (UB).
With 32-bit int and int factorial(int p), p > 12 oveflows the int range.
Code could use a wider integer type (long long works up to p==20), but improvements can be made at NchooseM() to avoid overflow for higher values.
Something like the below. Works up to int n = 30;
int NchooseM(int n, int m) {
// return factorial(n)/(factorial(n-m)*factorial(m));
int nm = 1;
int den = 1;
for (int i = m+1; i <= n; i++) {
assert(INT_MAX/i >= nm);
nm *= i;
assert(nm % den == 0);
nm /= den++;
}
return nm;
}
Tried unsigned long long and works up to int n = 62;
Edit: Another bug:
I "fixed" by initializing all to 1, yet I suspect something remains amiss in /* Calculating the value of pnumbers[k][l] */ for (i = 0; i < n; i++) { code.
pnumbers[i] = malloc((i + 1) * sizeof pnumbers[i][0]);
for (int j = 0; j < i + 1; j++) {
pnumbers[i][j] = 1;
}
Aside: rather than pnumbers[i] = (int *) malloc((i+1) * sizeof(int));, consider below with no unneeded cast nor trying to match the right type.
pnumbers[i] = malloc(sizeof pnumbers[i][0] * (i+1));

Calculating and printing the sums of the diagonals of a matrix

This is a program that is supposed to calculate the sum of all the diagonals in the matrix and then print them out.
ex. if the matrix is
1 2 3 4 5
2 3 4 5 6
0 1 1 2 5
5 5 5 5 5
7 8 9 7 7
the output should be
17 13 13 10 5
15 17 13 13 10
14 15 17 13 13
13 14 15 17 13
7 13 14 15 17
#include <stdio.h>
int main()
{
int n, sum=0, i, j, sub_i, sub_j, sub1_i, sub1_j;
scanf("%d ", &n);
int array1[n][n];
for(i=0;i<n;i++){
for(j=0; j<n; j++){
scanf("%d", &array1[i][j]);
}
}
for(i=0; i<n; i++){
for(j=0; j<n; j++){
sub_i=i;
sub_j=j;
sub1_i=i;
sub1_j=j;
sum=0;
if(j>i){
while(sub_j<n){
sum+=array1[sub_i][sub_j];
sub_i++;
sub_j++;
}
while(sub_j<n){
array1[sub_i][sub_j]=sum;
sub1_i++;
sub1_j++;
}
}
if(i>j){
while(sub_i<n){
sum+=array1[sub1_i][sub1_j];
sub_i++;
sub_j++;
}
while(sub1_i<n){
array1[sub1_i][sub1_j]=sum;
sub1_i++;
sub1_j++;
}
}
}
}
for(i=0; i<n; i++){
for(j=0; j<n; j++){
printf("%d ", array1[i][j]);
}
printf("\n");
}
return 0;
}
When i run the program it prints the array as if no value was assigned to the matrix. Can someone point out what is happening?
Quoting the comment by Weather Vane:
The program alters the array it is examining — see array1[sub_i][sub_j]=sum; — and then prints incorrect values, since you can't correctly sum the diagonals of an array that is changing.
The OP already realize that
... what you are telling me is to assign the values to another array and print that.
Yes, that is way easier:
#include <stdio.h>
int main(void)
{
int n;
// Checking the input is always a good idea, but you
// may prefer something less brutal, in case of error
if (scanf("%d", &n) != 1 || n < 1)
return 1;
int mat[n][n];
for (int i = 0; i < n; ++i) {
for (int j= 0; j < n; ++j) {
if (scanf("%d", &mat[i][j]) != 1)
return 1;
}
}
// Calculate and store the sum of the diagonals. Note that
// it could be done in the previous loop, but it may be better
// to refactor those snippets into separate functions.
int diagonals[2 * n + 1];
for (int i = 0; i < 2 * n + 1; ++i)
diagonals[i] = 0; // consider 'memset' instead of this loop
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
diagonals[n + i - j] += mat[i][j];
}
}
// Now print the correct values in their position
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
printf("%4d", diagonals[n + i - j]);
}
printf("\n");
}
return 0;
}
Testable HERE.
You can do like the follow:
#include <stdio.h>
#define N 5
int main()
{
int array[N][N] = {
1, 2, 3, 4, 5,
2, 3, 4, 5, 6,
0, 1, 1, 2, 5,
5, 5, 5, 5, 5,
7, 8, 9, 7, 7};
for(int i = 1; i < N; ++i)
for(int j = 1; j < N; ++j)
array[i][j] += array[i - 1][j - 1];
for (int i = 0; i + 1 < N; ++i)
for (int j = 0; j + 1 < N; ++j)
if (i == j)
array[i][j] = array[N - 1][N - 1];
else if (i > j)
array[i][j] = array[N - 1][N - 1 - i + j];
else
array[i][j] = array[N - 1 - j + i][N - 1];
for (int i = 0; i < N; ++i) {
for(int j = 0; j < N; ++j)
printf("%d ", array[i][j]);
printf("\n");
}
return 0;
}

Why does my code return -nan in visual studio, but not in Linux?

My Gauss Elimination code's results are -nan in visual studio, but not in Linux.
And the Linux results are awful because at func Gauss_Eli how many I increase the variable k at for blocks the func is working... doesn't occur segment error.
What is wrong with my code?
float ** Gauss_Eli(float ** matrix, int n) {
// -----------------------------------------------------
// | |
// | Eliminate elements except (i, i) element |
// | |
// -----------------------------------------------------
// Eliminate elements at lower triangle part
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
for (int k = 0; k < n + 1; k++) {
float e;
e = matrix[i][k] * (matrix[j][i] / matrix[i][i]);
matrix[j][k] -= e;
}
}
}
// Eliminate elements at upper triangle part
for (int i = n - 1; i >= 0; i--) {
for (int j = i - 1; j >= 0; j--) {
for (int k = 0; k < n + 1; k++) {
float e;
e = matrix[i][k] * (matrix[j][i] / matrix[i][i]);
matrix[j][k] -= e;
}
}
}
// Make 1 elements i, i
for (int i = 0; i < n; i++)
for (int j = 0; j < n + 1; j++) matrix[i][j] /= matrix[i][i];
return matrix;
}
int main() {
float ** matrix;
int n;
printf("Matrix Size : ");
scanf("%d", &n);
// Malloc variable matrix for Matrix
matrix = (float**)malloc(sizeof(float) * n);
for (int i = 0; i < n; i++) matrix[i] = (float*)malloc(sizeof(float) * (n + 1));
printf("Input elements : \n");
for (int i = 0; i < n; i++)
for (int j = 0; j < n + 1; j++) scanf("%f", &matrix[i][j]);
matrix = Gauss_Eli(matrix, n);
printf("Output result : \n");
//Print matrix after elimination
for (int i = 0; i < n; i++) {
for (int j = 0; j < n + 1; j++) printf("%.6f ", matrix[i][j]);
printf("\n");
}
return 0;
}
1.) OP allocates memory using the wrong type. This may lead to issues of insufficient memory and all sorts of UB and explain the difference between systems as they could have differing pointer and float sizes.
float ** matrix;
// v--- wrong type
// matrix = (float**)malloc(sizeof(float) * n);
Instead allocate to the size of the referenced variable. Easier to code (and get right), review and maintain.
matrix = malloc(sizeof *matrix * n);
if (matrix == NULL) Handle_Error();
2.) Code should look for division by 0.0
//for (int k = 0; k < n + 1; k++) {
// float e;
// e = matrix[i][k] * (matrix[j][i] / matrix[i][i]);
// matrix[j][k] -= e;
//}
if (matrix[i][i] == 0.0) Handle_Error();
float m = matrix[j][i] / matrix[i][i];
for (int k = 0; k < n + 1; k++) {
matrix[j][k] -= matrix[i][k]*m;
}
3.) General problem solving tips:
Check return values of scanf("%f", &matrix[i][j]);. It is 1?
Enable all warnings.
Especially for debug, print FP using "%e" rather than "%f".
4.) Numerical analysis tip: Insure exact subtraction when i==j
if (i == j) {
for (int k = 0; k < n + 1; k++) {
matrix[j][k] = 0.0;
}
else {
if (matrix[i][i] == 0.0) Handle_Divide_by_0();
float m = matrix[j][i] / matrix[i][i];
for (int k = 0; k < n + 1; k++) {
matrix[j][k] -= matrix[i][k]*m;
}
}

Resources