Stop printing repeated arithmetic expressions - c

I wrote this program in C to find all sums of three numbers that equal number n:
#include<stdio.h>
int main ()
{
int n;
printf("n:");
scanf("%d", &n);
int a,b,c;
a=0;
while(a<n)
{
a++;
b = 0;
while (b < n)
{
b++;
c = 1;
while (c < n)
{
if(a + b + c == n){
printf("%d + %d + %d = %d\n", a , b ,c ,n);
c++;
}
if (a + b + c != n){
c++;
}
}
}
}
}
What do I do to stop it from printing repeated arithmetic expressions, like 1 + 1 + 3 and 3 + 1 + 1, for example.

I would recommend something similar to what Ry-♦ suggested in the comments to your question.
Here is what it would look like in your code:
#include<stdio.h>
int main ()
{
int n;
printf("n:");
scanf("%d", &n);
int a,b,c;
a=0;
while(a<n)
{
a++;
b = a; /* start b at a to prevent duplicate sequences */
while (b < n)
{
b++;
c = b; /* start c at b to prevent duplicate sequences */
while (c < n)
{
if(a + b + c == n){
printf("%d + %d + %d = %d\n", a , b ,c ,n);
c++;
}
if (a + b + c != n){
c++;
}
}
}
}
}
Also in the comments of your question is a suggestion to use for loops. This would make your code a lot more compact and easier to read:
#include<stdio.h>
int main ()
{
int n;
printf("n:");
scanf("%d", &n);
int a,b,c;
for(a=0;a<n;a++)
for(b=a;b<n;b++)
for(c=b;c<n;c++)
if(a + b + c == n)
printf("%d + %d + %d = %d\n", a , b ,c ,n);
}

Related

Why does my program only work half the time?

I have an assignment to write a program for a natural number where its inverse is divisible by its number of digits. A natural number n ( n > 9) is entered from the keyboard. To find and print the largest natural number less than n that its inverse is divisible by its number of digits. If the entered number is not valid, print a corresponding message (Brojot ne e validen).
I have tried :
#include <stdio.h>
int main() {
int n,r,s=0,a=0;
int m;
scanf("%d",&n);
int t=n;
if(t<10)
{ printf("Brojot ne e validen");}
else {
for (int i = n - 1; i > 0; i--) {
while (n != 0) {
r = n % 10;
s = (s * 10) + r;
n = n / 10;
a++;
if (s % a == 0) {
m = i;
break;
}
}
}
printf("%d\n", m);
}
return 0;
}
And when my inputs is 50, it gives the correct answer which is 49, but when I try numbers like 100 or 17 it prints 98 instead of 89 and 16 instead of 7 respectively. I have been baffled by this for more than an hour now
check your logic.
you can check each value by
#include <stdio.h>
int main() {
int t,r,s=0,a=0;
int m;
scanf("%d",&t);
if(t<10)
{ printf("Brojot ne e validen");}
else {
for (int i = t - 1; i > 0; i--) {
while (t != 0) {
r = t % 10;
printf("%d \n", r);
s = (s * 10) + r;
printf("%d \n", s);
t = t / 10;
printf("%d \n", t);
a++;
if (s % a == 0) {
m = i;
break;
}
}
}
printf("%d\n", m);
}
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);
}
}

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.

why is this code giving this output - "HCF is: 1" whenever a%b != 0?

This program is made to find the HCF of two integers a and b by the formula/algorithm - 'a = bq +r' where a and b are two numbers, q being the quotient and r is the remainder.
here is the code.
#include <stdio.h>
int main() {
int a, b;
printf("enter both numbers a>b to find HCF\n");
scanf("%d %d",&a, &b);
int q, r, hcf;
if(a%b == 0) {
r = 0;
hcf = r;
} else {
q = a/b;
r = a%b;
}
int i;
for(i = r; i = 0;) {
a = b;
b = i;
hcf = b;
q = a/b;
i = a%b;
}
printf("HCF is: %d", hcf);
return 0;
}
The for loop is not correct. You need to use == instead of =. The = operator is for assignment, == is for comparison. Also, you want the loop to stop when i == 0 so the condition should be i != 0. The following loop works for me:
for(i = r; i != 0; ) {
a = b;
b = i;
hcf = b;
i = a%b;
}

inverse Function works properly, but if works after while loops it produces wrong answers

I try to implement Chinese remainder theorem, for doing this I should find multiplicative inverse of some numbers. Function works properly, but if it works after while loops it produces wrong results.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
main(){
int rem[5],div[5],fac[5];
int t = 0;
int c = 0;
int m = 1;
int d = 0;
void inverse(int,int);
//take remainder and divider from user
while ((rem[t] != -1) & (div[t] != -1))
{
printf("Enter remainder and divider in an order(-1 -1 to finish):");
scanf_s("%d" "%d", &rem[t], &div[t]);
if (rem[t] != -1 & div[t] != -1)
t++;
else {
printf("You ask to stop! Thank you.\n");
div[t] = -1;
rem[t] = -1;
}
}
while ((div[c] != -1) & (rem[c] != -1)) {/* print until face null character */
printf("%d . character is %d and %i\n", c + 1,rem[c], div[c]);
m = m*div[c];
c++;
}
printf(" m is %d\n", m);
//implement crt algorithm
while ((div[d] != -1) & (rem[d] != -1)) {
fac[d] = m/div[d];
printf(" m(%d) is %d\n",d+1, fac[d]);
inverse(div[d], fac[d]);
d++;
}
inverse(5,21);//this lines works if I first enter -1 -1
inverse(7,15);
system("pause");
//return 0;
}
//this is for finding gcd and inverse
int a, b, i;
int k = 1;
int q[10];
int r[10];
int x[10];
int y[10];
void inverse(int a, int b){
q[1] = (a / b);
r[1] = a%b;
q[0] = a;
r[0] = b;
//find gcd of two numbers
while (r[k] != 0){
k = k++;
q[k] = r[k - 2] / r[k - 1];
r[k] = r[k - 2] % r[k - 1];
}
printf("gcd of %d and %d is: %d\n", a, b, r[k - 1]);
//check whether these two numbers are relatively prime,if it is then find inverse
if (r[k - 1] != 1)
printf("These two numbers should be relatively prime\n");
else{
x[k - 1] = -q[k - 1];
y[k - 1] = 1;
i = k - 1;
while (i > 1){
x[i - 1] = -x[i] * q[i - 1] + y[i];
y[i - 1] = x[i];
i = i - 1;
}
//check whether the inverse of number is less than 0, if it is then add the modulo
if ((x[1] % a) < 0)
printf("multiplicative inverse of %d in mod %d is %d\n", b, a, (x[1] % a) + a);
else
printf("multiple inverse of %d in mod %d is %d\n", b, a, x[1] % a);
}
}
The main trouble that I saw was the use of int k = 1; in a global scope. If you initialize k inside the inverse method (k = 1) you won't keep referencing previous calculations.
Also, I'm not sure of the C semantics but in Java k = k++; will not actually increment k. You probably just want k++.

Resources