Why is the output 321 instead of 212? - c

#include <stdio.h>
int main()
{
int i;
int j;
int k;
for(i = 1, j = 0, k = 3 ; i <= 5, j <= 6, k > 1 ;i++, j++, k--);
{
printf("%d%d%d", i, j, k);
}
}
Why is this program printing 321 instead of 212?
I get 321 when I execute the program but I think it should be 212. I cannot understand why it is printing 321.

That's because you have a semicolon at the end of the for loop, so the code runs essentially like this:
// first you increment i,j and decrement k until k is 1, so twice
for(i = 1, j = 0, k = 3 ; i <= 5, j <= 6, k > 1 ;i++, j++, k--) {}
// then you print the values
printf("%d%d%d", i, j, k);

You have 2 bugs.
The first was already mentioned and should also be reported by your compiler.
You have a stray semicolon after your for loop.
The second is that your condition is rather strange: i <= 5, j <= 6, k > 1
Relational operators have higher precedence than coma operator. That means this condition is same as (i <= 5), (j <= 6), (k > 1) which again is same as k>1.
If you want to have all the relational operands evaluate to true, you must add logical operator: i <= 5 && j <= 6 && k > 1

Related

How to calculate the number of triangles that can be formed

The code below should have counted the number of triangles that can be formed out of every triplet of 3 distinct integers from the given range 1...N. However, when I input 5, it gives me 34, while the right answer is 3: the only possible triangles are (2, 3, 4), (2, 4, 5) and (3, 4, 5).
// C code to count the number of possible triangles using
#include <stdio.h>
int main()
{ int N, count=0;
setvbuf(stdout, NULL, _IONBF, 0);
printf("Please input the value of N: \n");
scanf("%d", &N );
for (int i = 1; i < N; i++) {
for (int j = 1; j < N; j++) {
// The innermost loop checks for the triangle
// property
for (int k = 1; k < N; k++) {
// Sum of two sides is greater than the
// third
if (i + j > k && i + k > j && k + j > i)
{
count++;
}
}
}
}
printf ("Total number of triangles possible is %d ",count);
return 0;
}
You do not ensure that the numbers are distinct.
You can do this be chosing your loop limits correctly:
for (int i = 1; i <= N-2; i++) {
for (int j = i+1; j <= N-1; j++) {
for (int k = j+1; k <= N; k++) {
Start each inner loop one higher than current counter of outer loop. It also does not make any sense to run each loop up to N. If they must be distinct, you can stop at N-2, N-1, N
This creates triples where numbers are increasing.
If you consider triangles (3,4,5) and (4,3,5) to be different, we must also account for permuations of these triples.
As all values are distinct, we have 6 possible permutations for each triple that was found in the inner loop.
I'm sorry, I can't go for a comment so let's go for an answer.
I don't really get what you wish to do. As I am understanding it, you wish to print this :
1, 2, 3, 4, 5-> [2, 3, 4], [2, 4, 5], [3, 4, 5] -> 3
Except, with your code, you'll never check your N since you go out of your loop when i turns into N.
Also, your "j" and "k" don't have to move starting 1 since you already tried that position with "i", so you'll only get doublons doing that.
EDIT : some changes for a smarter code (I removed my +1 but go check for "<=", which I personnaly dislike :) ):
// since [1, 2, 3] can't bring any triangle
if (N < 4) return 0;
// since there is no possible triangle with 1 as a border, start at 2
for (int i = 2; i <= N-2; i++) {
for (int j = i+1; j <= N-1; j++) {
// The innermost loop checks for the triangle
// property
for (int k = j+1; k <= N; k++) {
// Sum of two sides is greater than the
// third
// simplified as suggested by S M Samnoon Abrar
if (i + j > k)
{
count++;
}
}
}
You need to do the following:
run first loop through 1 to N, i.e.: 1 <= i <= N
don't start each nested loop from index 1. So, you need to run first nested loop in range i+1 <= j <= N and second nested loop in range j+1 <= k <=N.
Explanation
First, if you run all 3 loops from 1 to N, then you are not doing distinct counting because all numbers in the range will be iterated 3 times. So it would give an incorrect result.
Secondly, since we need to count distinct numbers only, it is efficient to count +1 from the previous outer loop each time. In this way, we are ensuring that we are not iterating over any number twice.
Check the following code:
// C code to count the number of possible triangles using
#include <stdio.h>
int main()
{ int N, count=0;
setvbuf(stdout, NULL, _IONBF, 0);
printf("Please input the value of N: \n");
scanf("%d", &N );
for (int i = 1; i <= N; i++) {
for (int j = i+1; j <= N; j++) {
// The innermost loop checks for the triangle
// property
for (int k = j+1; k <= N; k++) {
// Sum of two sides is greater than the
// third
if (i + j > k && i + k > j && k + j > i)
{
count++;
}
}
}
}
printf ("Total number of triangles possible is %d ",count);
return 0;
}
Spot the extra line of code that enforces the constraint that the 3 numbers are "distinct" (read "unique"). Funny what a little "print debugging" can turn up...
printf("Please input the value of N: ");
scanf("%d", &N );
for (int i = 1; i < N; i++) {
for (int j = 1; j < N; j++) {
for (int k = 1; k < N; k++) {
if (i + j > k && i + k > j && k + j > i) {
if( i != j && j != k && k != i ) {
printf( "%d %d %d\n", i, j, k );
count++;
}
}
}
}
}
printf ("Total number of triangles possible is %d ",count);
Output
Please input the value of N: 5
2 3 4
2 4 3
3 2 4
3 4 2
4 2 3
4 3 2
Total number of triangles possible is 6
The OP code was counting (1,1,1) or (2,3,3) in contravention of "distinct" digits.
AND, there is now ambiguity from the OP person as to whether, for instance, (4,2,3) and (4,3,2) are distinct.
printf() - the coder's friend when things don't make sense...

Explain the output of 2D array with nested loop code

#include <stdio.h>
int main()
{
int i, j, k, px[] = { -2, -2, -1, -1, 1, 1, 2, 2 },
py[] = { -1, 1, -2, 2, -2, 2, -1, 1 };
int cox[4][4] = { { 0 } };
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
for (k = 0; k < 8; k++)
if (((i + px[k]) >= 0 && (i + px[k]) < 4) &&
((j + py[k]) >= 0 && (j + py[k]) < 4))
cox[i][j]++;
printf("%d\t", cox[i][j]);
}
printf("\n\n");
}
}
I partially understand this nested loop. but i can't fully understand why its output in some part are 3 and why smiddle part are 4 but i understand why output of corner parts of this 2d array is 2.please explain me.
As the result matrix is quadrant symmetric, let me start with examining
the four cases: (i=0, j=0), (i=0, j=1), (j=1, i=0) and (i=1, j=1).
If (i=0, j=0), the condition (i + px[k]) >= 0 && (i + px[k]) < 4) && ((j + py[k]) >= 0 && (j + py[k]) < 4) meets twice: when k=5 and k=7.
If (i=0, j=1), the condition meets three times: when k=5, k=6 and k=7.
If (i=1, j=0), the condition meets three times: when k=3, k=5 and k=7.
If (i=1, j=1), the condition meets four times: when k=3, k=5, k=6 and k=7.
You can extend the similar consideration to the four quadrants then you can
obtain the output.

