Skip to content

Instantly share code, notes, and snippets.

@jpavley
Created October 4, 2015 01:48
Show Gist options
  • Save jpavley/1781556f16ca9152f546 to your computer and use it in GitHub Desktop.
Save jpavley/1781556f16ca9152f546 to your computer and use it in GitHub Desktop.
CS193P Professor Paul Hegarty iTuneU course
//: Playground - noun: a place where people can play
import UIKit
import Foundation
class CalculatorBrain {
enum Op: CustomStringConvertible {
case Operand(Double)
case BinaryOperation(String, (Double, Double) -> Double)
var description: String {
get {
switch self {
case .Operand(let operand):
return "\(operand)"
case .BinaryOperation(let symbol, _):
return symbol
}
}
}
}
var opStack = [Op]()
var knownOps = [String:Op]()
init() {
func learnOp (op: Op) {
knownOps[op.description] = op
}
learnOp(Op.BinaryOperation("*", *))
learnOp(Op.BinaryOperation("+", +))
learnOp(Op.BinaryOperation("-", {$1 - $0}))
learnOp(Op.BinaryOperation("/", {$1 / $0}))
}
func evaluate() -> Double? {
let (result, _) = evaluate(opStack)
return result
}
func evaluate(ops: [Op]) -> (result: Double?, remainingOps: [Op]) {
if !ops.isEmpty {
var remainingOps = ops
let op = remainingOps.removeLast()
switch op {
case .Operand(let operand):
return (operand, remainingOps)
case .BinaryOperation(_, let operation):
let op1Evaluation = evaluate(remainingOps)
if let operand1 = op1Evaluation.result {
let op2Evaluation = evaluate(op1Evaluation.remainingOps)
if let operand2 = op2Evaluation.result {
return (operation(operand1, operand2), op2Evaluation.remainingOps)
}
}
}
}
return (nil, ops)
}
func pushOperand(operand: Double) -> Double? {
opStack.append(Op.Operand(operand))
return evaluate()
}
func popOperand() -> Double? {
if !opStack.isEmpty {
opStack.removeLast()
}
return evaluate()
}
func performOperation(symbol: String) -> Double? {
if let operation = knownOps[symbol] {
opStack.append(operation);
}
return evaluate()
}
func showStack() -> String? {
return opStack.map{ "\($0)" }.joinWithSeparator(" ")
}
}
var cb = CalculatorBrain()
print(cb.knownOps)
cb.showStack()
cb.pushOperand(1)
cb.pushOperand(2)
cb.performOperation("+")
cb.pushOperand(3)
cb.pushOperand(4)
cb.performOperation("/")
cb.pushOperand(5)
cb.pushOperand(6)
cb.performOperation("*")
cb.pushOperand(7)
cb.pushOperand(8)
cb.performOperation("-")
cb.showStack()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment