Skip to content

Instantly share code, notes, and snippets.

@8of
Forked from hirad/RPNSolver
Last active April 29, 2017 18:01
Show Gist options
  • Save 8of/0103068289d9f034e62ebaf4e97672cc to your computer and use it in GitHub Desktop.
Save 8of/0103068289d9f034e62ebaf4e97672cc to your computer and use it in GitHub Desktop.
A Simple RPN Calculator in Swift
struct Stack<T> {
let values: [T]
init(_ v: [T] = [T]()) {
self.values = v
}
func push(elem: T) -> Stack<T> {
let newValues = [elem] + self.values
return Stack<T>(newValues)
}
func pop() -> (T?, Stack<T>) {
if self.values.isEmpty {
return (nil, self)
}
let first = self.values.first
let cnt = self.values.count
let newValues = self.values[1..<cnt]
return (first, Stack<T>(Array(newValues)))
}
}
typealias BinaryOp = (Double, Double) -> Double
func solveRPN(expr: String) -> Double {
return expr.components(separatedBy: " ").reduce(Stack<Double>(), combineFunction).pop().0!
}
func combineFunction(stk: Stack<Double>, str: String) -> Stack<Double> {
var result: Stack<Double>
switch(str) {
case "+":
result = applyBinaryOp(s: stk, op: +)
case "-":
result = applyBinaryOp(s: stk, op: -)
case "*":
result = applyBinaryOp(s: stk, op: *)
default:
result = stk.push(elem: Double(str)!)
}
return result
}
func applyBinaryOp(s: Stack<Double>, op: BinaryOp) -> Stack<Double> {
let (v1, s1) = s.pop()
let (v2, s2) = s1.pop()
return s2.push(elem: op(v1!, v2!))
}
let expression = "10 3 2 - +";
solveRPN(expr: expression) // should print 9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment