While and for loops not giving the right answer - c

My code is supposed to make a pyramid as such, but just gives me a line, why? I've tried changing the conditions of the for and while loops and haven't found any solution. Any help would be appreciated!!
#
##
###
####
#####
######
#######
########
#include <stdio.h>
#include <cs50.h>
int main(void)
{
int n = get_int("Add the height of the pyramid: ");
int j = 0;
for(int i = 0; i < n ; i++) {
while (j <= i) {
printf("#");
j = j + 1;
}
printf("\n");
}

Declare j inside the for loop so it starts at 0 on each iteration.
for(int i = 0; i < n; i++) {
int j = 0;
while (j <= i) {
printf("#");
j = j + 1;
}
printf("\n");
}
The inner loop could also be rewritten as a for loop.
for(int i = 0; i < n; i++) {
for (int j = i; j >= 0; j--) printf("#");
printf("\n");
}

While the answer from #Unmitigated is correct, this would be a great place to break out some functionality into a function.
void print_n_ln(char *str, int n) {
for (; n > 0; n--) {
printf("%s", str);
}
printf("\n");
}
Then:
int main(void) {
int n = get_int("Add the height of the pyramid: ");
for (int i = 1; i <= n; i++)
print_n_ln("#", i);
return 0;
}

While an iterative solution (nested for() loops) would be simplest, this might be a good time to discover recursion. As long as the pyramid is not so tall as to risk stack overflow, the following works (leaving gathering/validating user input as an exercise.)
#include <stdio.h>
#include <cs50.h>
void print( int n ) {
if( n > 1 )
print( n - 1 );
while( n-- )
putchar( '#' );
putchar( '\n' );
}
int main() {
print( 7 );
return 0;
}
putchar() is a much simpler function than printf() and should be used when outputting a simple single character (for speed and efficiency.)
If you think your way through the operation presented, you will come to understand recursion and how it may sometimes be used to solve problems.
Another (albeit 'limited') solution follows:
int main() {
char wrk[] = "################";
int i = sizeof wrk - 1; // 'i' starts as the 'length' of the string
int want = 7;
while( want-- )
puts( wrk + --i ); // adding decreasing values of 'i' prints longer strings
return 0;
}
puts() will output a string to stdout while appending a 'newline'.
NB: Its more general sibling function (fputs()) works in a similar fashion, but does NOT append the LF for you.
There are often many ways to do things.
EDIT:
Here's another minimalist solution using pointers. This one uses a "compile time" string, so is not easily amenable to influence by a user (but it could be made so, if you're clever.)
#include <stdio.h>
#include <string.h>
int main() {
char want[] = "#######";
char *p = want + strlen( want );
while( --p >= want) puts( p );
return 0;
}

Related

How to stop the loop after printing one?

So here is the problem: Write a program that accept an integer n, print out the largest number but smaller or equal n that is the product of two consecutive even number. Example: Input: 12, Output: 8 ( 2x4 )
Here is my code :
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
for (int i = n; i >= 0; i--)
{
for (int j = 0; j <= n; j = j + 2)
{
if ( i == j * (j+2) )
{
printf("%d ", i);
break;
}
}
}
return 0;
}
So if i input 20, it will print out 8 and 0 instead of 8, if i input 30, it will print out 24,8 and 0 instead of just 24. How do i make it stop after printing out the first number that appropriate ?
You need to stop an outer loop from processing, for example by using a boolean flag (meaning "solution found, we finish work") or a goto statement.
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int solutionFound = 0;
for (int i = n; i >= 0; i--) {
// this could also be put into for's condition i.e. "i >= 0 && !solutionFound"
if (solutionFound) {
break;
}
for (int j = 0; j <= n; j = j + 2) {
if ( i == j * (j+2) ) {
printf("%d ", i);
solutionFound = 1;
break;
}
}
}
return 0;
}
EDIT: immediate return as noted in the comments is also a nice idea, if you don't need to do anything later.
Your problem is that you are nested - in a for loop which is inside another for loop - when you want to stop processing.
Some languages would let you code break 2; to indicate that you want to break out of 2 loops. Alas, C i snot such a language.
I would recommend that you code a function. That would serve a few porpoises: 1) your main should be "lean & mean" 2) as your programs get larger, you will learn the benefits of putting individual coding tasks into functions 3) you can use return; instead of break; and it will exit the function immediately.
Something like this:
#include <stdio.h>
void FindNeighbouringDivisors(int n)
{
for (int i = n; i >= 0; i--)
{
for (int j = 0; j <= n; j = j + 2)
{
if ( i == j * (j+2) )
{
printf("%d times %d = %d", j, j + 2, i);
return;
}
}
}
printf("There are no two adjacent even numbers which can be multiplied to give %d", n);
}
int main()
{
int n;
scanf("%d", &n); /* could get from comamnd line */
FindNeighbouringDivisors(n);
return 0; /* should be EXIT_SUCCESS */
}
Btw, when you have a problem with your code, ask a question here. When you have it working, consider posting it at our code review site where more experienced programmers can give you advice on how to improve it. It's a great way to learn
Break only breaks you out of immediate loop, so either use flags or just use return to terminate the execution. Or you can even use following code:
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
for (int j = 0; j <= n; j = j + 2)
{
if ( n < j * (j+2) )
{
printf("%d ", j*(j-2));
break;
}
}
return 0;
}