Count how many times an array element is larger than the subsequent element (off-by-one error)

I'm programming in C. I have to make a function called count , that counts how many times is larger than the subsequent element in the same array. For example, if we had a main code looking like this:
int main() {
int a1[] = { 5 };
int a2[] = { 1, 2, 3, 4, 5 };
int a3[] = { 5, 4, 3, 2, 1 };
int a4[] = { 1, 9, 3, 7, 5 };
int a5[] = { 7, 5, 6 };
printf("%d\n", count(a1, sizeof a1 / sizeof a1[0]));
printf("%d\n", count(a2, sizeof a2 / sizeof a2[0]));
printf("%d\n", count(a3, sizeof a3 / sizeof a3[0]));
printf("%d\n", count(a4, sizeof a4 / sizeof a4[0]));
printf("%d\n", count(a5, sizeof a5 / sizeof a5[0]));
return 0;
}
Count should return the following:
0
0
4
2
1
I have tried myself, but it seems like I get an off-by-one error that I don't know how to fix.
int count(int a[], int i){
int k=0;
int j;
for (j=0; j<=i-1; j++){
if(a[j] > a[j+1])
k++;
}
return k;
}
But this gives this wrong output:
0
1
5
3
2
Can someone spot the mistake in my code, or help me with this?
You're reading a[i] when j=i-1, which is out of array a bound.
for (j=0; j<=i-1; j++){
if(a[j] > a[j+1])
It should be
for (j=0; j<i-1; j++){
if(a[j] > a[j+1])
A way to avoid this off-by-one error is to use an idiomatic "iterate over an array" for loop and termination condition j < i but change the initial loop index from 0 to 1. The test inside the loop uses j and j - 1.
int count(const int *a, int i)
{
int k = 0;
for (int j = 1; j < i; j++) {
if (a[j - 1] > a[j])
k++;
}
return k;
}
I think j < i is easier to reason about than j <= i - 1 and be confident that it's correct.

For-loop not working as intended

When I run this code, the printf() function seems to give a random large number, as if it is calling an array that is out of bounds. What is going on here?
#include <stdio.h>
#include <math.h>
int main(void)
{
int test_num = 1000;
int factors[16];
for(int i = 1, j = 0; i < test_num; i++, j++) {
if(test_num % i == 0)
factors[j] = i;
}
printf("%d", factors[2]);
return 0;
}
Most likely, the problem is that you are incrementing j even when you don't assign i.
The sequence of factors you get is 1, 2, 4, 5, 8, 10, ... You probably want to assign those to the indices 0-5 (inclusive), not 0, 1, 3, 4, 7, 9, etc.
Change your loop as follows:
for(int i = 1, j = 0; i < test_num && j < 16; i++) {
if(test_num % i == 0) {
factors[j] = i;
j++;
}
}
The main point is only to increment j when i fits your criterion. You also want to make sure that you don't go out of bounds (&& j < 16).
If you print out i and j in the loop, notice that j is never 2.
Thus, factors[2] is never initialized, so you will print out junk.
When j == 2, i == 3 and 1000 % 3 does not equal 0. It equals 1. Not passing your if statement condition. Therefore factors[2] will be undefined (since you didn't initialize your array). Hence the large number.

What does this for loop do in C ?

#include <stdio.h>
int main(void) {
int i= 1, j = 1;
for (; j; printf("%d %d",i, j))
j = i++ <= 5;
return 0;
}
output-
2 13 14 15 16 17 0
Can anyone explain what is happening inside the loop? This question was asked in the interview process.
The code is equivalent to:
int main(void) {
int i=1,j=1;
while (j != 0) {
j = (i<=5);
i = i+1;
printf("%d %d",i,j);
}
return 0;
}
I think that its meaning and the output is evident now. Note that printf does not print any separator after the second number. It means that the two digit "numbers" in the output are printed by two successive invocations of printf each. If you use printf("%d %d; ",i,j); instead of printf("%d %d",i,j); the output will be:
2 1; 3 1; 4 1; 5 1; 6 1; 7 0;
Your code is the same as
#include <stdio.h>
int main() {
int i = 1, j = 1;
while (j > 0) {
if (i <= 5) {
j = 1;
} else {
j = 0;
}
i = i + 1;
printf("%d %d",i, j);
}
}
It should now be easy to understand.
De-obfuscated, the code is equivalent to this:
for(int i=1; i<7; i++)
{
printf("%d\t%d\n", i+1, (i+1) < 7);
}
What such a loop would be needed for, I have no idea.
Initially, i and j are 1 so condition for loop will be true and it will enter into the loop.
At j = i++<=5; statement first it will execute conditional operation and assign result of conditional operation (true = 1, or, false = 0) to j and increment i by one. After this, it will execute print statement from the loop which will print value for i (which is now incremented by one is 2) and j (will be 1 as the condition is true). This will continue until the i<=5 condition is true. Whenever i becomes greater than 5 j will be 0, breaking the loop.
To make the code and its output more clear rewrite the program the following way
#include <stdio.h>
int main(void)
{
for ( int i = 1, j = 1; j != 0; )
{
j = i++ <= 5;
printf("%d %d\n", i, j );
}
return 0;
}
The program output is
2 1
3 1
4 1
5 1
6 1
7 0
As the variable j is calculated as a result of this condtion
i++ <= 5
then it will be always equal to 1 except when i will be equal to 6 because for this value of i the condition is evaluted to false that is to 0 and this value is assigned to j.
So the last iteration of the loop is when i is equal to 6. In this case after this statement
j = i++ <= 5;
i will be equal to 7 and j will be equal to 0. These values are outputted in the last iteration of the loop.
7 0

Resources