Number guessing game - c++

I've been given a 'broken algorithm' to fix. It's for the game 'Guess a number between 1-100' Where the computer answers within 7 questions/iterations.
The brief i've been given suggests only minimal changes need to be made to the algorithm, sorry if that's vague, i'm thinking the same thing.
Anyway the algorithm was full of silly mistakes which i've cleaned up. For a test case of 33 the algorithm assigns the following medians
50,25,37,19 << 19 is obviously incorrect.
I'm aware the last_median = current median is not in the right place. It's been a long day and if anyone could shed any light onto this i'd be grateful.
const int MAX_VALUE = 100;
int current_median = MAX_VALUE /2;
int last_median = 0;
while (true)
{
last_median = current_median;
if(number >= current_median)
{
if(number == current_median)
{
//Check for equality
cout << endl << number << endl;
break;
}
current_median += last_median /2;
}
else if(number <= current_median)
{
if(number == current_median)
{
// Check for equality
cout<<endl<<number<<endl;
break;
}
current_median -= last_median /2;
}
}

Two hints:
You can move the equality comparison outside the two ifs.
You should keep track of the range that you know contains the number. Once you do that, the logic will be very straightforward.

The algorithm is basically doing a binary search. One problem you have is with your conditionals:
if(number >= current_median)
// ...
else if(number <= current_median)
// ...
If the number is equal, you want to exit the loop, not continue it:
if(number > current_median)
// ...
else if(number < current_median)
// ...
else // we are equal
{
break;
}
You should also adjust your conditionals to check for a (low, high) range as it should (quickly) get smaller as your median value approaches the real value.
A simple example:
#include <iostream>
int main()
{
std::cout << "Pick a number between [0, 100] (Don't tell me what it is!)";
unsigned int low = 0;
unsigned int high = 100;
do
{
unsigned int median = (low + high) / 2;
std::cout << "Is your number > " << median << "? ";
char answer;
std::cin >> answer;
if (answer == 'Y' || answer == 'y')
{
low = median;
continue;
}
else
{
std::cout << "Is your number < " << median << "? ";
std::cin >> answer;
if (answer == 'Y' || answer == 'y')
{
high = median;
continue;
}
else // we are equal
{
low = high = median;
}
}
} while (low != high);
std::cout << "Your number is " << low << std::endl;
return 0;
}

If you're looking for a number between 0 and 100 you're going to find it in 7 or less steps. If you want to be more precise, it's exactly 7 steps if you're looking for an odd number and it's going to be 6 or less in some cases if you're looking for an even number. I'll put below a simple code for this. I didn't put in all the checks (entering numbers not letters, or other stuff), it's just written in a couple of minutes:
#include <iostream>
int main(){
std::cout << "Think of a number between 1 and 100" << std::endl ;
std::cout << "Press 0 if my number is correct. 1 if YOUR number is smaller. 2 if bigger" << std::endl;
int response = 0;
int middle = 64;
int low = 0;
int high = 128;
int counter = 1;
while(response!=0)
{
std::cout << counter << " Guess " << counter << ": " << middle << std::endl;
std::cout <<"Press 0(bingo) 1(smaller) 2(greater): " ;
std::cin >> response ;
std::cout << std::endl ;
counter++;
switch (response){
case 0:
std::cout << "Your number is: " << middle << std::endl;
break;
case 1:
high = middle;
middle = (low+high)/2;
break;
case 2:
low = middle;
middle = (low+high)/2;
break;
} //end swhitch
}; //end while
return 0;
}

int main()
{
char uput = '?';
int maxx = 100;
int minn = 0;
while (minn != maxx)
{
cout << (minn+maxx)/2 << ": [h]igher, [l]ower or [e]qual?";
cin >> uput;
if (uput == 'l')
{
maxx = (minn+maxx)/2;
}
else if (uput == 'h')
{
minn = (minn+maxx)/2;
}
else if (uput == 'e')
{
cout << "Your number is " << (minn+maxx)/2 << ". Yay.";
return 0;
}
}
return 0;
}
If the number is lower than the median, the median is the new maximum.
If the number is higher than the median, the median is the new minimum.
Create a loop. For each time around the loop, find the median between the minn and the maxx. Since you are narrowing the gap between the numbers between the minimum and the maximum each time, you will eventually arrive with only 1 possibility remaining, and that's your number.
The code above isn't a great example but hopefully it helps illustrate.

Related

C++ assignment that requires a tricky while loop at the end

