Swift Code Kata: Roman Numerals
Create the first 100 roman numerals and turn them back into integers
import Foundation
extension Int {
func times(_ text: String) -> String {
(0..<self).reduce(""){ e, _ in e + text }
}
}
let digits = [
("I", "V", "X"),
("X", "L", "C"),
("C", "D", "M")
]
var exchangeRules: ((l:String, m:String, h:String)) -> [(Int, String, String)] = { r in
[
(10, r.l, r.h),
( 9, r.l, r.l+r.h),
( 5, r.l, r.m),
( 4, r.l, r.l+r.m)
]
}
func roman(for n:Int, digits: [(String, String, String)] = digits) -> String {
digits
.reduce(n.times("I")) {
exchangeRules($1)
.reduce($0) {
$0.replacingOccurrences(of: $1.0.times($1.1), with: $1.2)
}
}
}
func from(roman: String, digits: [(String, String, String)] = digits) -> Int {
digits
.reversed()
.reduce (roman) {
exchangeRules($1)
.reversed()
.reduce($0) {
$0.replacingOccurrences(of: $1.2, with: $1.0.times($1.1))
}
}.count
}
// --- Run ---
let romans = (1...100).map { roman(for: $0) }
let ints = romans.map { from(roman: $0) }
(zip(ints, romans)).forEach { x in
print(x)
}
Discussion
Please feel free to discuss this article.