This is my solution to the Calculator kata from CodeWars: https://www.codewars.com/kata/5235c913397cbf2508000048/train/ruby
Create a simple calculator that given a string of operators (), +, -, *, / and numbers separated by spaces returns the value of that expression
// Example
Calculator.new.evaluate("2 / 2 + 3 * 4 - 6") # => 7
Remember about the order of operations! Multiplications and divisions have a higher priority and should be performed left-to-right. Additions and subtractions have a lower priority and should also be performed left-to-right.
function getOperation(operation) {
switch (operation) {
case '+':
return (a, b) => a + b
case '-':
return (a, b) => a - b
case '*':
return (a, b) => a * b
case '/':
return (a, b) => a / b
default:
break;
}
}
function operator(arr, symbol) {
const i = arr.lastIndexOf(symbol)
const operation = getOperation(symbol)
const leftHandNum = Number(arr[i + 1])
const rightHandNum = Number(arr[i - 1])
const result = operation(leftHandNum, rightHandNum)
arr.splice(i - 1, 3, result)
}
function worker(arr) {
const lastDivIndex = arr.lastIndexOf('/');
const lastMultIndex = arr.lastIndexOf('*');
const lastAddIndex = arr.lastIndexOf('+');
const lastSubIndex = arr.lastIndexOf('-');
if (
lastMultIndex === -1 &&
lastDivIndex === -1 &&
lastAddIndex === -1 &&
lastSubIndex === -1
) {
return Number(arr[0])
} else if (lastDivIndex > lastMultIndex) {
operator(arr, '/')
return worker(arr)
} else if (lastMultIndex > lastDivIndex) {
operator(arr, '*')
return worker(arr)
} else if (
lastMultIndex === -1 && lastDivIndex === -1
) {
if (lastAddIndex > lastSubIndex) {
operator(arr, '+')
return worker(arr)
} else if (lastAddIndex < lastSubIndex) {
operator(arr, '-')
return worker(arr)
}
}
}
const Calculator = function () {
this.evaluate = string => {
const reversedArr = string.split(' ').reverse()
return worker(reversedArr)
}
};