Is there some way to write a condition within a while loop that creates output if the user guesses a number that is within 10 units (plus or minus) from a random number generated by the program (integers)?
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
srand ( time(NULL) );
bool valid;
int randNum;
int sum = 0;
int userNum;
for (int x = 1; x < 11; x++)
{
randNum = rand() % (71) + 7;
cout << "Random number " << x << ": " << randNum << endl;
sum = sum + randNum;
}
cout << "\nThe total of all the random numbers is " << sum << "\n\n";
cout << "Guess a number between 70 and 770: ";
do
{
cin >> userNum;
while(userNum >= 70 && userNum <= 770)
{
while(userNum == sum)
{
cout << "You win";
break;
}
while(/* the number given by the user is within 10 units from the random number generated by the program*/)
{
cout << "You almost won";
break;
}
break;
}
while(userNum < 70 || userNum > 770)
{
cout << "Try again.";
valid = false;
break;
}
}
while (!valid);
return 0;
}
You will have to #include <stdlib.h> then for the condition in your while loop you write abs(userNum - randNum) <= 10. This will give the magnitude of the difference between the userNum and randNum, which you want to be less than or equal to 10.

How do I limit the amount of numbers I have in a row?

I'm attempting to list a set of prime numbers from a lower bound to an upper bound limiting the number of prime numbers in a row to 8. Though I have done the first part, I can't get them to list in rows with only 8 prime numbers per row.
#include <iostream>
enter code here
int main()
{
int low, high, i, flag, j;
cout << "Enter two numbers(intervals): ";
cin >> low >> high;
cout << "Prime numbers between " << low << " and " << high << " are: ";
while (low < high)
{
flag = 0;
for (i = 2, j = 1; i <=low/2; +ii, ++j)
{
if (j == 8)
{
cout << "\n";
j = j - 7;
}
else if (low % i == 0)
{
flag = 1;
break;
}
}
if (flag == 0)
cout << low << " ";
++low;
}
return 0;
}
It works for the first row, then everything else seems to start listing rather than being in a row.
Output: Enter two numbers(intervals): 1
200
Prime numbers between 1 and 200 are: 1 2 3 5 7 11 13 17
19
23
29
31 ...
It's a little late, but I said I'd do it. My suggestions:
#include <iostream>
//enter code here
using std::cin;
using std::cout;
int main()
{
int low, high, count, i;
bool flag; // bools are more suited to being flags
cout << "Enter two numbers(intervals): ";
cin >> low >> high;
cout << "Prime numbers between " << low << " and " << high << " are: ";
count = 1; // I replaced j with this for ease of reading
while (low < high)
{
flag = true;
// using break in loops is not recommended, and you already have a flag
for (i = 2; i <= low / 2 && flag; ++i)
{
if (low % i == 0)
{
flag = false;
}
}
if (flag)
{
cout << low;
if (count == 8)
{
cout << std::endl;
count = 1;
}
else
{
cout << " ";
++count;
}
}
++low;
}
return 0;
}
Your code divide not every 8 prime numbers, but every 8 attempts of dividing a number during search for prime number. So any prime that is 8 or more values away from previous will generate a line break. Consider following fix:
#include <iostream>
using namespace std;
int main()
{
int low, high, i, flag, j;
cout << "Enter two numbers(intervals): ";
cin >> low >> high;
cout << "Prime numbers between " << low << " and " << high << " are: ";
j = 0;
while (low < high)
{
flag = 0;
for (i = 2; i <=low/2; ++i)
{
// Removed here
if (low % i == 0)
{
flag = 1;
break;
}
}
if (flag == 0)
{
++j; // Added here
cout << low << " ";
}
if (j == 8) // and here
{
cout << "\n";
j = j - 8;
}
++low;
}
return 0;
}
By the way, you should end a search when reaching square root of low, not low / 2. The loop will be much faster.

Lowest Common Multiple Program

I tried making a program to find the lowest common multiple of any two numbers. I have gotten most of the way there but my program prints all of the common multiples from 1-1000000 instead of just the first one. How do I make it print only the first one
?
#include <iostream>
using namespace std;
int main() {
cout << "Find the lowest common multiple of two numbers, just enter them one after the other" << endl;
int firstNum;
int secondNum;
cin >> firstNum;
cin >> secondNum;
int i;
for (i = 1; i < 1000001; i++) {
if (i % firstNum == 0 && i % secondNum == 0) {
cout << "these two number's LCM is" << i << endl;
}
}
system("pause");
return 0;
}
You can add a break to end a loop. In your case, you want to add it at the end of your if statement:
for (i = 1; i < 1000001; i++) {
if (i % firstNum == 0 && i % secondNum == 0) {
cout << "these two number's LCM is" << i << endl;
break;
}
}
Your problem is a break statement as others have mentioned.
But a better solution: lcm is standardized in C++17! So you can just do:
cout << lcm(firstNum, secondNum) << endl;
If you don't have access to C++17 yet this is already available in the namespace experimental: http://en.cppreference.com/w/cpp/experimental/lcm
After finding the first one you need to leave from for loop, that is why it keeps printing other values.
for (i = 1; i < 1000001; i++) {
if (i % firstNum == 0 && i % secondNum == 0) {
cout << "these two number's LCM is" << i << endl;
break;
}
}

