Program keeps printing one extra line then what the user inputs - cs50

I'm having some trouble trying to build a pyramid out of "#" for mario.c in problem set 1. My program seems to be having some trouble with handling input.
I get these errors:
:( handles a height of 1 correctly
expected ""#"", not "" #"\n"##""
:( handles a height of 2 correctly
expected "" #"\n"##"", not "" #"\n" ##"\n..."
:( handles a height of 8 correctly
expected "" #"\n" ...", not "" #"\n"..."
:( rejects a height of 9, and then accepts a height of 2
expected "" #"\n"##"", not "" #"\n" ##"\n..."
Here is my code:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int height;
do
{
height = get_int("How many rows for the pyramid?\n");
}
while (height < 1 || height > 8); //This loops until the user input 1 - 8 rows
for (int row = 0; row <= height; row++) //This says to print a new row until it reaches the user inputted height
{
for (int spaces = (height - (row + 1)); spaces >= 0; spaces--) //This formula prints less spaces as more rows are printed
{
printf(" ");
}
for (int hashes = 1; hashes <= (row + 1); hashes++) //This formula prints more hashes as more rows are printed
{
printf("#");
}
printf("\n");
}
}
Any help is appreciated!!

Your code prints an extra line of hashtags creating a pyramid which is 1 greater in height than the user input. You can see this in the error message you get:
:( handles a height of 1 correctly expected ""#"", not "" #"\n"##""
Hence, the output of your program is #\n## which equates to
#
##
The required output for a height of 1 is:
#
To fix your issue, you have to iterate through your code one lesser time than you do currently for any number. Hence, perhaps consider changing the condition: row <= height; in your for loop.
Consider changing the comparison to just <. By doing this, the code inside the for loop will run one lesser time.

Related

find the number of ways you can form a string on size N, given an unlimited number of 0s and 1s

The below question was asked in the atlassian company online test ,I don't have test cases , this is the below question I took from this link
find the number of ways you can form a string on size N, given an unlimited number of 0s and 1s. But
you cannot have D number of consecutive 0s and T number of consecutive 1s. N, D, T were given as inputs,
Please help me on this problem,any approach how to proceed with it
My approach for the above question is simply I applied recursion and tried for all possiblity and then I memoized it using hash map
But it seems to me there must be some combinatoric approach that can do this question in less time and space? for debugging purposes I am also printing the strings generated during recursion, if there is flaw in my approach please do tell me
#include <bits/stdc++.h>
using namespace std;
unordered_map<string,int>dp;
int recurse(int d,int t,int n,int oldd,int oldt,string s)
{
if(d<=0)
return 0;
if(t<=0)
return 0;
cout<<s<<"\n";
if(n==0&&d>0&&t>0)
return 1;
string h=to_string(d)+" "+to_string(t)+" "+to_string(n);
if(dp.find(h)!=dp.end())
return dp[h];
int ans=0;
ans+=recurse(d-1,oldt,n-1,oldd,oldt,s+'0')+recurse(oldd,t-1,n-1,oldd,oldt,s+'1');
return dp[h]=ans;
}
int main()
{
int n,d,t;
cin>>n>>d>>t;
dp.clear();
cout<<recurse(d,t,n,d,t,"")<<"\n";
return 0;
}
You are right, instead of generating strings, it is worth to consider combinatoric approach using dynamic programming (a kind of).
"Good" sequence of length K might end with 1..D-1 zeros or 1..T-1 of ones.
To make a good sequence of length K+1, you can add zero to all sequences except for D-1, and get 2..D-1 zeros for the first kind of precursors and 1 zero for the second kind
Similarly you can add one to all sequences of the first kind, and to all sequences of the second kind except for T-1, and get 1 one for the first kind of precursors and 2..T-1 ones for the second kind
Make two tables
Zeros[N][D] and Ones[N][T]
Fill the first row with zero counts, except for Zeros[1][1] = 1, Ones[1][1] = 1
Fill row by row using the rules above.
Zeros[K][1] = Sum(Ones[K-1][C=1..T-1])
for C in 2..D-1:
Zeros[K][C] = Zeros[K-1][C-1]
Ones[K][1] = Sum(Zeros[K-1][C=1..T-1])
for C in 2..T-1:
Ones[K][C] = Ones[K-1][C-1]
Result is sum of the last row in both tables.
Also note that you really need only two active rows of the table, so you can optimize size to Zeros[2][D] after debugging.
This can be solved using dynamic programming. I'll give a recursive solution to the same. It'll be similar to generating a binary string.
States will be:
i: The ith character that we need to insert to the string.
cnt: The number of consecutive characters before i
bit: The character which was repeated cnt times before i. Value of bit will be either 0 or 1.
Base case will: Return 1, when we reach n since we are starting from 0 and ending at n-1.
Define the size of dp array accordingly. The time complexity will be 2 x N x max(D,T)
#include<bits/stdc++.h>
using namespace std;
int dp[1000][1000][2];
int n, d, t;
int count(int i, int cnt, int bit) {
if (i == n) {
return 1;
}
int &ans = dp[i][cnt][bit];
if (ans != -1) return ans;
ans = 0;
if (bit == 0) {
ans += count(i+1, 1, 1);
if (cnt != d - 1) {
ans += count(i+1, cnt + 1, 0);
}
} else {
// bit == 1
ans += count(i+1, 1, 0);
if (cnt != t-1) {
ans += count(i+1, cnt + 1, 1);
}
}
return ans;
}
signed main() {
ios_base::sync_with_stdio(false), cin.tie(nullptr);
cin >> n >> d >> t;
memset(dp, -1, sizeof dp);
cout << count(0, 0, 0);
return 0;
}

stuck on CS50x left aligned to right aligned mario pyramid

I have been trying to make my pyramid from left aligned to right aligned but i am confused on how to do it. This is the code i am using.
Edit: i have changed the code but i have been getting an error
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int height;
do
{
//asks user for number between 1 and 8
height = get_int("please give height: ");
}
while (height < 1 || height > 8);
//prints rows (i)
for (int rows = 0; rows < height; rows++)
{
//prints spaces (j)
for (int spaces = 0; spaces < height - rows; spaces++)
{
printf(".");
}
printf("\n");
}
for (int hashes = 0; rows < height - rows; hashes++)
{
printf("#");
}
printf("\n");
}
user gets prompted and writes number between 1 and 8
user types 4
Expected
...#
..##
.###
####
Actual output
....
...
..
.
mario.c:24:48: error: use of undeclared identifier 'rows'
for (int hashes = 0; rows < height - rows; hashes++)
^
mario.c:24:32: error: use of undeclared identifier 'rows'
for (int hashes = 0; rows < height - rows; hashes++)
^
2 errors generated.
<builtin>: recipe for target 'mario' failed
make: *** [mario] Error 1
i am trying to print hashes and use the rows interger but for some reason the error says it is am undefined interger.
I think the error is because you're curly brackets {} in your first and second for loops are mixed up. It looks like you're trying to do three loops that are nested inside each other; however, your third loops is outside the first one because you have an extra } in the middle of your code for the second loop. The variable row is declared in the first loop and the third loop doesn't know what that means since it is outside the first loop.
Sticking to the class's recommendations about indentation helped me keep this straight.

CS50 Mario Pyramid in C - Hashes not printing out as expected by code logic

#include <stdio.h>
#include <cs50.h>
int main(void)
{
int height, row, spaces, hashes; //declare all variables to be used
do //prompt the user for valid height inputs that are non-negative and less than 23.
{
printf("Height:");
height = get_int();
} while ((height < 0) || (height > 23));
for (row = 1; row <= height; row ++) // iterate through each row of the height
{
for (spaces = (height - row); spaces >= 0; spaces--) //print the number of spaces for the ith row
{
printf(" ");
}
for (hashes = (row + 1); hashes <= (height + 1); hashes++) //print the number of hashes for each row
{
printf("#");
}
printf("\n");
}
}
Not sure what I am missing in the above code. The spaces print as expected, but the behavior of the hashes is inverted, printing the highest and decreasing.
Let's assume the user submitted 12 as height.
You start the outer loop with row = 1, which gives spaces from height - row = 11 to 0, makes 12 spaces.
The hashes go from row + 1 = 2 to height + 1 = 13, makes 12 hashes.
Next iteration of the loop: 11 spaces, 11 hashes.
What you have expected can be achieved if you changes the second inner loop:
for (hashes = 0; hashes < row; hashes++) //print the number of hashes for each row
If this is not exactly what you need, change beginning of the loop to hashes = 1; or the end to row - 1; or whatever you need.
Your mistake was to assume that hashes++ makes it ascending. It does, technically, but it only changes the order of the loop, not how often it is run. Since you do not need the actual value of hashes, the order is irrelevant. The only thing that counts is how often the loop is run ;)

check50 error messages: On my Mario.c pset1 solution

:( handles a height of 0 correctly \ expected an exit code of 0, not output of "\n Please enter a positive integer valu..."
:( rejects a non-numeric height of "" \ expected output, not a prompt for input
https://sandbox.cs50.net/checks/5593ad8059ce4492804c07aff8e377eb
I think I should put part of my code too:
#include <stdio.h>
int clean_stdin()
{
while (getchar()!='\n');
return 1;
} //snippet gotten from http://stackoverflow.com/questions/14104013/prevent-users-from-entering-wrong-data-types
int main (void)
{
int row, pyramid_height, space, hash;
char c;
do
{
printf("\n Please enter a positive integer value, less than 24 as the height: ");
}
while (((scanf("%i%c", &pyramid_height, &c) != 2 || c!='\n') && clean_stdin()) || pyramid_height < 1 || pyramid_height > 23);
//snippet gotten from http://stackoverflow.com/questions/14104013/prevent-users-from-entering-wrong-data-types
Please help:
Also, Is there an easier way to prevent users from entering wrong data?
Thank you.
You should do something like this to ask the user for input
printf("Enter height < 23 and a non-negative number\n");
do{
printf("Height: ");
height = GetInt(); // ask user again until valid input is given
}while(height < 0 || height >23);
If you don't want to use GetInt() you can do this with scanf too. Just replace the GetInt line with scanf("%d",&height);. It'll work the same except when you enter a wrong number it'll yell at you by saying Height:
rather than Retry:.
And you should remove that clean_stdin function. That level of precision is not required in pset1.
Now the remaining part is the nested for loops which you've not provided in the question so, I am assuming that you have a problem there too since your program can't handle 0 properly.
Try something like this in place of the for loops.
for(int i=1; i<=height; i++){ // i number of #s in each step
for(int j=0; j<height-i; j++){ //print appropriate number of spaces
printf(" ");
}
for(int k=0; k<=i; k++){ //print #s
printf("#");
}
printf("\n"); //change line
}

Counter for two binary strings C++

I am trying to count two binary numbers from string. The maximum number of counting digits have to be 253. Short numbers works, but when I add there some longer numbers, the output is wrong. The example of bad result is "10100101010000111111" with "000011010110000101100010010011101010001101011100000000111000000000001000100101101111101000111001000101011010010111000110".
#include <iostream>
#include <stdlib.h>
using namespace std;
bool isBinary(string b1,string b2);
int main()
{
string b1,b2;
long binary1,binary2;
int i = 0, remainder = 0, sum[254];
cout<<"Get two binary numbers:"<<endl;
cin>>b1>>b2;
binary1=atol(b1.c_str());
binary2=atol(b2.c_str());
if(isBinary(b1,b2)==true){
while (binary1 != 0 || binary2 != 0){
sum[i++] =(binary1 % 10 + binary2 % 10 + remainder) % 2;
remainder =(binary1 % 10 + binary2 % 10 + remainder) / 2;
binary1 = binary1 / 10;
binary2 = binary2 / 10;
}
if (remainder != 0){
sum[i++] = remainder;
}
--i;
cout<<"Result: ";
while (i >= 0){
cout<<sum[i--];
}
cout<<endl;
}else cout<<"Wrong input"<<endl;
return 0;
}
bool isBinary(string b1,string b2){
bool rozhodnuti1,rozhodnuti2;
for (int i = 0; i < b1.length();i++) {
if (b1[i]!='0' && b1[i]!='1') {
rozhodnuti1=false;
break;
}else rozhodnuti1=true;
}
for (int k = 0; k < b2.length();k++) {
if (b2[k]!='0' && b2[k]!='1') {
rozhodnuti2=false;
break;
}else rozhodnuti2=true;
}
if(rozhodnuti1==false || rozhodnuti2==false){ return false;}
else{ return true;}
}
One of the problems might be here: sum[i++]
This expression, as it is, first returns the value of i and then increases it by one.
Did you do it on purporse?
Change it to ++i.
It'd help if you could also post the "bad" output, so that we can try to move backward through the code starting from it.
EDIT 2015-11-7_17:10
Just to be sure everything was correct, I've added a cout to check what binary1 and binary2 contain after you assing them the result of the atol function: they contain the integer numbers 547284487 and 18333230, which obviously dont represent the correct binary-to-integer transposition of the two 01 strings you presented in your post.
Probably they somehow exceed the capacity of atol.
Also, the result of your "math" operations bring to an even stranger result, which is 6011111101, which obviously doesnt make any sense.
What do you mean, exactly, when you say you want to count these two numbers? Maybe you want to make a sum? I guess that's it.
But then, again, what you got there is two signed integer numbers and not two binaries, which means those %10 and %2 operations are (probably) misused.
EDIT 2015-11-07_17:20
I've tried to use your program with small binary strings and it actually works; with small binary strings.
It's a fact(?), at this point, that atol cant handle numerical strings that long.
My suggestion: use char arrays instead of strings and replace 0 and 1 characters with numerical values (if (bin1[i]){bin1[i]=1;}else{bin1[i]=0}) with which you'll be able to perform all the math operations you want (you've already written a working sum function, after all).
Once done with the math, you can just convert the char array back to actual characters for 0 and 1 and cout it on the screen.
EDIT 2015-11-07_17:30
Tested atol on my own: it correctly converts only strings that are up to 10 characters long.
Anything beyond the 10th character makes the function go crazy.

Resources