Why does the code give me wrong triangle? - c

Make a triangle
*
**
***
****
*****
******
*******
********
*********
**********
***********
************
int rows = 12, i = 1, j = 1;
while(i <= rows)
{
while(j <= i)
{
printf("*");
j++;
}
printf("\n");
i++;
j=1;
I try to make a triangle like
********
*******
******
*****
****
***
**
*
but i am getting wrong.

You have problem with
while(j <= i)
loop. Here is my solution:
int rows = 12, i = 1, j = 1;
while (i <= rows)
{
while (j <= (rows - i +1))
{
printf("*");
j++;
}
printf("\n");
i++;
j = 1;
}

Basically you have to reverse your loops. So for each loop in your code you're increasing the number of instances '*' is printed for each iteration of i. This is because i and j start at 1 and are increased until the number of iterations equals rows.
int rows = 12, i = 1, j = 1;
while (i <= rows)
{
while (j <= (rows - i +1))
{}
}
What you want is to start from 12, and decrement each time until you hit 0. So to start with you can loose the variable rows, and set i and j equal to 12. In the outer while() loop you want to decrement i and reset j = i each time the inner loop closes. The inner loop should print * and decrement j. Below is my solutions, but Loc Tran's answer works just as well.
int main(void){
int i = 12, j = 12;
while(i >=0)
{
while(j >= 0)
{
printf("*");
j--;
}
printf("\n");
i--;
j=i;
}
}
If this is for a school assignment (I had one quite similar in a 1st year course) I suggest you try understand why your code is different to the provided solutions.

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

Error printing a pyramid pattern with asterisks in C [duplicate]

This question already has answers here:
What is a null statement in C?
(6 answers)
Closed 2 years ago.
The program asks the user for the pyramid hight i.e: rows number, and prints out a pyramid.
for input of 5, the result should look like this:
*
***
*****
*******
*********
the code I wrote is:
#include <stdio.h>
void main()
{
int i, j, n = 0;
printf("enter pyramid hight: \t");
scanf("%d", &n);
// FOR EACH ROW:
for (i = 0; i < n; i++)
{
// print spaces till middle:
for (j = 0; j < (n - 1 - i); j++)
{
printf(" ");
}
// print stars:
for (j = 0; j < 2 * n + 1; j++)
;
{
printf("*");
// go to new row
printf("\n");
}
}
}
but the result is:
*
*
*
*
*
what could be going wrong exactly, I think the second loop may be the problem but I can't put my hand on the reason.
You got a logic errors for the second for loop which does not do what you want:
// print stars:
for (j = 0; j < 2 * n + 1; j++) //<-- error #1 - n should be i as it's specific for this row
; //<-- error #2 - this termination is completely wrong, it means this `for` loop doing nothing
{
printf("*");
// go to new row
printf("\n");
}
which should be:
// print stars:
for (j = 0; j < 2 * i + 1; j++)
{
printf("*");
}
// go to new row
printf("\n");

Print repeating diamond shapes with custom rows, columns and length

I am new to C, and I am trying to print diamond shapes according to the rows(2~10), columns(2~10) and the length(3, 5, 7, 9) of the diamond input from the user.
Using the code below I can print diamond and number of diamonds correctly, but I just can't get the correct distance between them.
void printDiamondWith(int diamondlength, int numberOfDiamonds) {
int i, j, k;
int star, space;
star = 1;
space = diamondlength;
for (i = 1; i < diamondlength * 2 - 1; i++) {
for (k = 0; k < numberOfDiamonds; k++) {
for (j = 0; j < space; j++) {
printf(" "); // Print the distance for the previous star
}
for (j = 1; j < star * 2; j++) {
printf("*");
}
for (j = 0; j < space; j++) {
printf(" "); // Print the distance for the next star
}
}
printf("\n");
// Check if length is equal 3, else length -1 to get the correct rows of second half of the diamond
if (diamondlength == 3) {
// Loops until the first half of the diamond is finished, then reverse the process to print the second half
if(i < (diamondlength - diamondlength / 3)) {
space--;
star++;
} else {
space++;
star--;
}
} else if (diamondlength >= 3) {
if (i < (diamondlength - 1 - diamondlength / 3)) {
space--;
star++;
} else {
space++;
star--;
}
}
}
}
Actual running result:
Expected result:
Your formulas for calculating the space is off. It works for me when I change this
space = diamondlength;
to this
space = diamondlength/2+1;
And this
for (k = 0; k < numberOfDiamonds; k++) {
for (j = 0; j < space; j++) {
to this:
for (k = 0; k < numberOfDiamonds; k++) {
for (j = 0; j < space-1; j++) {
In such situations I recommend hardcoding the variable for different parameters and write down what the variable has to be for what parameter so you can try to find a function that maps the parameter to the value. For instance I saw that as diamondlength increased, the space error also increased, so the relation between parameter and variable can't be one to one.

Need to do a half of a christmas tree with "*"

The output desired from the half of Christmas tree is:
*
**
***
****
*****
I could get a output like this:
*
**
***
****
*****
By using only cycles and conditions (arrays, can't be used), how can I get a solution like the first one?
main()
{
int n;
printf("Introduza o nĂºmero de ramos: ");
scanf_s("%d", &n);
for (int i = 1; i <= n; i++)
{
for (int j = 1 ; j <= i; j++)
{
putchar('*');
}
putchar('\n');
}
}
You obviously understand how to put a number of same characters next to each other.
The only thing left to do for you is to notice that the only difference between the first half-tree and the second is some spaces in front of the stars.
Also notice that the number of spaces is quite predictable, given the number of stars: the total width of spaces and stars is constant.
You just need to give a condition in inner loop. you should run the inner loop from 1 to n and print a " "(space) if j is less then i else print '*'
for (int i = 1; i <= n; i++)
{
for (int j = 1 ; j <= n; j++)
{
if(j < i)
putchar(' ');
else
putchar('*');
}
putchar('\n');
}

8 Queens puzzle with recursive deep search

I'm trying to solve the 8 queens puzzle problem in C. I'm having problems with the recursive search. The program is supposed to start at a given column:
execute(tabuleiro,8,0);
Where the 8 is the number of columns in the board, and 0 is the start column.
This works when I start at column 0. When I send any other column number to the recursive search, the program just counts to the last column. For example, if I choose to start the search from the number 5 column, the code search from the column 5 to 7, after this it should search from 0 to 4, but it doesn't do that.
If I do this:
execute(tabuleiro,8,3);
It fills in only the last 5 colummns, and does not return to column 0 to finish the solution:
Also, how can I select the initial position for the queen in this code? Like I said before, the column is assigned in the code, but I'm not sure how to pick the correct column.
The code has 3 functions: one is to display the board, a second to check if the move is legal (so one queen doesn't attack the other), and the last one to place one queen and recur for the remainder of the board.
#include <stdlib.h>
#include <windows.h>
int sol = 0;
void viewtab(int tab[][8], int N)
{
int i,j;
for( i = 0; i < N; i++)
{
for( j = 0; j < N; j++)
{
if(tab[i][j] == 1)
printf("R\t");
else
printf("-\t");
}
printf("\n\n");
}
printf("\n\n");
system("pause");
printf("\n");
}
int secury(int tab[][8], int N, int lin, int col)
{
// this function is to check if the move is secury
int i, j;
// attack in line
for(i = 0; i < N; i++)
{
if(tab[lin][i] == 1)
return 0;
}
//attack in colune
for(i = 0; i < N; i++)
{
if(tab[i][col] == 1)
return 0;
}
// attack in main diagonal
//
for(i = lin, j = col; i >= 0 && j >= 0; i--, j--)
{
if(tab[i][j] == 1)
return 0;
}
for(i = lin, j = col; i < N && j < N; i++, j++)
{
if(tab[i][j] == 1)
return 0;
}
// attack in main secondary
for(i = lin, j = col; i >= 0 && j < N; i--, j++)
{
if(tab[i][j] == 1)
return 0;
}
for(i = lin, j = col; i < N && j >= 0; i++, j--)
{
if(tab[i][j] == 1)
return 0;
}
// if arrive here the move is secury and return true
return 1;
}
void execute(int tab[][8], int N, int col)
{
int i;
if(col == N)
{
printf("Solution %d ::\n\n", sol + 1);
viewtab(tab, N);
sol++;
return;
}
for( i = 0; i < N; i++)
{
// check if is secury to put the queen at that colune
if(secury(tab, N, i, col))
{
// insert the queen (with 1)
tab[i][col] = 1;
// call recursive
execute(tab, N, col + 1);
// remove queen (backtracking)
tab[i][col] = 0;
}
}
}
int main()
{
int i, j, tabuleiro[8][8];
for (i = 0; i < 8; i = i + 1)
for (j = 0; j < 8; j = j + 1) tabuleiro[i][j] = 0;
execute(tabuleiro,8,0);
return 0;
}
The search always stops in the rightmost column because you specifically tell it to stop there:
void execute(int tab[][8], int N, int col)
{
int i;
if(col == N)
{
printf("Solution %d ::\n\n", sol + 1);
viewtab(tab, N);
sol++;
return;
}
Look at your termination condition: you check the current column against the highest column number, and stop there.
If you want to go back to column 0, you have to change your loop logic. For instance, let col reach N, at which point you reset it to 0, and let it continue until you hit the original value. Another way is to continue until the count of placed queens is N.
You choose the initial point in the same way: you pick the first one and make your recursive call. If that eventually results in a solution, you print it. If not, your top-most call continues to the next row (line) of the board and puts the first queen there.
This is already in your main logic. Just make sure that secury will return true when the board is empty, rather than false or throwing an error.
A. You can place the first Queen at (0,0).
B. And begin the search also from (0,0).
C. I do not see any need to start looking for some other index.
Successfully!!

Resources