Last active
April 29, 2017 18:03
-
-
Save hirad/80a87e9fe5ff8a021c91 to your computer and use it in GitHub Desktop.
A Simple RPN Calculator in Swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.characters.split { $0 == " " }.map { String($0) }.reduce(Stack<Double>(), combine: combineFunction).pop().0! | |
} | |
func combineFunction(stk: Stack<Double>, str: String) -> Stack<Double> { | |
var result: Stack<Double> | |
switch(str) { | |
case "+": | |
result = applyBinaryOp(stk, +) | |
case "-": | |
result = applyBinaryOp(stk, -) | |
case "*": | |
result = applyBinaryOp(stk, *) | |
default: | |
result = stk.push(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(op(v1!, v2!)) | |
} | |
let expression = "10 3 2 - +"; | |
solveRPN(expression) // output: 11 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello, mate.
Thank you for the gist.
I've updated it to Swift 3.1
Maybe you want to update yours too.
If that's the case - you are welcome:
https://gist.github.com/8ofproject/0103068289d9f034e62ebaf4e97672cc