0

I have array of equations:

let tasks = ["11 + 14 = 25", "2 + 2 = 5"]

and the function

func checkTask(task: String) throws -> String 

which should:

  1. If the equation is correct, then return "Ok", else return "Correct answer: .."
  2. If string isn't equation, throw error with description "It's not an equation"

The equation has two numbers to the left of the equal sign, one number to the right. Operations: addition and subtraction.

How I can do this?

AnderCover
  • 2,488
  • 3
  • 23
  • 42
Student
  • 13
  • 3
  • 2
    Please add some code which you have tried. – Raja Kishan May 11 '21 at 17:04
  • 4
    What you are asking is how you write a function that evaluates mathematical expressions. This is a big, complex task, and well beyond the scope of a SO post. If you were to limit it to expressions of the form "a + b = c" and a, b, and c are all integers, it would be pretty straightforward, but this is not a code writing service. You need to 1) define your problem more specificially, and 2) make an attempt at solving it yourself. – Duncan C May 11 '21 at 17:07
  • See https://stackoverflow.com/questions/26719180/swift-resolving-a-math-operation-in-a-string – Martin R May 11 '21 at 17:30
  • https://stackoverflow.com/a/16786016/1425697 seems to be more suitable – AnderCover May 12 '21 at 11:04

1 Answers1

1

This is a quick implementation: it handles expressions with 2 integer values and a single operator, where the operator is +, -, *, or /. The expressions look like <value> <operator> <value> = <value>. The values on the left-hand side of the expression are integers, but the value on the right-hand side can be a floating point value. (eg try? checkTask(task: "7 / 2 = 3.5") will print OK)

I think it can be a good starting point if you want to do something more advanced.

enum Error: Swift.Error {
    case malformed
}
func checkTask(task: String) throws -> String {
    let operations = "*/+-"
    let split = task.replacingOccurrences(of: " ", with: "").split(separator: "=")
    guard let resultString = split.last,
          let expressionString = split.first else {
        throw Error.malformed
    }
    let expression = expressionString.split { character in
        operations.contains(character)
    }
    
    guard let operationString = expressionString.first(where: { operation in operations.contains(operation) }),
          let lhsString = expression.first,
          let rhsString = expression.last,
          let equationResult = Double(String(resultString)),
          let lhs = Double(lhsString),
          let rhs = Double(rhsString) else {
        throw Error.malformed
    }
    
    var operation: (Double, Double) -> Double
    switch operationString {
    case "+":
        operation = (+)
    case "-":
        operation = (-)
    case "*":
        operation = (*)
    case "/":
        operation = (/)
    default:
        throw Error.malformed
    }
    let result = operation(lhs, rhs)
    guard result == equationResult else {
        return "Correct answer: \(result)"
    }
    return "OK"
}
let tasks = ["11 + 14 = 25", "2 + 2 = 5"]
let first = try? checkTask(task: tasks.first!) // "OK"
let second = try? checkTask(task: tasks.last!) // "Correct answer: 4.0"

If you want an error with a description you'll have to make the modifications yourself.

AnderCover
  • 2,488
  • 3
  • 23
  • 42
  • Nice lean implementation. You should describe what it does and does not handle (It looks like it handles expressions with 2 values and one operator, (`+`,`-`,`/` or `*`) But it would not handle `6 - 2 * 3 = 0` It doesn't handle parens, exponents, etc. – Duncan C May 11 '21 at 19:32
  • Yes you're right, it just handles the use cases described by OP. I will edit my answer! – AnderCover May 11 '21 at 19:45
  • 1
    It handles expressions with 2 integer values and a single operator, where the operator is `+`, `-`, `*`, or `/`. The expressions look like ` = `. The values on the left-hand side of the expression are integers, but the value on the right-hand side can be a floating point value. – Duncan C May 11 '21 at 20:03
  • Thank you Sir, allow me to copy/paste! – AnderCover May 11 '21 at 20:08