I was just browsing the IT forum on discuss.com.hk and came across a post on a university question on about writing a program to give change to for a vending machine (note it is in Chinese). Don't worry about he forum. Although there are a definitely a few good developers in there, the questions and discussion are generally of pretty low quality. I just browse occasionally hoping it will help me getting to know the IT industry in Hong Kong a little better.
I recall doing a similar problem in university for either an assignment or exam question, and I recall doing it the "Imperative way" with loops and states. It was an awful experience.
Now arm with thinking functionally, I took another crack at it and seems much easier.
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
object CoinMachine { | |
def changeWithBigCoin(accum: Change, changeOwing: Double, avaliableChange: Change): (Change, Double, Change) = { | |
if (changeOwing < 0) throw new Error("Cannot give change with existing coins") | |
else if (changeOwing == 0) return (accum, 0, avaliableChange) | |
else if (changeOwing >= 5 && avaliableChange.fiveDollarsLeft > 0) changeWithBigCoin(accum.changeFiveDollar(1), changeOwing - 5, avaliableChange.changeFiveDollar(-1)) | |
else if (changeOwing >= 2 && avaliableChange.twoDollarsLeft > 0) changeWithBigCoin(accum.changeTwoDollar(1), changeOwing - 2, avaliableChange.changeTwoDollar(-1)) | |
else if (changeOwing >= 1 && avaliableChange.dollarsLeft > 0) changeWithBigCoin(accum.changeDollar(1), changeOwing - 1, avaliableChange.changeDollar(-1)) | |
else if (changeOwing >= 0.5 && avaliableChange.fiftycentsLeft > 0) changeWithBigCoin(accum.changeFiftyCent(1), changeOwing - 0.5, avaliableChange.changeFiftyCent(-1)) | |
else throw new Error("Cannot give change on remainder: " + changeOwing) | |
} | |
def pay(paidAmount: Double, cost: Double, availableChange: Change): Change = { | |
val requiredChange: Double = paidAmount - cost | |
if (requiredChange < 0) throw new Error("Pay me more") | |
else if (requiredChange == 0) return new Change(0, 0, 0, 0) | |
else { | |
val result = changeWithBigCoin(new Change(0, 0, 0, 0), requiredChange, availableChange) | |
result._1 | |
} | |
} | |
pay(10, 7, new Change(2, 2, 0, 5)) | |
class Change(fiftycents: Int, dollars: Int, twoDollars: Int, fiveDollars: Int) { | |
def changeFiveDollar(amt: Int) = new Change(fiftycents, dollars, twoDollars, fiveDollars + amt) | |
def changeTwoDollar(amt: Int) = new Change(fiftycents, dollars, twoDollars + amt, fiveDollars) | |
def changeDollar(amt: Int) = new Change(fiftycents, dollars + amt, twoDollars, fiveDollars) | |
def changeFiftyCent(amt: Int) = new Change(fiftycents + amt, dollars, twoDollars, fiveDollars) | |
override def toString() = "(" + fiftycents + ", " + dollars + ", " + twoDollars + ", " + fiveDollars + ")" | |
def fiftycentsLeft = fiftycents; | |
def dollarsLeft = dollars; | |
def twoDollarsLeft = twoDollars; | |
def fiveDollarsLeft = fiveDollars | |
} | |
} |
No comments:
Post a Comment