Why is 100 not inclusive in this program? - c++

I am writing this program which will guess the number user is thinking about. After days of work, I could not figure out what is wrong in it.
Also my proposed grade for the assignment is not what I expected.
Please help.
User can guess 100, but my program uses mid-point rule so can only go up to 99. How can I make 100 inclusive?
If I keep pressing 'l' the program will eventually break out of loop and prints If you want to try again?
Is there a better way to code this program? Example please.
Here is the actual program:
Write a program in that can figure out a number chosen by a human user. The human user will think of a number between 1 and 100. The program will make guesses and the user will tell the program to guess higher or lower. The program should find the midpoint of the two numbers and ask if the number is higher or lower.
#include <iostream>
using namespace std;
int main() {
char check;
char tryagain;
do {
int midpoint;
const int MAX = 100;
const int MIN = 1;
int y = MAX;
int x = MIN;
cout << "Think of a number between 1 and 100." << endl;
midpoint = (x + y) / 2;
while (x != y || y != x) {
cout << endl << "Is it" << " " << midpoint << " " << "?";
cin >> check;
if (check == 'l' || check == 'L') {
y = midpoint;
midpoint = (x + y) / 2;
}
else if (check == 'h' || check == 'H') {
x = midpoint;
midpoint = (x + y) / 2;
}
else if (check == 'c' || check == 'C') {
break;
}
else {
cout << "Incorrect choice." << endl;
}
}
cout << "Great! Do you want to try again? (y/n)";
cout << endl;
cin >> tryagain;
} while (tryagain == 'y' || tryagain != 'n');
return 0;
}

Your problem is just a mis-think in the calculation of x and y like Alf suggested in the comments.
It should read
y = midpoint - 1;
and
x = midpoint + 1;
respectively. The reason is simple. You use midpoint as the guess. The guess is then no longer part of the available guesses. Your first guess is 50, x or y should then be either 51 or 49 as the new min or max in the interval.
This will also make 100 included in the available guesses. The last step in the calculation will be when midpoint was 99 and the user selects 'h'.
x = 99 + 1;
lower bound is 100, and the midpoint guess evaluates to
midpoint = (100 + 100) / 2;
which is correct.
As for better ways to write this program. This would depend on what your course has taught you, what's in the curriculum, and so on. You might want to check out code-review

When your x and y are too close, the division of their sum produces an incorrect midpoint. 100 + 99 / 2 = 99 (which is 99.5 rounded down). You need to check for this special case. At the end of the loop before the closing bracket insert:
if ( y-x < 2) midpoint = y;

User can guess 100, but my program uses mid-point rule so can only go up to 99. How can I make 100 inclusive?
Division of integers in c++ discards any decimal. It always rounds down. Consider what happens when midpoint is 99. You get midpoint = (99 + 100) / 2 which is 199 / 2 which is 99.5. Discarding the decimal leaves you with 99 every time. One possible solution is to change y = midpoint; to y = midpoint - 1; and x = midpoint; to x = midpoint + 1; This will prevent your application from guessing the same value more than once. With this change, when midpoint is 99, x will first be incremented to 100 giving us a new midpoint (100 + 100) / 2 which evaluates to 100.
If I keep pressing 'l' the program will eventually break out of loop and prints If you want to try again?
If the user keeps pressing l then eventually the only possible solution is 1. It seems that you chose not to propose your guess at that point and assume the user followed the rules. Add an extra print when the answer is deduced.
if (x == y) {
// Answer was deduced
cout << "You guessed " << x << ".\n";
}
Is there a better way to code this program? Example please.
See the first two parts of this answer. Other than that, it's difficult to say objectively what "better way to code this" means. You might want to consider a system to detect when the user is lying. For example, if midpoint == x then the user can't select l without lying.

Related