how to add probabilities to the game?

This program runs great, but like a true casino owner. I want the payout to be as minimal as possible without adding more possibilities. The way I want to do that is to add probabilities to each number. there 8 possibilities (2,3,4,5,6,7,8,9) I want 7 to occur the least. So I want to set probabilities as 2-6 at 75% (that's 15% each) 8-9 at 20% (that's 10% each) and 7 at 5%. Can someone help me?
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <ctime>
using namespace std;
int Random(int low, int high);
int Result(int a, int b, int c, int chips, int bet);
int main()
{
srand( time(0) );
int low1(2), low2(2), low3(2);
int high1(9), high2(9), high3(9);
int menu=0;
int bet =0;
bool quit=0;
cout << "Player's chips: $1000" << endl;
int chips=1000;
while (!quit)
{
cout << "1) Play slot. 2) Exit.";
cin >> menu;
switch (menu)
{
case 1:
{
cout << "Enter your bet: ";
cin >> bet;
if (bet<=0 || bet>chips)
{
cout << "You did not enter a valid bet." << endl;
menu=1;
}
else
{
int a = Random(low1,high1);
int b = Random(low2,high2);
int c = Random(low3,high3);
cout << a << " " << b << " " << c << endl;
chips = Result(a,b,c,chips,bet);
cout << "Player's chips: $" << Result(a,b,c,chips,bet) << endl;
}
break;
}
case 2:
{
cout << "Exiting..." << endl;
quit=1;
break;
}
default:
{
cout << "Not a valid menu !"<<endl;
}
}
}
if (chips <=0)
{
cout << "You have $0 ! Game Over !" << endl;
quit=1;
}
}
int Random(int low, int high)
{
int random;
random = low + rand() % ((high+1)-low);
return random;
}
int Result(int a, int b, int c, int chips, int bet)
{
if ((a==7 && b==7 && c==7))
{
cout << "You won 10 times your bet !($" << (bet*10) << ")" << endl;
chips=chips+(bet*10);
}
if ((a==b==c) && !(a==7 && b==7 && c==7))
{
cout << "You won 5 times your bet !($" << (bet*5) << ")" << endl;
chips=chips+(bet*5);
}
if ((a==b || a==c || b==c) && !(a==b==c) && !(a==7 && b==7 && c==7))
{
chips=chips+(bet*3);
cout << "You won 3 times your bet ! ($" << (bet*3) << ")" << endl;
}
else
{
cout << "You lost your bet ! ($-" << bet << ")" << endl;
chips=chips-bet;
}
return chips;
}
Introduce an array of values [0.05, 0.15, 0.25, 0.4, 0.55, 0.7, 0.85] corresponding to values 7, 8, 9, 2, 3, 4, 5. 6 is if a generated random number > 0.85.
Then get a random number r from 0 to 1.
if r <=0.05 then it is 7
else if r <= 0.15 then it is 8
else if r <= 0.1 then it is 9
...
else if r <= 0.85 then it is 5
else it is 6
You can figure out how to write it down as a loop if you want.
I would re-write the function as follows (it could be reworked into something better, but it is a start that should work):
// Generate a random number 2-9, with weighted probabilities
int Random()
{
int number; // number 1-9 to generate
int prob; // probability
// Generate probability value 0-99
prob = rand() % 100;
// Calculate number with desired probability "additive"
if (prob < 15) // 15% probability for 2
number = 2;
else if (prob < 30) // 15% probability for 3
number = 3;
else if (prob < 45) // 15% probability for 4
number = 4;
else if (prob < 60) // 15% probability for 5
number = 5;
else if (prob < 75) // 15% probability for 6
number = 6;
else if (prob < 80) // 5% probability for 7
number = 7;
else if (prob < 90) // 10% probability for 8
number = 8;
else // 10% probability for 9
number = 9;
return number;
}
Don't forget to add the following code to seed the random number generator:
srand (time(NULL));
I hope this isn't for a real slot machine by the way, there could be legal issues if it were :-)

C++ question on prime numbers

