samedi 7 mai 2016

Generating random math expression, C++, multiple parenthesis

I wrote a simple function to generate a random math expression. This was my inspiration: http://ift.tt/1nymWOU.

Here are some example expressions I want to generate randomly:

4 + 2                           [easy]
3 * 6 - 7 + 2                   [medium]
6 * 2 + (5 - 3) * 3 - 8         [hard]
(3 + 4) + 7 * 2 - 1 - 9         [hard]
5 - 2 + 4 * (8 - (5 + 1)) + 9   [harder]
(8 - 1 + 3) * 6 - ((3 + 7) * 2) [harder]

For now on, I managed to implement easy, medium and hard ones. However, I still have problems with harder expressions. I want it to be the simplest possible, so I do want to use neither trees nor regular expressions. Any ideas how to modify my code to get it work?

#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <cstdlib>
using namespace std;


bool is_operator(char op)
{
    if(op == '-' || op == '+' || op == '/' || op == '*' || op == '(' || op == ')')
        return true;
    else
        return false;
}

bool is_math_operator(char op)
{
    if(op == '-' || op == '+' || op == '/' || op == '*')
        return true;
    else
        return false;
}

char rand_math_operator()
{
    std::vector<char> math_op;
    math_op.push_back('+');
    math_op.push_back('-');
    math_op.push_back('/');
    math_op.push_back('*');
    int index = 0 + rand() % (math_op.size());
    return math_op[index];
}

char rand_operator()
{
    std::vector<char> operators;
    operators.push_back('+');
    operators.push_back('-');
    operators.push_back('*');
    operators.push_back('/');
    operators.push_back('(');
    operators.push_back(')');
    int index = 0 + rand() % (operators.size());
    return operators[index];
}

std::string rand_values()
{
    std::vector<std::string> values;
    values.push_back("x");
    values.push_back("y");
    values.push_back("z");
    int index = 0 + rand() % (values.size());
    return values[index];
}

std::string expression_generator(int length)
{
    bool was_bracket = false;
    int i = 0;

    std::string expression = "";

    while(i < length)
    {
        std::string value = rand_values();
        char op = rand_operator();

        expression += value;
        i++;

        if(op == '(')
        {
            if(!was_bracket)
            {
                if(!is_math_operator(expression[i-1]))
                {
                    was_bracket = true;
                    expression += rand_math_operator();
                    expression += op;
                    i += 2;
                }
            }
        }
        else if(op == ')')
        {
            if(was_bracket)
            {
                if(!is_math_operator(expression[i-1]))
                {
                    was_bracket = false;
                    expression += op;
                    expression += rand_math_operator();
                    i += 2;
                }
            }
        }
        else
        {
            expression += op;
            i++;
        }
    }

    if(expression[expression.length()-1] == '(')
    {
        if (expression.size () > 0)  expression = expression.substr(0, expression.size()-1);
        was_bracket = false;
    }

    if(is_math_operator(expression[expression.length()-1]))
        if (expression.size () > 0)  expression = expression.substr(0, expression.size()-1);

    if(was_bracket)
        expression += ")";


    return expression;
}
int main(int argc, char **argv)
{
    srand(time(NULL));
    std::string expression = "";
    expression = expression_generator(20);
    std::cout << expression << "\n";

    return 0;
}




Aucun commentaire:

Enregistrer un commentaire