Create random valid expressions
- polym
-
polym
- Member since: Oct. 2, 2007
- Offline.
-
- Forum Stats
- Member
- Level 14
- Audiophile
This is a pretty simple program. All it does is create expressions like (12 + 18). They can be nested, which is the beauty of it. Right now, it doesn't actually compute itself, but it can easily be adjusted to do so. I just haven't gotten around the problem of recursive computation because the Expr object can take a string in its constructor. You can easily dissect the string into an Expr object, but I haven't had much success so far.
Here's the code:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <random>
using namespace std;
class Value
{
public:
int _val;
Value() { }
Value(int val) : _val(val) { }
operator string() const
{
return to_string(_val);
}
};
class Oper
{
public:
char _op;
Oper() { }
Oper(char op) : _op(op) { }
operator string() const
{
return string(1, _op);
}
};
class Expr
{
public:
Value _left;
Value _right;
Oper _op;
string _leftexpr;
string _rightexpr;
int type;
Expr() { }
Expr(Value left, Oper op, Value right)
: _left(left), _op(op), _right(right) { type = 0; }
Expr(string left, Oper op, Value right)
: _leftexpr(left), _op(op), _right(right) { type = 1; }
Expr(Value left, Oper op, string right)
: _left(left), _op(op), _rightexpr(right) { type = 2; }
Expr(string left, Oper op, string right)
: _leftexpr(left), _op(op), _rightexpr(right) { type = 3; }
operator string() const
{
if (!type)
return string("(") + (string)_left + string(" ") + (string)_op + string(" ") + (string)_right + string(")");
else if (type == 1)
return string("(") + _leftexpr + string(" ") + (string)_op + string(" ") + (string)_right + string(")");
else if (type == 2)
return string("(") + (string)_left + string(" ") + (string)_op + string(" ") + _rightexpr + string(")");
else if (type == 3)
return string("(") + _leftexpr + string(" ") + (string)_op + string(" ") + _rightexpr + string(")");
}
};
int main()
{
random_device rd;
char ops[] = {
'+', '-', '*', '/', '%', '^'
};
auto gen_rand_expr = [&] ()
{
Expr expr;
int dice = 0 + (rd() % ((4 - 0) + 1));
int num1 = 1 + (rd() % ((100 - 1) + 1));
int num2 = 1 + (rd() % ((100 - 1) + 1));
int op_dice = 0 + (rd() % ((5 - 0) + 1));
expr = Expr(Value(num1), Oper(ops[op_dice]), Value(num2));
return expr;
};
const int depth = 2;
for (int k = 0; k < 10; k++) {
int op_dice = 0 + (rd() % ((5 - 0) + 1));
int dice = 0 + (rd() % ((4 - 0) + 1));
Expr expr = Expr((string)gen_rand_expr(), Oper(ops[op_dice]), (string)gen_rand_expr());
for (int i = 0; i < 1 + (rd() % ((depth - 1) + 1)); i++)
{
op_dice = 0 + (rd() % ((5 - 0) + 1));
dice = 0 + (rd() % ((4 - 0) + 1));
if (dice == 0)
expr = Expr((string)expr, Oper(ops[op_dice]), (string)gen_rand_expr());
else if (dice == 1)
expr = Expr((string)gen_rand_expr(), Oper(ops[op_dice]), (string)expr);
else if (dice == 2)
expr = Expr((string)expr, Oper(ops[op_dice]), (string)expr);
else if (dice == 3)
expr = gen_rand_expr();
}
cout << (string)expr << endl;
}
return 0;
}
And example output:
(((54 ^ 49) % (57 / 92)) * (49 ^ 19))
((((8 * 83) - (37 ^ 4)) ^ ((8 * 83) - (37 ^ 4))) * (83 / 83))
(((42 * 18) / (78 / 49)) / ((42 * 18) / (78 / 49)))
((63 * 64) - (69 + 76))
((17 ^ 45) * (17 ^ 45))
(12 / 18)
(((39 - 29) ^ (96 / 69)) % ((39 - 29) ^ (96 / 69)))
((31 ^ 3) - (48 - 85))
((76 - 82) ^ (64 + 33))
((74 % 100) / (((70 + 42) - (6 - 19)) / (24 / 60))) - PMMurphy
-
PMMurphy
- Member since: May. 27, 2012
- Offline.
-
- Forum Stats
- Member
- Level 01
- Artist
ahahahahahahahhhh
refactor that code and switch those if-elses to switches.
I think it would be so much more readable.
Do you plan on taking this a step further and adding pattern recognition and reasoning?
Like, (enter in a math equation). Then it evaluates the math equation by generating potential solutions and such.
Looks like fun though. But do you really need this many classes to get the job done?
Your just making mathematical expressions with appropriate values in a random order right?
Evolutionary Computation tutorials
Evolutionary Algorith and Genetic Algorithm Basic Concept
- polym
-
polym
- Member since: Oct. 2, 2007
- Offline.
-
- Forum Stats
- Member
- Level 14
- Audiophile
At 4/1/13 11:24 PM, PMMurphy wrote: ahahahahahahahhhh
refactor that code and switch those if-elses to switches.
I think it would be so much more readable.
Do you plan on taking this a step further and adding pattern recognition and reasoning?
Like, (enter in a math equation). Then it evaluates the math equation by generating potential solutions and such.
Looks like fun though. But do you really need this many classes to get the job done?
Your just making mathematical expressions with appropriate values in a random order right?
If I was -solving- equations, the code would be much different. This just generates them, and so it's much different.
- PMMurphy
-
PMMurphy
- Member since: May. 27, 2012
- Offline.
-
- Forum Stats
- Member
- Level 01
- Artist
or you can take my post seriously instead of just having a conversation.
But yea bro do as you want!
I just think this could be done in a much easier way.
Evolutionary Computation tutorials
Evolutionary Algorith and Genetic Algorithm Basic Concept
- sharpnova
-
sharpnova
- Member since: Feb. 19, 2005
- Offline.
-
- Forum Stats
- Member
- Level 09
- Blank Slate
For the most part, it seems that PMMurphy can be ignored. He's fairly childish and doesn't seem to know much.
On a more constructive note, if you end up wanting to write code to evaluate arbitrary (but valid) expressions, you'll want to check out these concepts:
infix notation
prefix notation (also known as polish notation)
postfix notation
and the associated algorithms for converting between them, which though rarely known, fall into a category of algorithms and data structures which I feel all good programmers should know. At least those with an inkling of intellectual curiosity.
The shunting yard algorithm comes to mind. Evaluating postfix and prefix is trivial. Evaluating infix usually requires conversion to a polish/reverse-polish notation first.
It may seem arbitrary, but for example, let's say you want to state an expression verbally. In high school they might have taught you to say (a+b)^2 as "a plus b quantity squared" <- this always embarrassed the hell out of me as it actually removed no ambiguities.
I came up with my own way of stating expressions which annoyed my teachers to no end (an extra perk) like so: "the square of the sum of a and b" This way is effectively unambiguous as long as a binary structure is assumed. And later on when I started learning about algorithms, found out that this was known as polish notation.
= + ^ e * i pi 1 0
- PMMurphy
-
PMMurphy
- Member since: May. 27, 2012
- Offline.
-
- Forum Stats
- Member
- Level 01
- Artist
Yea it sucks not having edit buttons when ahahahahahahahahahahhahhhhh was meant to be.
AHHHHHHHHHHHHHHHHHHH
But yea. I'm childish bro.
Harrass me with inbox messages being condenscending criticizing my intelligence and judging me for my maturity.
Thats brillant at 30 when im 22.
Evolutionary Computation tutorials
Evolutionary Algorith and Genetic Algorithm Basic Concept
- Diki
-
Diki
- Member since: Jan. 31, 2004
- Online!
-
- Forum Stats
- Moderator
- Level 13
- Programmer
Okay guys this slap fight is really unnecessary; please stop.

