Skip to content

Instantly share code, notes, and snippets.

@hirad
Last active April 29, 2017 18:03
Show Gist options
  • Save hirad/80a87e9fe5ff8a021c91 to your computer and use it in GitHub Desktop.
Save hirad/80a87e9fe5ff8a021c91 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.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
@8of
Copy link

8of commented Apr 29, 2017

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment