Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Scala Coding Dojo files
object RomanConvert {
val arabic = List(
"I" -> 1,
"IV" -> 4,
"V" -> 5,
"IX" -> 9,
"X" -> 10,
"XL" -> 40,
"L" -> 50,
"XC" -> 90,
"C" -> 100,
"CD" -> 400,
"D" -> 500,
"CM" -> 900,
"M" -> 1000
)
val roman = arabic.map {
_.swap
}
// Values
// 1 -> I
// 5 -> V
// 10 -> X
// 50 -> L
// 100 -> C
// 500 -> D
// 1000 -> M
def toArabic(roman: String): Int = {
def reduce(acc:Int, number:String, numerals:List[(String, Int)]):Int = {
if(number.isEmpty) {
acc
} else {
if(number.startsWith(numerals.head._1)){
reduce( acc+ numerals.head._2, number.replaceFirst(numerals.head._1, ""), numerals)
} else {
reduce(acc, number, numerals.tail)
}
}
}
reduce(0, roman, arabic.reverse)
}
def toRoman(number: Int): String = {
def reduce(acc:String, number:Int, numerals:List[(String, Int)]):String = {
if(number == 0 || numerals.isEmpty) {
acc
} else {
val count = number/ numerals.head._2
if(count > 0) {
reduce(acc + (numerals.head._1 * count), number - numerals.head._2 * count, numerals.tail)
} else {
reduce(acc, number, numerals.tail)
}
}
}
reduce("", number, arabic.reverse)
}
}
import org.scalatest.{Matchers, FunSpec}
class RomanTest extends FunSpec with Matchers {
val testCases = Map(
"III" -> 3,
"II" -> 2,
"VIII" -> 8,
"XXXI" -> 31,
"XXIX" -> 29,
"XXXVIII" -> 38,
"CCXCI" -> 291,
"MCMXCIX" -> 1999
)
describe("Converting arabic numerals to roman numerals") {
describe("Defining the range of our problem") {
it("converts the smallest: 1") {
RomanConvert.toRoman(1) should equal("I")
}
it("converts the largest: 3999") {
RomanConvert.toRoman(3999) should equal("MMMCMXCIX")
}
}
it("converts 2 to II") {
RomanConvert.toRoman(2) should equal("II")
}
it("converts 4 to IV") {
RomanConvert.toRoman(4) should equal("IV")
}
describe("Defining a few test cases") {
testCases.map(_.swap).foreach { case (arabic: Int, roman: String) =>
it(s"converts $arabic to $roman") {
RomanConvert.toRoman(arabic) should equal(roman)
}
}
}
}
describe("Converting roman numerals to arabic numerals") {
describe("Defining the range of our problem") {
it("converts the smallest: I") {
RomanConvert.toArabic("I") should equal(1)
}
it("converts the largest: MMMCMXCIX") {
RomanConvert.toArabic("MMMCMXCIX") should equal(3999)
}
}
describe("Converting single roman numerals to arabic") {
List(("I", 1), ("V", 5), ("X", 10), ("L", 50), ("C", 100), ("D", 500), ("M", 1000)).foreach { case (roman, arabic) =>
it(s"converts $roman to $arabic") {
RomanConvert.toArabic(roman) should equal(arabic)
}
}
}
describe("defining a few test cases") {
testCases.foreach { case (roman: String, arabic: Int) =>
it(s"converts $roman to $arabic") {
RomanConvert.toArabic(roman) should equal(arabic)
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment