Skip to content

Instantly share code, notes, and snippets.

@nkhil
Last active June 9, 2021 11:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nkhil/1320831be5eed175afa4c1c3f5494faf to your computer and use it in GitHub Desktop.
Save nkhil/1320831be5eed175afa4c1c3f5494faf to your computer and use it in GitHub Desktop.
Create a simple calculator that given a string of operators (), +, -, *, / and numbers separated by spaces returns the value of that expression

Calculator

This is my solution to the Calculator kata from CodeWars: https://www.codewars.com/kata/5235c913397cbf2508000048/train/ruby

Kata

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.

Solution

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)
  }
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment