Created
October 4, 2015 01:48
-
-
Save jpavley/1781556f16ca9152f546 to your computer and use it in GitHub Desktop.
CS193P Professor Paul Hegarty iTuneU course
This file contains 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
//: 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