Programming in C - CS50 Mario pyramid blocks print - For loops difficulties

I am working on this problem from the CS50 class. I am still a beginner. What I need to program is this:
Toward the end of World 1-1 in Nintendo’s Super Mario Brothers, Mario
must ascend right-aligned pyramid of blocks, a la the below.
screenshot of Mario jumping up a right-aligned pyramid
Let’s recreate that pyramid in C, albeit in text, using hashes (#) for
bricks, a la the below. Each hash is a bit taller than it is wide, so
the pyramid itself is also be taller than it is wide.
#
##
###
####
#####
######
#######
########
The program we’ll write will be called mario. And let’s allow the user
to decide just how tall the pyramid should be by first prompting them
for a positive integer between, say, 1 and 8, inclusive.
However I have tried many ways, two of which are these:
code mariov1
After looking at some Stack Overflow attempts, it now looks like this:
#include <cs50.h>
#include <stdio.h>
string hash(int);
int main(void)
{
int n;
do
{
n = get_int("Height: ");
}
while (n < 0 || n > 8);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n-1-i; j++)
{
for(int j = 0; j < i+1; j++)
{
printf(".");
}
printf("#");
}
printf("\n");
}
}
What can I try next?
Suriyu, to add to what Weather Vane said. To pass it through Check50, you'll still need to make small tweaks to the code so that it passes through all CS50 tests.
For the do-while loop, n <=0 instead of n < 0 to ask for an input when n = 0, because the specification demands a minimum of one brick (1 to 8 both inclusive).
You need only the two loops, don't print extra characters not specified in the problem set, ex: printf(".");
All the best with CS50, it's going to be a fun experience!
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int n;
do
{
n = get_int("Height: ");
}
while (n < 1 || n > 8);
// this for loop makes new lines
for (int i = 0; i < n; i++)
{
// here I have two for loops nested inside the above for loop,
// I previously made the mistake of having two inner loops nested.
// this 2nd for loop prints n-1-i spaces
// because if n=5, then in the 4th row, there will be 5-1-3 spaces/dots
for (int j = 0; j < n - 1 - i; j++)
{
printf(" ");
}
// this 3rd for loop prints i+1 hashes
// because if n=5, then in the 4th row, there will be 3+1 hashes.
// (3 because you count from 0)
for (int j = 0; j < i + 1; j++)
{
printf("#");
}
printf("\n");
}
}
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int n;
do
{
n = get_int("Height of the pyramid is:\n");
}
while (n < 1 || n > 8); //condition to get a number from 1-8 from the user
for (int i = 0; i < n; i++) //loop for height
{
for (int j = 0; j < n - 1 - i; j++) //loop for spaces on left pyramid
{
printf(" ");
}
for (int k = 0; k < i + 1; k++) // loop for hashes on left pyramid
{
printf("#");
}
printf(" "); // spacing between pyramids
for (int p = 0; p <= i; p++) //loop for right pyramid
{
printf("#");
}
printf("\n");
}
}
This is the advanced version of the problem if you decide to try it.
Here's a different approach. Instead of iteratively printing blanks, followed by iteratively printing number signs, this version creates a buffer (size defined by a precompiler constant - currently set to 8, change it if you want to allow bigger pyramids), then for each row in the pyramid it first fills the buffer with number signs, then overlays the beginning of the line with the proper number of spaces, and then prints it:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#define MAXSIZE 8
int main(void)
{
int size, spaces;
char buf[MAXSIZE+1];
do
size = get_int("Height: ");
while (size < 0 || size > MAXSIZE);
buf[size] = '\0';
for(spaces = size-1 ; spaces >= 0 ; --spaces)
printf("%s\n", (char *)memset(memset(buf, '#', size), ' ', spaces));
}
EDIT
And here's yet another approach which builds the entire output block in an array in memory and then prints it using a single call to puts:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#define MAXSIZE 8
#define TOTSIZE ((MAXSIZE+1) * MAXSIZE)
int main(void)
{
int size, spaces;
char buf[TOTSIZE+1];
do
size = get_int("Height: ");
while (size < 0 || size > MAXSIZE);
memset(buf, '\n', (size+1)*size);
buf[((size+1)*size)] = '\0';
for(char *p = buf, spaces = size-1 ; *p != '\0' ; p += size+1, --spaces)
memset(memset(p, '#', size), ' ', spaces);
puts(buf);
}
This is an option that likely works best:
from cs50 import get_int
while True:
n=get_int("Enter Height: ")
if n>=1 and n<=8:
break
for i in range(0, n-1):
print(" " * (n - (i+1)) + "#" * (i+1))

