Skip to content

Instantly share code, notes, and snippets.

@cjwebb
Last active December 29, 2015 15:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cjwebb/7691864 to your computer and use it in GitHub Desktop.
Save cjwebb/7691864 to your computer and use it in GitHub Desktop.
Solutions to the classic roman numerals problem
class RomanNumerals {
def toInt(romanNumerals: String): Int = {
@annotation.tailrec
def recur(l: List[Int], total: Int): Int = {
l match {
case h :: Nil => total + h
case h :: tail if h < tail.head => recur(tail, total - h)
case h :: tail => recur(tail, total + h)
case Nil => total // romans didn't have zero though
}
}
val nums = romanNumerals map getCharValue
recur(nums.toList, 0)
}
def toIntFolding(r: String): Int = {
r.map(getCharValue(_))
.foldRight(List.empty[Int]) { case (a, b) => if (a >= b.headOption.getOrElse(0)) a :: b else -a :: b }
.reduce(_ + _)
}
def getCharValue(char: Char): Int = {
char match {
case 'I' => 1
case 'V' => 5
case 'X' => 10
case 'L' => 50
case 'C' => 100
case 'D' => 500
case 'M' => 1000
}
}
}
class RomanNumeralsTest extends FreeSpec with ShouldMatchers {
val r = new RomanNumerals()
val tests = List(
"I" -> 1,
"II" -> 2,
"III" -> 3,
"IV" -> 4,
"V" -> 5,
"IX" -> 9,
"X" -> 10,
"XV" -> 15,
"IL" -> 49,
"L" -> 50,
"C" -> 100,
"D" -> 500,
"M" -> 1000,
"LXXXIV" -> 84,
"MDCCC" -> 1800)
)
tests map { test =>
s"${test._1} equals ${test._2}" in {
r.toInt(test._1) should be (test._2)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment