C program chasing and I can't find the mistake - c

I just started learning programing and I'm having issues with my C code. The idea is to create a squared array sized [m][m] and fill the lateral and one diagonal spaces with 'n' (the user input determine the value of 'm' and 'n'), and then fill the rest of the spaces with numbers following a pattern. But every time it starts to fill the spaces it just crashes without pointing any warning or error.
Here is the code:
#include<stdlib.h>
#include<stdio.h>
int M[100][100] = {}, l, c;
int ImpMat(int m)
{
int l, c;
for(l = 0; l < m; l++)
{
printf("\n");
for(c = 0; c < m; c++)
printf("%i ", M[l][c]);
}
}
int Matriz(int m, int n)
{
int l, c;
for(l = 0; l < m; l++)
{
for(c = 0; c < m; c++)
{
if(c == 0 || c == m - 1 || c + l == m - 1)
M[l][c] = n;
else
M[l][c] = 0;
}
}
}
int NumMatI(int m)
{
int l, c, p, q;
for(l = 2; l < m; l++)
for(c = m -2; c >= 1; c++)
{
p = l - 1;
q = c + 1;
if(l + c > m - 1)
M[l][c] = M[p][c] + M[p][q];
}
}
int main()
{
int m, n;
printf("Type the value of 'm': ");
scanf("%i", &m);
printf("Type the value of 'n': ");
scanf("%i", &n);
Matriz(m, n);
NumMatI(m);
ImpMat(m);
return 0;
}
The function 'ImpMat' just prints the array, the 'Matriz' creates the array (the size is limited to 100) and 'NumMatI' is where it tries to fill the array.
I already realised the function 'NumMatI' is the one crashing the program, but can't find what is causing it.
I'm using Dev-C++.

In for(c = m -2; m >= 1; c++), the comparison should involve c somehow.

Related

How to make competitive coding solutions more efficient (BIT wise operations)?

How do I make my code more efficient (in time) pertaining to a competitive coding question (source: codechef starters 73 div 4):
(Problem) Chef has an array A of length N. Chef wants to append a non-negative integer X to the array A such that the bitwise OR of the entire array becomes = Y .
Determine the minimum possible value of X. If no possible value of X exists, output -1.
Input Format
The first line contains a single integer T — the number of test cases. Then the test cases follow.
The first line of each test case contains two integers N and Y — the size of the array A and final bitwise OR of the array A.
The second line of each test case contains N space-separated integers A_1, A_2, ..., A_N denoting the array A.
Please don't judge me for my choice of language .
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int* binary_number(int n) // returns pointer to a array of length 20(based on given constrains) representing binary
{
int* ptc;
ptc = (int*) malloc(20*sizeof(int));
for(int i = 0; i < 20; i++)
{
if((n / (int) pow(2,19-i)) > 0){*(ptc + i) = 1;}
else {*(ptc + i) = 0;}
n = n % (int) pow(2,19-i) ;
}
return ptc;
}
int or_value(int* ptc, int n) // Takes in pointers containing 1 or zero and gives the logical OR
{
for(int k = 0; k < n; n++)
{
if(*ptc == *(ptc + 20*k)){continue;} // pointers are 20 units apart
else{return 1;break;}
}
return *ptc;
}
int main(void) {
int t; scanf("%d", &t);
for (int i = 0; i < t; i++)
{
int n, y;
scanf("%d %d", &n, &y);
int a[n];
for(int j = 0; j < n ; j++)
{
scanf("%d", &a[j]);
}
int b[20*n];
for (int j = 0; j < n; j++)
{
for (int k = 0; k < 20; k++)
{
b[20*j + k] = *(binary_number(a[n])+k);
}
}
int c = 0;
int p = 0;
for (int j = 0; j < 20; j++)
{
if ((*(binary_number(y) + j) == 1) && (or_value((&b[0] + j),n) == 0)){c = c + pow(2,19 - j);}
else if ((*(binary_number(y) + j) == 0) && (or_value((&b[0] + j),n) == 1)){p = 1; break;}
}
if (p==1){printf("-1");}
else {printf("%d\n", c);}
}
return 0;
}

Recursive function to verify Matrix is Symmetric in C