C++ question: User think a number 1-100, program asks questions no more than 6 times to get answer. can't get correct [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
User has to think of a number from 1 - 100. Computer keeps asking not more than 6 times to get what
the user think number. I could not get the logic right, I don't know how to fix anymore. Please somebody help me.
#include "std_lib_facilities.h"
// this program is not correct
// try 24 you will see it
int main()
{
cout << "Think of a number between 1 to 100\n";
int max{100};
int min{0};
int answer{0};
string response{"??"};
while ((max - min) != 1)
{
cout << "Is the number < " << (max + min) / 2 << "?\n";
cin >> response;
if (response == "y" || response == "yes")
{
max = ((max + min) / 2);
if ((max - min) == 1)
answer = min;
}
else if (response == "n" || response == "no")
{
min = (max + min) / 2;
if ((max - min) == 1)
answer = max;
}
else
{
error("Invalid response\n");
}
}
cout << "The answer is " << answer << endl;
keep_window_open();
return 0;
}
Thank you in advance.
As has already been pointed out in the comments section, there are at least 3 bugs in your code:
Your question states that the user should think of a number between 1 and 100, but the variables min and max are initialized to 0 and 100, as if the user was supposed to think of a number between 0 and 100. Therefore, you should initialize min to 1 instead of 0.
When the user replies "yes" to the question whether the number is below a certain value, you set max to this value. This does not make sense, because you know that the number cannot be this value, but must be below this value. Therefore, you should set max to this value minus 1.
When min == 1 and max == 2, it would make sense for the next question your program asks to be whether the number is "< 2", in order to determine whether the number is 1 or 2. However, in that case, your program asks whether the number is "< 1", which does not make sense, because it already knows that the answer to that question is "no". Therefore, instead of asking whether the number is smaller than (max + min) / 2, it would make more sense to ask whether the number is smaller than (max + min + 1) / 2.
I have cleaned up your code a bit and fixed the bugs mentioned above. Here is the code:
#include <iostream>
#include <string>
constexpr int MIN = 1;
constexpr int MAX = 100;
int main()
{
int min{ MIN };
int max{ MAX };
std::string response;
std::cout << "Think of a number between " << MIN << " and " << MAX << "." << std::endl;
while ( min != max )
{
int guess = (max + min + 1) / 2;
std::cout << "Is the number < " << guess << "? ";
std::cin >> response;
if ( response == "y" || response == "yes" )
{
max = guess - 1;
}
else if ( response == "n" || response == "no" )
{
min = guess;
}
else
{
std::cout << "Invalid response" << std::endl;
}
//The following line only exists for debugging purposes and can be disabled
std::cout << "min: " << min << " max: " << max << std::endl;
}
std::cout << "The number is " << min << "." << std::endl;
return 0;
}
I have rearranged the code in such a way that the numbers 1 and 100 are hard-coded only in one place, instead of several places in the program. This allows you to change the range very easily, without having to change the numbers in several places in the program.
One thing that my code does not do is stop asking after 6 questions, because it can take up to 7 questions to find the correct answer. In your question, you specified that it should ask not more than 6 times, but did not specify what should happen if it has not found the answer by then.

Dynamic numerical series

