The 24 Game tests one’s mental arithmetic.

Write a program that randomly chooses and displays four digits, each from one to nine, with repetitions allowed. The program should prompt for the player to enter an arithmetic expression using *just* those, and *all* of those four digits, used exactly *once* each. The program should *check* then evaluate the expression. The goal is for the player to enter an expression that evaluates to **24**.

- Only multiplication, division, addition, and subtraction operators/functions are allowed.
- Division should use floating point or rational arithmetic, etc, to preserve remainders.
- Brackets are allowed, if using an infix expression evaluator.
- Forming multiple digit numbers from the supplied digits is
*disallowed*. (So an answer of 12+12 when given 1, 2, 2, and 1 is wrong). - The order of the digits when given does not have to be preserved.

Note:

- The type of expression evaluator used is not mandated. An RPN evaluator is equally acceptable for example.
- The task is not for the program to generate the expression, or test whether an expression is even possible.

#include <random> #include <iostream> #include <stack> #include <set> #include <string> #include <functional> using namespace std; class RPNParse { public: stack<double> stk; multiset<int> digits; void op(function<double(double,double)> f) { if(stk.size() < 2) throw "Improperly written expression"; int b = stk.top(); stk.pop(); int a = stk.top(); stk.pop(); stk.push(f(a, b)); } void parse(char c) { if(c >= '0' && c <= '9') { stk.push(c - '0'); digits.insert(c - '0'); } else if(c == '+') op([](double a, double b) {return a+b;}); else if(c == '-') op([](double a, double b) {return a-b;}); else if(c == '*') op([](double a, double b) {return a*b;}); else if(c == '/') op([](double a, double b) {return a/b;}); } void parse(string s) { for(int i = 0; i < s.size(); ++i) parse(s[i]); } double getResult() { if(stk.size() != 1) throw "Improperly written expression"; return stk.top(); } }; int main() { random_device seed; mt19937 engine(seed()); uniform_int_distribution<> distribution(1, 9); auto rnd = bind(distribution, engine); multiset<int> digits; cout << "Make 24 with the digits: "; for(int i = 0; i < 4; ++i) { int n = rnd(); cout << " " << n; digits.insert(n); } cout << endl; RPNParse parser; try { string input; getline(cin, input); parser.parse(input); if(digits != parser.digits) cout << "Error: Not using the given digits" << endl; else { double r = parser.getResult(); cout << "Result: " << r << endl; if(r > 23.999 && r < 24.001) cout << "Good job!" << endl; else cout << "Try again." << endl; } } catch(char* e) { cout << "Error: " << e << endl; } return 0; }

- Output:

Enter an expression using the digits 8833 that evals to 24: (8/(3-(8/3))) nice! Enter an expression using the digits 8833 that evals to 24: (8/(3-(8/9))) Extra goodies in expression: 9 Enter an expression using the digits 8833 that evals to 24: (8/(3-(8/8))) You can only use the digits 8833 once each Enter an expression using the digits 7155 that evals to 24: 7+1+5+5 That evaled to 18, not 24 Enter an expression using the digits 8332 that evals to 24: 8*3*(3-2) nice!

Content is available under GNU Free Documentation License 1.2.