I am just working on a recursive function to verify if a matrix is symmetric or not. The matrix must be square and I am considering max n = 20. I could develop the function:
int verifySymmetric(int m[20][20], int i, int j, int n) {
if (!((n == i) || (n == j))) {
if (m[i][j] != m[j][i]) {
return 0;
} else {
return (verifySymmetric(m, i + 1, j, n) && verifySymmetric(m, i, j + 1, n));
}
}
return 1;
}
Below is a code to run:
#include <stdio.h>
#include <stdlib.h>
int verifySymmetric(int m[20][20], int i, int j, int n) {
if (!((n == i) || (n == j))) {
if (m[i][j] != m[j][i]) {
return 0;
} else {
return (verifySymmetric(m, i + 1, j, n) && verifySymmetric(m, i, j + 1, n));
}
}
return 1;
}
int main() {
int n, r, c, m[20][20], t[20][20], flag, i, j;
i = j = 0;
printf("Enter matrix order >> ");
scanf("%d", &n);
printf("\nEnter the elements \n");
for (r = 0; r < n; r++) {
for (c = 0; c < n; c++) {
printf("m[%d][%d]: ", r + 1, c + 1);
scanf("%d", &m[r][c]);
}
}
for (r = 0; r < n; r++)
for (c = 0; c < n; c++)
t[c][r] = m[r][c];
flag = verifySymmetric(m, i, j, n);
if (flag == 1)
printf("Matrix is symmetric ");
if (flag == 0)
printf("Matrix is not symmetric ");
return 0;
}
My main concern is about the line
return (verifySymmetric(m, i + 1, j, n) && verifySymmetric(m, i, j + 1, n));
The program seem to work but I noticed that many m[row][column] is printed when I run the code. Something like this
Enter the elements
m[1][1]: m[1][2]: m[1][3]: m[1][4]: m[1][5]: m[1][6]: m[1][7]: m[1][8]: m[1][9]: m[1][10]: m[1]
[11]: m[1][12]: m[1][13]: m[1][14]: m[1][15]: m[1][16]: m[1][17]: m[1][18]: m[1][19]: m[1][20]:
m[1][21]: m[1][22]: m[1][23]: m[1][24]: m[1][25]: m[1][26]: m[1][27]: m[1][28]: m[1][29]: m[1]
[30]: m[1][31]: m[1][32]: m[1][33]: m[1][34]: m[1][35]: m[1][36]: m[1][37]: m[1][38]: m[1][39]:
m[1][40]: m[1][41]: m[1][42]: m[1][43]: m[1][44]: m[2][1]: m[2][2]: m[2][3]: m[2][4]: m[2][5]:
m[2][6]: m[2][7]: m[2][8]: m[2][9]: m[2][10]: m[2][11]: m[2][12]: m[2][13]: m[2][14]: m[2][15]:
m[2][16]: m[2][17]: m[2][18]: m[2][19]: m[2][20]: m[2][21]: m[2][22]: m[2][23]: m[2][24]:
What would be wrong with the function?
What would be another approach?
Edit
This is not a good approach, using recursion for a function like this, but I was curious about it and couldn't find an example in the internet. It is basically for learning purposes.
I am using Visual Studio Code and the strange behavior described above is when I click to Run Code two times. Running once, it runs as I expected, printing Enter matrix order >> , but once I click it for the second time without entering the matrix order, the misbehavior happens.
The code seems to work but it is very inefficient as the recursive approach will cause many redundant comparisons. The time complexity is O(n4) instead of O(n2)
You reason you get this misleading output is you prompt for each matrix value to stdout, but the input is read from a file and not echoed to stdout.
Here is a simpler non-recursive approach:
#include <stdio.h>
int verifySymmetric(int m[20][20], int n) {
for (int r = 0; r < n; r++) {
for (int c = 0; c < r; c++) {
if (m[r][c] != m[c][r])
return 0;
}
}
return 1;
}
int main() {
int n, m[20][20];
printf("Enter matrix order >> ");
if (scanf("%d", &n) != 1) {
printf("missing input\n");
return 1;
}
if (n < 1 || n > 20) {
printf("invalid dimension %d\n", n);
return 1;
}
printf("\nEnter the elements\n");
for (int r = 0; r < n; r++) {
for (int c = 0; c < n; c++)
if (scanf("%d", &m[r][c]) != 1) {
printf("missing input\n");
return 1;
}
}
}
if (verifySymmetric(m, n)) {
printf("Matrix is symmetric\n");
else
printf("Matrix is not symmetric\n");
return 0;
}
If for some reason the implementation is required to be recursive, here is a modified version without redundant comparisons:
int verifySymmetric(int m[20][20], int i, int j, int n) {
if (j == n) {
return 1;
} else
if (i < j) {
return (m[i][j] == m[j][i]) && verifySymmetric(m, i + 1, j, n);
} else {
return verifySymmetric(m, 0, j + 1, n);
}
}

simple program doesn't work with negative array numbers

I just started to learn C language. By now I have very basic knowledge. At the moment I am coding some very simple programs from given exercises by my University.
Current exercise I have is: Write a program that finds two largest elements in n element array (2 ≤ n ≤ 10) and outputs sum of those two elements.
The problem is that my written code works only with positive array numbers and doesn't work with negative numbers.
Current code:
#include <stdio.h>
int main() {
int seka[] = {0,0,0,0,0,0,0,0,0,0}; //array in lithuanian = seka
int k; //variable to determine array size
int m = seka[0];
int n = seka[0];
int y = 0;
scanf ("%d",&k);
for(int i = 0; i < k; ++i){
scanf ("%d",&seka[i]);
}
for(int j = 0; j < k; ++j){
if (seka[j] > m)
m = seka[j];
}
for(int o = 0; o < k; ++o){
if (seka[o] == m)
y = y + 1;
}
if(y >= 2){
n = m;
}
else
{
for(int l = 0; l < k; ++l){
if(seka[l] != m)
if (seka[l] > n)
n = seka[l];
}
}
printf ("%d", m + n);
return 0;
}
Input used:
5
4 9 5 6 3
Output got:
15
But if input has negative numbers:
6
-5 -8 -6 -2 -5 -8
Output is:
0
I know that this is not the most efficient approach for given problem, but I am still learning and I hope that you will help me finding the root of the issue.
Fixed my code with your help, now works like it should.
Fixed code:
#include <stdio.h>
int main() {
int seka[] = {0,0,0,0,0,0,0,0,0,0}; //array in lithuanian = seka
int k; //variable to determine array size
int y = 0;
scanf ("%d",&k);
for(int i = 0; i < k; ++i){
scanf ("%d",&seka[i]);
}
int m = seka[0];
for(int j = 1; j < k; ++j){
if (seka[j] > m)
m = seka[j];
}
for(int o = 0; o < k; ++o){
if (seka[o] == m)
y = y + 1;
}
int n;
for(int l = 0; l < k; ++l){
if(seka[l] != m)
if (seka[l] < n)
n = seka[l];
}
if(y >= 2){
n = m;
}
else
{
for(int l = 0; l < k; ++l){
if(seka[l] != m)
if (seka[l] > n)
n = seka[l];
}
}
printf ("%d", m + n);
return 0;
}
You update the max value with
for(int j = 0; j < k; ++j){
if (seka[j] > m)
m = seka[j];
}
but you initialize it with
m = seka[0];
The problem is that seka[0] has not been set by the user, yet, so its value is 0. That's Why the maximum value cannot be less than 0.
In order to fix it, just initialize the maximum with the first element of the array, but after the user input. Then loop starting from index 1:
m = seka[0];
for(int j = 1; j < k; ++j){
if (seka[j] > m)
m = seka[j];
}

0xC0000374: A heap has been corrupted (parameters: 0x77AAB960)