I am trying to create a program to print first 200 elements following a specific numerical series condition which is
1-1-3-6-8-8-10-20
But instead of showing, just 200 elements is showing 802. I assume is because of the code inside the for loop. I have hours thinking on how to reduce that code to the job and I cannot think anything else. I am getting frustrated and need your help.
The exercise is on the code comments
//Print the following numerical series 1-1-3-6-8-8-10-20 until 200
#include <stdafx.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
int Num1=200, z = 0, x = 1, y = 1;
cout << "\n\n1,";
cout << " 1,";
for (int i = 1; i <= Num1; i++)
{
z = y + 2;
cout << " " << z << ","; //It will print 3
z = z * 2;
cout << " " << z << ",";//It will print 6
z = z + 2;
cout << " " << z << ",";//It will print 8
z = z;
cout << " " << z << ",";//It will print 8
y = z;
}
cout << "\n\n";
system("pause");
return 0;
}
You're looping 200 times, and each time you loop, you're printing out 4 different numbers. You're also printing twice at the start so thats 2 + 4 * 200 = 802, which is where your 802 number output is coming from.
I assume is because of the code inside the "for" loop but I've hours
thinking on how to reduce that code to the job and I cannot think
anything else. I'm getting frustrated and need your help.
So you basically wanna simplify your code. Which can be done by noticing the repetitions.
There you can find only two types of change in the series; either a +2 or x2 with the previous element.
In each iteration this can be achieved by:
If reminder i%4 == 1 or i%4 == 3, need an increment of 2 (assuming 1 <= i <= MAX)
If reminder i%4 == 0, nothing but a multiplication of 2.
When you do like so, you can simply neglect, printing of first two ones and other complications in the total numbers in the series.
Also not that, you are trying to get 200 terms of this series, which increases in each step very fast and exceed the maximum limit of int. Therefore, long long is needed to be used instead.
The updated code will look like this:
#include <iostream>
typedef long long int int64;
int main()
{
int size = 200;
int64 z = -1;
for (int i = 1; i <= size; i++)
{
if ((i % 4 == 1) || (i % 4 == 3)) z += 2;
else if (i % 4 == 0) z *= 2;
std::cout << z << "\n";
}
return 0;
}
See the Output here: https://www.ideone.com/JiWB8W

. Read in real numbers until 10 positive values have been found. Write out the sum of the 10 positives

Here's the important part of my code:
int realnum, positive = 0, total, poscount;
for (poscount = 1; poscount < 11; poscount++)
{
cin >> realnum;
while (realnum > 0)
{
total = realnum + positive;
}
}
cout << "Total of 10 positive values is " << total << endl;
I really just don't see what's wrong here. After declaring my integers the program goes into my for, increase the poscount to 2, asks my to input realnum. I put in a positive number (ex: 6), which should in theory add my realnum with positive (which I declared 0) and give total the value (ex: 6 + 0 = 6). It should keep looping until poscount reaches 11 and output the total of 10 positive numbers.
When I run it, I put in 6 and the command prompt just shows 6, nothing happens, and I have to close through the x button. Can someone please tell me what the error is?
I would just use a while in the outer loop, to keep the number of so-far positive numbers.
Also, your total is uninitialised and you assign positive to it, which is just 0?
This is what I have in mind:
int realnum, total = 0, poscount = 0;
while (poscount < 10) {
cin >> realnum;
if (realnum > 0)
{
total += realnum;
poscount++;
}
}
cout << "Total of 10 positive values is " << total << endl;
Replace your while with an if since currently, once you enter that while loop you never exit it.
Also, why are you always increasing poscount? Shouldn't you only do that if realnum is positive? The iteration statement in the for loop is allowed to be blank; then you write poscount++ inside the new if block.
You also need to write total += to increment the total amount.
These things are easy to spot if you use your debugger.
Okay, so I think I've corrected myself (without blatantly copying blurry but also using Bathsheba's tip on replacing my while.
int realnum = 1, positive = 0, total, poscount;
if (realnum > 0)
{
for (poscount = 1; poscount < 11; poscount++)
{
cin >> realnum;
total = realnum + positive;
positive = total;
}
}
cout << "Total of 10 positive values is " << total << endl;
So far, it seems to work, there's probably a lot of unnecessary things that make it inefficient but I didn't want to copy examples. *Edit of course I still need to do with the ignoring negative part
I think I backed myself into the point of no return, ha. I really thought there was an alternate way I was going... Anyways, thanks for your replies, guys. I've always been lurking around here, until I made an account now.
Add a condition to terminate the while loop. And instead of adding positive to realnum, try adding poscount. That should provide the desired result.

Having garbage numbers while calculating percentage