Return string instead of int

When I print out a pyramid, the last line of the pyramid or the base prints out an integer which represents how many hashes, instead of a string of hashes.
like such:
Height: 3
#
##
3
when its supposed to be:
Height 3:
#
##
###
I'm supposed to print out a pyramid with a height based on the user's input, but instead of the base being printed out as a string it prints out an integer of how many hashes there should be for the base. I understand that this is because I'm returning n but I don't know how to go about it in a way where it still returns the loop.
I've tried changing the class to void instead of int, but that throws an error as it's conflicting types. I'm thinking I should print out an empty string but it messes with my bounds.
#include <cs50.h>
#include <stdio.h>
int get_height(string prompt);
int main(void)
{
int ask = get_height("Height: ");
printf("%i\n", ask);
}
int get_height(string prompt) {
int n;
do {
n = get_int("%s", prompt);
}
while (n < 1 || n > 8);
for (int i = 0; i < n; i++) {
for (int j = 0; j < i; j++) {
printf("#");
}
printf("\n");
}
return n;
}
The last line of output is the height because that is the last thing printed in your main function:
printf("%i\n", ask);
get_height will actually only print n-1 lines because the first iteration (i=0,j=0) is skipped.
the 3 should be output
The problem is this statement;
for (int j = 0; j < i; j++) {
which stops too early. Suggest:
for (int j = i; j >=0; j--) {
The output after making the above change:
#
##
###
3

How to create a pattern using for loops in C

I have been stumped by this problem. I need to create a pattern such as:
1
21
221
2221
22221
Using nested for loops. I have something that does (A)
222221
222221
222221
222221
222221
and used to have something that did (B)
/* 1
* 21
* 221
* 2221
* 22221
* 222221
* 2222222
*/
#include <stdio.h>
main()
{
int n, c, k;
printf("Enter number of rows\n");
scanf("%d",&n);
for ( c = 1 ; c <= n ; c++ )
{
printf("1\n");
for( k = 1 ; k <= c ; k++ )
printf("2");
}
return 0;
}
Any hints would be helpful.
Solution - Thanks to the intelligent people that decided to help.
I appreciate your help!
#include <stdio.h>
main()
{
int n, c, k;
printf("Enter number of rows");
scanf("%d",&n);
for ( c = 1 ; c <= n ; c++ )
{
for( k = 1 ; k < c ; k++ )
{
printf("2");
}
printf("1\n");
}
return 0;
}
This can be done using nested for loops. Let's examine the formulae for one line of the output:
line 1:
1
Which can be made using a simple for loop like this:
for (int i = 0; i < 1; i++)
{
putc('1', stdout);
putc('\n', stdout);
}
line 2:
21
Hmm, this requires change to our structure, as we can't break the output of iteration #1, but we still need to be able to add the '2' in there... Something like this should work:
for (int i = 0; i < 2; i++)
{
if (i > 0)
putc('2', stdout);
putc('1', stdout);
putc('\n', stdout);
}
line 3:
221
Wait, now we need two '2's in there! How can we do this without breaking line's 2 and three? Well something like this should do it:
for (int i = 0; i < 3; i++)
{
int j = i;
while (j--)
{
putc('2', stdout);
}
putc('1', stdout);
putc('\n', stdout);
}
Notice that I used a while loop instead of a for loop. It is an exercise to the reader to figure out how to turn that while loop into a for loop.
Hopefully this helped you to understand the process behind solving similar problems like this in the future - as it is an important programming skill to have.
Here is some code that generates your first pattern.
#include <stdio.h>
#define NUMLINES 5
int main(void) {
int i, j;
for(i=0; i<NUMLINES; i++) {
for(j=0; j<i; j++) {
printf("2");
}
printf("1\n");
}
return 0;
}
The important part is that the inner for loops until the current value of the outer loop is reached (j<i).

What's wrong with this C program [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Help with C puzzle
The intention of the program was to print a minus sign 20 times, but it doesn't work.
#include <stdio.h>
int main()
{
int i;
int n = 20;
for( i = 0; i < n; i-- )
printf("-");
return 0;
}
This is a classic puzzle!
The way I saw it was
"You can only change/insert/delete one character in the code to make the - print 20 times".
Some answers are (if I remember them correctly)
1)
#include <stdio.h>
int main()
{
int i;
int n = 20;
for( i = 0; -i < n; i-- )
printf("-");
return 0;
}
Here you change the i < n to -i < n
2)
#include <stdio.h>
int main()
{
int i;
int n = 20;
for( i = 0; i < n; n-- )
printf("-");
return 0;
}
Here you change the i-- to n--
3)
#include <stdio.h>
int main()
{
int i;
int n = 20;
for( i = 0; i + n; i-- )
printf("-");
return 0;
}
You change the i < n to i+n.
For a challenge, try changing/inserting/deleting one character to make it print the - 21 times. (Don't read the comments to this answer if you want to try it!)
#include <stdio.h>
int main()
{
int i;
int n = 20;
for( i = 0; i < n; i++ )
printf("-");
return 0;
}
You had -- instead of ++
Replace i-- with i++.
int main() {
int i;
int n = 20;
for( i = 0; i < n; i++)
printf("-");
return 0;
}
You had decrement instead of increment.
Have you tried changing the
i--
to
i++
You have the loop to print out a "-" for as long as "i" is less than 20.
After every loop you reduce the value of i by 1, it will continue to print
for a very long time. Changing the final part of the for loop to "i++" means it will perform one iteration each loop and stop once the twentieth iteration finished.
Change i-- to i++.
i-- decrements the value which at start is 0 and with subsequent reductions won't ever reach 20 (or +20).
the i-- needs to be i++
you could also do
int n = -20;
for( i = 0; i > n; i-- )
but that is bad coding practice
What exactly are you trying to do with this problem???
Here you are trying to decrement the value of a variable..a variable whose value will never reach the condition (i<20) you have provided... hence it will keep on printing '-' until what jamie wong specified, i.e. i= -2^31. It will become +ve. I just tried this program.
#include <stdio.h>
int main()
{
int i;
int n = 20;
for( i = 0; i < n; i-- )
printf("-");
return 0;
}
According to the question you asked, i should be incremented, i.e. i++ instead of i--.
#jamie wong: thanx man..learnt a new thing about tht a wraparound....
You'll print no dashes. You can either go with Jaime Wong's solution or do this:
for (i = n; i >= 0; i--)

Resources