I am trying to make a program that determines if the number is prime or composite. I have gotten thus far. Could you give me any ideas so that it will work? All primes will , however, because composites have values that are both r>0 and r==0, they will always be classified as prime. How can I fix this?
int main()
{
int pNumber, limit, x, r;
limit = 2;
x = 2;
cout << "Please enter any positive integer: " ;
cin >> pNumber;
if (pNumber < 0)
{
cout << "Invalid. Negative Number. " << endl;
return 0;
}
else if (pNumber == 0)
{
cout << "Invalid. Zero has an infinite number of divisors, and therefore neither composite nor prime." << endl;
return 0;
}
else if (pNumber == 1)
{
cout << "Valid. However, one is neither prime nor composite" << endl;
return 0;
}
else
{
while (limit < pNumber)
{
r = pNumber % x;
x++;
limit++;
if (r > 0)
cout << "Your number is prime" << endl;
else
{
cout << "Your number is composite" << endl;
return 0;
}
}
}
return 0;
}
Check out http://en.wikipedia.org/wiki/Prime_number and http://en.wikipedia.org/wiki/Primality_test
The simplest primality test is as
follows: Given an input number n,
check whether any integer m from 2 to
n − 1 divides n. If n is divisible by
any m then n is composite, otherwise
it is prime.
#include <iostream>
#include <math.h>
// Checks primality of a given integer
bool IsPrime(int n)
{
if (n == 2) return true;
bool result = true;
int i = 2;
double sq = ceil(sqrt(double(n)));
for (; i <= sq; ++i)
{
if (n % i == 0)
result = false;
}
return result;
}
int main()
{
std::cout << "NUMBER" << "\t" << "PRIME" << std::endl;
for (unsigned int i = 2; i <= 20; ++i)
std::cout << i << "\t" << (IsPrime(i)?"YES":"NO") << std::endl;
std::cin.get();
return 0;
}
bool check_prime(unsigned val) {
if (val == 2)
return true;
// otherwise, if it's even, it's not prime.
if ((val & 1) == 0)
return false;
// it's not even -- only check for odd divisors.
for (int i=3; i*i<=val; i+=2)
if (val % i == 0)
return false;
return true;
}
with respect ur code u didn't check if i enter 2 what will be happened,
and also u didn't return any thing if it is prime....thats why it is always returning prime in spite the number is composite .
here is the code below =>
#include<iostream>
using namespace std;
int main(){
int pNumber, limit, x, r;
limit = 2;
x = 2;
cout << "Please enter any positive integer: " ;
cin >> pNumber;
if (pNumber < 0){
cout << "Invalid. Negative Number. " << endl;
return 0;
}
else if (pNumber == 0){
cout << "Invalid. Zero has an infinite number of divisors, and therefore neither composite nor prime." << endl;
return 0;
}
else if (pNumber == 1){
cout << "Valid. However, one is neither prime nor composite" << endl;
return 0;
}
else if (pNumber == 2){
cout << " Your number is prime" << endl;
return 0;
}
else{
while (limit < pNumber){
r = pNumber % x;
x++;
limit++;
if (r > 0){
cout << "Your number is prime" << endl;
return 0;
}
else{
cout << "Your number is composite" << endl;
return 0;
}
}
}
return 0;
}
For one thing, you'll want to break out of your loop when you find some x where pNumber % x == 0. All you need to do is find one factor of pNumber greater than 1 and less than pNumber to prove it's not prime -- no point in searching further. If you get all the way to x = pNumber without finding one, then you know pNumber is prime. Actually, even if you get to the square root of pNumber without finding one, it's prime, since if it has a factor greater than that, it should have a factor less than that. Make sense?
I don't know what you have been taught thus far, but my discrete mathematics teacher was a fan of the Miller-Rabin test. It is a pretty accurate test that is very easy to code, within a few base tests you have a very negligible chance that you have a Carmichael Number. If you haven't gotten that far in your studies I would just stick to some basic division rules for numbers.
Simplest method is for a given number n , if it is perfectly divisible with any number between 2 to sqrt(n), its a composite, or else its prime
Hi i have done this that also without using math.h header file....Have used turboc compiler.
Following program checks whether the number is prime or composite.
#include<iostream.h>
#include<conio.h>
class prime
{
int a;
public:
void check();
};
void prime::check()
{
cout<<"Insert a number";
cin>>a;
int count=0;
for(int i=a;i>=1;i--)
{
if(a%i==0)
{
count++;
}
}
if(count==1)
{
cout<<"\nOne is neither prime nor composite";
}
if(count>2)
{
cout<<"\nThe number is composite " ;
}
if(count==2)
{
cout<<"\nThe numner is prime";
}
}
void main()
{
clrscr();
prime k;
k.check();
getch();
}