So, I hate to ask, but, I'm having some issue with this, I'm new to C++ and I'm just starting out. Everything is done for the most part. Expect for a little thing.
Line 35-36 should be calculating the average (Which for some reason, I haven't been able to get it to work.)
Line 41-47 should print out the percentage that heads/tails was landed on with precision to one decimal, and then print out the correct numbers of * to represent the percentage.
But, when I run it, my heads/tail count is messed up. As well as my percentage numbers. I'm just looking for a push in the right direction.
#include <cstdlib>
#include <iostream>
#include <ctime>
#include <iomanip>
using std::cout; using std::cin; using std::endl;
using std::fixed; using std::setprecision;
int main()
{
srand(time(0));
int userInput,
toss,
headsCount,
tailsCount;
double headsPercent = 0,
tailsPercent = 0;
cout << "How many times do you want to toss the coin? ";
cin >> userInput;
while(userInput < 0)
{
cout << "Please enter a positive number: ";
cin >> userInput;
}
for(int i = 1; i < userInput; i++)
{
toss = rand() % 2;
if(toss == 0)
headsCount++;
else
tailsCount++;
}
headsPercent = userInput / headsCount * 100;
tailsPercent = userInput / tailsCount;
cout << "Heads: " << headsCount << endl
<< "Tails: " << tailsCount << endl << endl;
cout << "Heads Percentage: " << fixed << setprecision(1) << headsPercent << " ";
for(int b = 0; b < headsPercent; b++)
cout << "*";
cout << "\nTails Percentage: " << tailsPercent << " ";
for(int b = 0; b < tailsPercent; b++)
cout << "*";
return 0;
}
In addition to the uninitialized variables here, that others have pointed out, the calculations are all wrong.
Take out paper and pencil, and run some your own calculations the old-fashioned way.
Let's say there were five tosses, three heads, two tails. This means that (after fixing the uninitialized variables):
userInput=5
headsCount=3
tailsCount=2
Now, here's how you're calculating your supposed percentages:
headsPercent = userInput / headsCount * 100;
tailsPercent = userInput / tailsCount;
So, using your own numbers, you will get:
headsPercent = 5 / 3 * 100
tailsPercent = 5 / 2;
Does this look right to you? Of course not. You can do the arithmetic yourself. Divide 5 by 3 and multiply by 100. This is integer division, so five divided by three is 1, multiplied by 100 is 100. Five divided by two is two. So you get 100% and 2% here.
Of course, that's wrong. Two and three times, out of five, is 40% and 60%, respectively.
Writing a program means:
A) Figure out how calculations need to be made
B) Write the code to do the calculations.
You're still on step A. You need to figure out how you want to make these calculations so they're correct, first.
This has nothing really to do with C++. If you were using any other language, and coded this, in that manner, you'll get the same wrong answers.
The only thing this might have to do with C++ is that integer division, in C++ does not produce a fractional amount. It's integer division. But that's not your only problem.
Firstly u have to correct ur basics of mathematics.
Calculating %age means
example
(Marks obtained)/(Total marks)*100
Not (Total marks/marks obt)*100
Dividing any no by 0 is not defined. So if ur current code randomly assign toss or head =0, then obviously u will have errors.
Secondly talking about codes, U should either initialize i from 0 , or u should use
for (i=1; i<=userInput; i++)
As otherwise the head+toss value will be userInput-1.
Also remember to initialise variables like
Int headsCount=0;
etc. As the variable will take any random value if not initialised to a fixed no. (Though it does not creates a problem here)
And just change the datatype
int userInput,
toss,
headsCount,
tailsCount;
To
double userInput,
toss,
headsCount,
tailsCount;
This will solve your problem.
Advice: Please use
using namespace std;
in the starting of ur programs as u have to type a lot of std::
Welcome to C++. You need to initialise your variables. Your compiler should have warned you that you were using a variable without initialising it. When you don't initialise a value, your program has undefined behaviour.
I'm talking about headsCount and tailsCount. Something like this should be fine:
int headsCount = 0, tailsCount = 0;
Also note that your loop should start at 0, not 1, since you are using the < operator on the final condition.
Finally, your percentage calculations are backwards. It should be:
headsPercent = headsCount * 100 / userInput;
tailsPercent = tailsCount * 100 / userInput;
Now, there's a weird thing that might happen because you are using integer division. That is, your percentages might not add up to 100. What's happening here is integer truncation. Note that I dealt with some of this implicitly using the 100x scale first.
Or, since the percentages themselves are double, you can force the calculation to be double by casting one of the operands, thus avoiding integer truncation:
headsPercent = static_cast<double>(headsCount) / userInput * 100;
In fact, since the only two possibilities are heads and tails, you only need to count one of them. Then you can do:
tailsPercent = 100 - headsPercent;
1) This loop should start from 0:
for(int i = 1; i < userInput; i++)
2) The divisions are not correct:
//headsPercent = userInput / headsCount * 100;
//tailsPercent = userInput / tailsCount;
headsPercent = headsCount / userInput * 100;
tailsPercent = tailsCount / userInput * 100;
3) Finally:
cout << "\nTails Percentage: " << fixed << setprecision(1) << tailsPercent << " ";

