Created
July 24, 2014 22:11
-
-
Save dkowis/b7d29b8d76319516cc44 to your computer and use it in GitHub Desktop.
Scala Coding Dojo files
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 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) | |
} | |
} |
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
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