Explain the output of 2D array with nested loop code - arrays

#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.

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...

Why is the output 321 instead of 212?

#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

Why won't for loop terminate?

My function:
int checkSE(disk board[][SIZE], disk hypotheticalDisk)
{
int i;
int j;
int row;
int col;
int player;
int opponent;
int checkSEflag;
player = hypotheticalDisk.type;
(player == 0) ? (opponent = 1) : (opponent = 0);
row = hypotheticalDisk.pos.row;
col = hypotheticalDisk.pos.col;
checkSEflag = 0;
for (i = row + 2, j = col + 2; ((i < SIZE) && (j < SIZE) && (checkSEflag == 0)); i++, j++)
{
if (board[i][j].type == player)
{
for (--i, --j; board[i][j].type == opponent; i--, j--)
{
if (i == row && j == col)
{
checkSEflag = 1;
break;
}
}
}
printf("\n%d and %d and %d", i, j, checkSEflag);
}
return checkSEflag;
}
My output:
2 and 3 and 0
2 and 3 and 0
2 and 3 and 0
2 and 3 and 0
2 and 3 and 0
.
.
.
And it keeps on going...
I want both i and j to increase until they are equal to SIZE (SIZE predefined to be 8) or until checkSEflag is assigned to be equal to 1.
It looks like the values of i and j just aren't being changed...
I tried taking them out of the loop conditions and instead placed them
in the loop body, though that didn't change anything.
I doubt the post increment operators just decided to not work so I must be doing something wrong, any ideas of what that may be?
These two lines:
for(i = row+2, j = col+2; ((i < SIZE) && (j <SIZE) && (checkSEflag == 0)); i++, j++)
...
for(--i, --j; board[i][j].type == opponent; i--, j--)
so, you are both incrementing and decrementing (i,j); try sprinkling printfs around these and see if you are both incrementing and decrementing i,j on each iteration...

To sort an array in required manner

I need to sort the elements in the odd positions in the descending order and elements in the even position in ascending order. Here is my code, I'm unable to break the first loop.
#include<stdio.h>
int main()
{
int n, t;
printf("Enter the size of the array\n");
scanf("%d", &n);
int i, a[n];
if ((n > 20) || (n <= 0))
printf("Invalid Size");
else
{
printf("Enter the values\n");
for (i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
for (i = 0; i < n; i + 2)
{
if (a[i] > a[i + 2])
{
t = a[i];
a[i] = a[i + 2];
a[i + 2] = t;
}
}
for (i = 1; i < n; i + 2)
{
if (a[i] < a[i + 2])
{
t = a[i];
a[i] = a[i + 2];
a[i + 2] = t;
}
}
for (i = 0; i < n; i++)
{
printf("%d\n", a[i]);
}
}
}
For starters according to the C Standard the function main without parameters shall be declared like
int main( void )
There is no great sense to declare the variable n as having the type int that after that to check whether its value is less than zero. It is much better to declare it as having the type size_t.
And the array should be declared after the check
if ((n > 20) || (n <= 0))
printf("Invalid Size");
else
{
int a[n];
//...
In loops like this
for (i = 0; i < n; i + 2)
the variable i is not increased. It is obvious that you mean i += 2.
And the loops only moves the first minimum even and the first maximum odd elements to the end of the array. You need additional loops that will do the same operation for other elements of the array. That is the implementation of the bubble sort algorithm is incorrect.
Here is a demonstrative program that shows how the array can be sorted according to the requirements for even and odd elements of the array.
#include <stdio.h>
#define N 20
int main(void)
{
int a[N] = { 18, 1, 16, 3, 14, 5, 12, 7, 10, 9, 8, 11, 6, 13, 4, 15, 2, 17, 0, 19 };
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
for ( size_t n = N, last; !( n < 3 ); n = last )
{
for ( size_t i = last = 2; i < n; i++ )
{
if ( ( i % 2 == 0 && a[i] < a[i - 2] ) ||
( i % 2 == 1 && a[i - 2] < a[i] ) )
{
int tmp = a[i];
a[i] = a[i - 2];
a[i - 2] = tmp;
last = i;
}
}
}
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
The program output is
18 1 16 3 14 5 12 7 10 9 8 11 6 13 4 15 2 17 0 19
0 19 2 17 4 15 6 13 8 11 10 9 12 7 14 5 16 3 18 1
The most obvious problem is that your for never ends because i is never actually updated. The i+2 in for (i = 0; i < n; i + 2) does not update i which keeps its initia value forever.
Try something like for (i = 0; i < n; i=i+2) instead.
A second problem is that you are not really performing a sorting.
I guess that you are trying to implement some sort of bubble sort.
It sorts using comparison. It is impossible to sort an array using less than n logn operation (when sorting using comparison). You are sorting the array in linear time and this should look as a red flag to you.
Try adding another for as follows:
for (i = 0; i < n; i+= 2)
for (j = i+2; j < n; j+= 2)
if (a[i] > a[j])
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
and most importantly then read about why you need it.
And if you feel brave you can swap the intgers without using an intermediate variable t as follows (read more on the topic here: XOR swap):
if (a[i] > a[j])
{
a[i] = a[i]^a[j];
a[j] = a[j]^a[i];
a[i] = a[i]^a[j];
}
Hope it helps.

C - bubble sort with decreased loops amount

I've written the function which bubble-sorts some given array, and stops execution when the array is already sorted.
int sort(int *arr, int size) {
int i, j, temp, st = 1, count = 0;
for(i = 0; (i < size - 1) && (st == 1); i++)
{
st = 0;
for(j = 0; j < size - 1; j++)
{
if(arr[j] < arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
st = 1;
}
count++;
}
}
return count;
}
As you can see, the loop should be broken when the array is sorted before size^2 move.
However, something is wrong, and the count variable is always size * size, no matter what array I pass, even {1, 2, 3, 4, 5} gives the same results.
What is wrong?
With the condition
if(arr[j] < arr[j + 1])
you are sorting the array in descending order. So if you pass it [5, 4, 3, 2, 1], you'll get a value of less than size*size.
Note that each iteration of the outer loop moves one element to its final place at the end of the array, so you can cut down the inner loop to run only
for(j = 0; j < size - 1 - i; j++)
If we run
#include <stdio.h>
int sort(int *arr, int size) {
int i, j, temp, st = 1, count = 0;
for(i = 0; (i < size - 1) && (st == 1); i++)
{
st = 0;
for(j = 0; j < size - 1; j++)
{
if(arr[j] < arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
st = 1;
}
count++;
}
}
return count;
}
int main(void) {
#ifdef ASCENDING
int ar[] = { 1, 2, 3, 4, 5 };
#else
int ar[] = { 5, 4, 3, 2, 1 };
#endif
int i, ct = sort(ar, sizeof ar / sizeof ar[0]);
printf("%d\n",ct);
for(i = 0; i < (int)(sizeof ar / sizeof ar[0]); ++i) {
printf("%d ", ar[i]);
}
printf("\n");
return 0;
}
compiled without ASCENDING defined, the output is
4
5 4 3 2 1
thus the outer loop breaks after the first iteration because the array is already sorted as desired. When compiled with -DASCENDING, the array is originally in ascending order and needs the complete cycle to become sorted, i.e. the output is
16
5 4 3 2 1
(with the count being reduced to 10 if the inner loop runs only for j < size - 1 - i).

Resources