How to write a program that "remembers" a previously guessed number?

I'm working on a question which is asking me to have a guessing game with the computer... with the computer being the guesser:
"Write a program that calculates a random number 1 through 100. The program then asks the user to guess the number.
If the user guesses too high or too low then the program should output "too high" or "too low" accordingly.
The program must let the user continue to guess until the user correctly guesses the number.★ Modify the program to output how many guesses it took the user to correctly guess the right number.★★ Modify the program so that instead of the user guessing a number the computer came up with, the computer guesses the number that the user has secretely decided. The user must tell the computer whether it guesed too high or too low."
So far I've did the first couple bits, but I'm stuck on the two-star part, where the program guesses the number.
This is my code below: (but as you'll be able to tell, it doesn't quite work as planned)
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
int compnumber;
string ok;
cout << "Think of a number between 1 and 100. Type 'ok' and I'll try and guess it." << endl;
cin >> ok;
cout << endl;
srand(time(NULL));
compnumber = rand() % 100 + 1;
cout << compnumber << endl;
cin >> ok;
while (ok != "correct")
{
if (ok == "high")
{
compnumber = rand() % compnumber + 1;
cout << compnumber << endl;
cin >> ok;
}
if (ok == "low")
{
compnumber = rand() % 100 + compnumber;
cout << compnumber << endl;
cin >> ok;
}
}
cout << "I won!" << endl;
}
I'm trying to figure out a way for the program to remember the number it previously guessed. I tried using the if (ok == "high") and if (ok == "low") to create what you'd call "boundaries" for the program "to remember". So if it was too high, it would remember the value it just guessed was too high, and would therefore guess lower than that, and vice versa with if it was too low.
But I'm struggling to get the program to remember both parts, e.g. if my secret number was 50, the computer guessed 80. I'd say it was too high, so it would go lower. If it then guessed 40, I'd say it was too low and it would go higher. But the program is then going HIGHER than it's original guess of 80, and sometimes even higher than 100 which I don't understand!
Any help would be appreciated. I have no idea if I'm going the right way with this, so any pointers would help! Thank you!
You need two extra variables - say int at_least = 1, at_most = 100; - as you get told "high" or "low", modify those to reflect the new knowledge of the range of possible answers. When you choose a new compnumber, keep it in that range by modding by the current size of the range and adding at_least.
You need two variables to store the high and low guesses so that the computer knows the range in which it should guess. Add this to your code:
int high = 101;
int low = 0;
Then when the computer guesses too high do this:
high = compnumber;
compnumber = ( rand() % (high-low - 1) ) + low;
And when too low, this:
low = compnumber;
compnumber = ( rand() % (high-low - 1) ) + low;
Hope that helps