B/C - Interpreter
- Category: behavioral
- Type: class
- Motivation: build an interpreter to solve the problem by Interpreting those sentences in a simple language
do {
let client = RomanNumeral()
let result: Int = client.convert("XIV");
print(result) // 14
}
// client
public struct RomanNumeral
{
public func convert(_ numeral: String) -> Int
{
parse(numeral)
.map { $0.interpret() }
.reduce(0) { $0 + $1 }
}
private func parse(_ numeral: String) -> [Expression]
{
var exps: [Expression] = []
var terms: [TermExpression] = numeral.map{ TermExpression(symbol: $0) }
while !terms.isEmpty {
let expression = terms.removeFirst()
let shouldShift = terms.count == 1 ||
(terms.count > 1 && terms[0].interpret() > terms[1].interpret())
if shouldShift {
let cal = CalExpression(lhs: expression, rhs: terms.removeFirst())
exps.append(cal)
} else {
exps.append(expression)
}
}
return exps
}
}
protocol Expression
{
func interpret() -> Int
}
struct TermExpression: Expression
{
let symbol: Character
func interpret() -> Int {
switch symbol {
case "I": return 1
case "V": return 5
case "X": return 10
case "L": return 50
case "C": return 100
case "D": return 500
case "M": return 1_000
default:return 0
}
}
}
struct CalExpression: Expression
{
let lhs: Expression
let rhs: Expression
func interpret() -> Int {
if lhs.interpret() < rhs.interpret() {
return rhs.interpret() - lhs.interpret()
} else {
return rhs.interpret() + lhs.interpret()
}
}
}