The code bellow sometimes throws exceptions similar to:
Exception thrown at 0x779CC19E (ntdll.dll) in Matriks.exe: 0xC0000005: Access violation reading location 0x0000001D.
I'm new to C and just learned to use pointers. Any tips ? Are there other problems in my code that are worth criticizing ?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
main()
{
int *Matrix_01, *Matrix_02;
int a, b, i, n,valid=1;
srand(time(0));
do
{
printf("Insert number of rows: ");
scanf("%d", &a);
printf("Insert number of columns: ");
scanf("%d", &b);
if (a >= 0 && b >= 0)
valid = 0;
else
{
printf("Invalid input!");
system("pause>null & cls");
}
} while (valid == 1);
Matrix_01 = (int *)malloc(a * b * sizeof(int));
Matrix_02 = (int *)malloc(a * b * sizeof(int));
for (i = 0; i < a; i++)
for (n = 0; n < b; n++)
{
Matrix_01[a*i + n] = rand() % 50;
Matrix_02[a*i + n] = rand() % 50;
}
printf("\nFirst Matrix:\n");
for (i = 0; i < a; i++)
{
printf("\n");
for (n = 0; n < b; n++)
{
printf("%4d", Matrix_01[a*i + n]);
}
}
printf("\n\nSecond Matrix:\n");
for (i = 0; i < a; i++)
{
printf("\n");
for (n = 0; n < b; n++)
{
printf("%4d", Matrix_02[a*i + n]);
}
}
printf("\n\nAddition:\n");
for (i = 0; i < a; i++)
{
printf("\n");
for (n = 0; n < b; n++)
{
printf("%4d", Matrix_01[a*i + n]+Matrix_02[a*i + n]);
}
}
printf("\n\nSubtraction:\n");
for (i = 0; i < a; i++)
{
printf("\n");
for (n = 0; n < b; n++)
{
printf("%4d", Matrix_01[a*i + n] - Matrix_02[a*i + n]);
}
}
printf("\n");
system("pause>null");
}
Heap is corrupt in that case means that you wrote out of the valid allocated zones.
Check the min & max values of your index:
i ranges from 0 to a-1
n ranges from 0 to b-1
So a*i + n ranges from 0 to a*(a+1) + b. So it doesn't match the matrix dimensions. If a is bigger than b the memory will get corrupted.
You need to replace this by b*i + n (which ranges from 0 to b*(a-1) + b => a*b
You also want to avoid to allow that a or b is zero when reading the input. Actually, it's better to check if scanf succeeded in scanning one value by checking the return code then check if values are greater than zero (but not equal)
Or use 2D matrixes (or compute pointers on rows once to avoid those computations)

Is there a way to optimize the code and improve to K number of sum terms instead of 4?

#include <stdio.h>
int main() {
int N = 133;
int a, b, c, d;
int flag = 0;
for ( int j = 1; j < (N/2); j++)
{
a = j;
for ( int k = 1; k < (N/2); k++)
{
b = k;
for ( int l = 1; l < (N/2); l++)
{
c = l;
for ( int m = 1; m < (N/2); m++)
{
d = m;
if ( a+b+c+d == N && (a != 0 && b!= 0 && c != 0 && d!= 0))
{
printf("\n %d + %d + %d + %d = %d" , a, b, c, d, N);
flag = 1;
break;
}
}
if(flag)
break;
}
if(flag)
break;
}
if(flag)
break;
}
return 0;
}
The code currently outputs
1 + 2 + 65 + 65 = 133
As you can see, I am getting the sum using 4 numbers to form N (133) in this case. Is there a way to improve the code to 'k' numbers without using nested 'k' for loops?
Desired Output: ( a + b + c + d + e + f + ...... + k = N )
say for a given value of N represented using sum of k terms, where k is an input parameter.
Notes:
None of the 'k' terms is zero.
Original question had loops starting from 0; updated to start from 1.
Specific Requirement, I want the terms (a to k) to have the lowest possible standard deviation among all the sums. So breaking out at the first sum is not ideal for that scenario, but this is the baseline code I have reached. Once I figure out reducing number of loops, I know how to modify for lowest S.D.
Also pretty obvious but k < N in all cases.
Much simpler code that does the same thing as yours:
#include <stdio.h>
int main()
{
int N = 133;
for ( int j = 1; j < (N/2); j++)
for ( int k = 1; k < (N/2); k++)
for ( int l = 1; l < (N/2); l++)
for ( int m = 1; m < (N/2); m++)
if ( j+k+l+m == N) {
printf("\n %d + %d + %d + %d = %d" , j, k, l , m, N);
return 0;
}
}
And to your problem, which is a bit vague, but seems to be finding k numbers a_1, a_2 ... a_k such that 1 < a_n < N/2 for all n and a_1+a_2+...+a_k=N. Here is very simple code to do that, using your algorithm but extended for arbitrary k:
#define N 133
#define k 8
int main()
{
int arr[k];
for(int i=0; i<k; i++)
arr[i]=1;
for(int i=0,c=k; c<N; c++) {
arr[i]++;
if(arr[i]>=N/2) {
c--;
i++;
}
}
for(int i=0; i<k-2; i++)
printf("%d + ", arr[i]);
printf("%d = %d\n", arr[k-1], N);
}
It has no error checking. The problem is not solvable for k=1 and k>N. And because integer division is rounded down, it is not solvable for k=2 if N is odd.
But here is some MUCH more efficient code. The problem is very simple, so it's not about finding the numbers a_1, a_2, a_3 ... a_k. It's really only about finding a_1 and a_2. The rest are one.
#define N 19
#define k 5
int main()
{
for(int i=0; i<k-2; i++)
printf("1 + ");
int c=N/2-(k-2);
if (c<1)
c=1;
printf("%d + ", c);
printf("%d = %d\n", N-(k-2)-c, N);
}
Again, no error check is made.

Resources