0

I want to create a random generator of math operations. I'm trying with ASCII codes but what happens is that it just concatenate the operands and operators as a String. Anyone has a suggestion for this?

let a = Math.floor(Math.random()*100)
let b =  Math.floor(Math.random()*100)
let ascCode = Math.floor(Math.random()* (46 - 42)) + 42
let op = String.fromCharCode(ascCode)
let c = a + `${op}` + b;
 
console.log(c)
Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
Gabriel Silva
  • 69
  • 1
  • 9

6 Answers6

3

You can use eval:

The eval() function evaluates JavaScript code represented as a string.

let a = 1
let b = 2
let ascCode = Math.floor(Math.random()* (46 - 42)) + 42
let op = String.fromCharCode(ascCode)
let c = eval(a + `${op}` + b);

console.log(c)

But eval can be troublesome.

eval() is a dangerous function, which executes the code it's passed with the privileges of the caller. If you run eval() with a string that could be affected by a malicious party, you may end up running malicious code on the user's machine with the permissions of your webpage / extension. More importantly, a third-party code can see the scope in which eval() was invoked, which can lead to possible attacks in ways to which the similar Function is not susceptible.

eval() is also slower than the alternatives, since it has to invoke the JS interpreter, while many other constructs are optimized by modern JS engines.

msdn

Another solution would be to use some if:

let a = 1
let b = 2
let ascCode = Math.floor(Math.random()* (46 - 42)) + 42
let op = String.fromCharCode(ascCode)

let c = 0;
if (op == "*")
c = a + b;
if (op == "+")
c = a + b;
if (op == "-")
c = a - b;

/*etc*/ 

console.log(c)

or even a map where keys are operators and values are functions:

let a = 1
let b = 2
let ascCode = Math.floor(Math.random()* (46 - 42)) + 42
let op = String.fromCharCode(ascCode)

let operators = {
'+': (a, b) => a + b,
'-': (a, b) => a - b,
'*': (a, b) => a * b,
'/': (a, b) => a / b, // handle zero!
'%': (a, b) => a % b // handle zero!
};

console.log(operators[op](a,b))
Community
  • 1
  • 1
aloisdg
  • 22,270
  • 6
  • 85
  • 105
1

What you could use (though this is definitely not a good practice), is eval(), which evaluates a string as javascript code.

(Another word of warning, eval is evil and shouldn't be used in production)

let a = Math.floor(Math.random()*100)
let b =  Math.floor(Math.random()*100)
let ascCode = Math.floor(Math.random()* (46 - 42)) + 42
let op = String.fromCharCode(ascCode)
let c = eval(a + `${op}` + b);
 
console.log(c)
Ahmed Bajra
  • 391
  • 1
  • 2
  • 14
1

This solution is similar to things discussed in the comments. It is a different, non-eval way of generating random math operations:

const ops = {
  '+': (a, b) => a + b,
  '-': (a, b) => a - b,
  '*': (a, b) => a * b,
  '/': (a, b) => a / b,
  '%': (a, b) => a % b,
  '>': (a, b) => a > b,
  '<': (a, b) => a < b,
  // etc
}

const randomOperation = ((ops) => {
  const keys = Object.keys(ops)
  const randomOpKey = () => keys[Math.floor(Math.random() * keys.length)]
  const evalOp = (key, a, b) => ops[key](a, b)
  
  return () => {
    const op = randomOpKey()
    const a = Math.floor(Math.random() * 100)
    const b = Math.floor(Math.random() * 100)
    return {
      expression: `${a} ${op} ${b}`,
      result: evalOp(op, a, b)
    }
  }
})(ops)


// demo

for (let i = 0; i < 20; i++) {
  let {expression, result} = randomOperation()
  console.log(`${expression} = ${result}`)
}

Note that what randomOperation returns is objects with two properties: expression as a string, and result as a value, which will be numeric or boolean. The demo code shows one way to use it. You have to manually maintain the list of operations, which is different than with the eval solutions.

I don't know what better suits your needs, but this should show that there are reasonable non-eval solutions possible.

Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
0

You should use built-in function eval()

let operators = ['+','-','*','/','%'];
    let number1 = 5;
    let number2 = 4;
    function getRandomOperation(){
     let randOpeator = operators[Math.floor(Math.random() * operators.length)];
     return eval(`${number1} ${randOpeator} ${number2}`);
    }
console.log(getRandomOperation());
Maheer Ali
  • 35,834
  • 5
  • 42
  • 73
0

You should evalute expression, using javascript eval function. It expects string as input.

const result = eval(c);

console.log(result);

Reference

Vejsil Hrustić
  • 179
  • 1
  • 7
-1

I presume it happens because you are using concatenation when one from concatenated values is a string:

let op = String.fromCharCode(ascCode)

To obtain a number under variable c you have to make sure that ${op} is number as well.

Sergey Ch
  • 91
  • 1
  • 5