File tree Expand file tree Collapse file tree 2 files changed +119
-0
lines changed
scala-core-modules/scala-core-numbers/src
main/scala/com/baeldung/scala/romannumerals
test/scala/com/baeldung/scala/romannumeral Expand file tree Collapse file tree 2 files changed +119
-0
lines changed Original file line number Diff line number Diff line change 1+ package com .baeldung .scala .romannumerals
2+
3+ import scala .annotation .tailrec
4+ import scala .math .BigDecimal .int2bigDecimal
5+
6+ object NumberToRomanNumeral {
7+
8+ private val numbersToRomans = List (
9+ (1000 , " M" ),
10+ (900 , " CM" ),
11+ (500 , " D" ),
12+ (400 , " CD" ),
13+ (100 , " C" ),
14+ (90 , " XC" ),
15+ (50 , " L" ),
16+ (40 , " XL" ),
17+ (10 , " X" ),
18+ (9 , " IX" ),
19+ (5 , " V" ),
20+ (4 , " IV" ),
21+ (1 , " I" )
22+ )
23+
24+ def usingRecursion (num : Int ): String = {
25+ numbersToRomans.find((n, _) => {
26+ num - n >= 0
27+ }) match
28+ case Some ((n, r)) => r + usingRecursion(num - n)
29+ case None => " "
30+ }
31+
32+ def usingTailRecursion (num : Int ): String = {
33+ @ tailrec
34+ def recursiveFn (remaining : Int , acc : String ): String = {
35+ numbersToRomans.find((n, _) => {
36+ remaining - n >= 0
37+ }) match
38+ case Some ((n, r)) => recursiveFn(remaining - n, acc + r)
39+ case None => acc
40+ }
41+ recursiveFn(num, " " )
42+ }
43+
44+ def usingFold (num : Int ): String = {
45+ numbersToRomans
46+ .foldLeft((num, " " ))((remainingAndAcc, numAndRoman) => {
47+ val (remaining, acc) = remainingAndAcc
48+ if (remaining == 0 ) remainingAndAcc
49+ else {
50+ val (n, r) = numAndRoman
51+
52+ (remaining % n, acc + r * (remaining / n))
53+ }
54+ })
55+ ._2
56+ }
57+
58+ }
Original file line number Diff line number Diff line change 1+ package com .baeldung .scala .romannumeral
2+
3+ import com .baeldung .scala .romannumerals .NumberToRomanNumeral
4+ import org .scalatest .matchers .should .Matchers
5+ import org .scalatest .prop .TableDrivenPropertyChecks
6+ import org .scalatest .wordspec .AnyWordSpec
7+
8+ class NumberToRomanNumeralUnitTest
9+ extends AnyWordSpec
10+ with Matchers
11+ with TableDrivenPropertyChecks {
12+ val testValuesWithResults = Table (
13+ (" Number" , " Roman" ),
14+ (0 , " " ),
15+ (1 , " I" ),
16+ (2 , " II" ),
17+ (4 , " IV" ),
18+ (5 , " V" ),
19+ (6 , " VI" ),
20+ (9 , " IX" ),
21+ (10 , " X" ),
22+ (11 , " XI" ),
23+ (14 , " XIV" ),
24+ (15 , " XV" ),
25+ (17 , " XVII" ),
26+ (19 , " XIX" ),
27+ (20 , " XX" ),
28+ (40 , " XL" ),
29+ (44 , " XLIV" ),
30+ (49 , " XLIX" ),
31+ (50 , " L" ),
32+ (90 , " XC" ),
33+ (100 , " C" ),
34+ (400 , " CD" ),
35+ (500 , " D" ),
36+ (900 , " CM" ),
37+ (1000 , " M" ),
38+ (1949 , " MCMXLIX" )
39+ )
40+
41+ " Correction roman numeral should be returned for number" should {
42+ " using usingRecursion" in {
43+ forAll(testValuesWithResults)((num, roman) => {
44+ NumberToRomanNumeral .usingRecursion(num) shouldBe roman
45+ })
46+ }
47+
48+ " using usingTailRecursion" in {
49+ forAll(testValuesWithResults)((num, roman) => {
50+ NumberToRomanNumeral .usingTailRecursion(num) shouldBe roman
51+ })
52+ }
53+
54+ " using usingFold" in {
55+ forAll(testValuesWithResults)((num, roman) => {
56+ NumberToRomanNumeral .usingFold(num) shouldBe roman
57+ })
58+ }
59+ }
60+
61+ }
You can’t perform that action at this time.
0 commit comments