Skip to content

Instantly share code, notes, and snippets.

@rkie
Created March 6, 2023 13:53
Show Gist options
  • Save rkie/f48c8fd049a14483fe7eb235e2d55f09 to your computer and use it in GitHub Desktop.
Save rkie/f48c8fd049a14483fe7eb235e2d55f09 to your computer and use it in GitHub Desktop.
Examples from How to Start Test Driven Development on failedtofunction.com
package com.failedtofunction.examples.numerals
fun Char.romanNumeralValue(): Int =
when (this) {
'I' -> 1
'V' -> 5
'X' -> 10
'L' -> 50
'C' -> 100
'D' -> 500
'M' -> 1000
else -> throw Exception("'$this' is not a valid Roman Numeral character.")
}
fun String.fromRomanNumeral(): Int =
this
.toCharArray()
.reversed()
.map { it.romanNumeralValue() }
.fold(Pair(0, 0)) { state, item ->
val maxVal = kotlin.math.max(state.first, item)
val runningTotal = if (item >= state.first) {
state.second + item
} else {
state.second - item
}
Pair(maxVal, runningTotal)
}.second
fun String.addRomanNumeral(other: String): String {
val thisValue = this.fromRomanNumeral()
val otherValue = other.fromRomanNumeral()
val sum = thisValue + otherValue
return sum.toRomanNumeral()
}
fun Int.toRomanNumeral(): String {
val descendingMap = listOf(
"M" to 1000, "CM" to 900, "D" to 500, "CD" to 400,
"C" to 100, "XC" to 90, "L" to 50, "XL" to 40,
"X" to 10, "IX" to 9, "V" to 5, "IV" to 4, "I" to 1
).toMap()
var num = this
var result = ""
for ((numeral, value) in descendingMap.entries) {
while (num >= value) {
num -= value
result += numeral
}
}
return result
}
package com.failedtofunction.examples.numerals
import kotlin.test.Test
import kotlin.test.assertEquals
class RomanNumeralExtensionsTest {
@Test
fun `should convert a Roman Numeral to an integer`() {
val input = "IV"
val expected = 4
val result = input.fromRomanNumeral()
assertEquals(expected, result)
}
@Test
fun `should convert the year in Roman Numerals to an integer`() {
val input = "MMXXIII"
val expected = 2023
val result = input.fromRomanNumeral()
assertEquals(expected, result)
}
@Test
fun `should convert integers from 1 to 1000 to Roman Numerals and back`() {
for (i in 1..1000) {
val asRomanNumeral = i.toRomanNumeral()
val asInteger = asRomanNumeral.fromRomanNumeral()
assertEquals(i, asInteger, "Incorrect conversion of $i either to Roman Numeral $asRomanNumeral or back to $asInteger")
}
}
@Test
fun `should convert an Int to an Roman Numeral`() {
val input = 4
val expected = "IV"
val result = input.toRomanNumeral()
assertEquals(expected, result)
}
@Test
fun `should convert the year at time of writing to the correct Roman Numeral`() {
val input = 2023
val expected = "MMXXIII"
val result = input.toRomanNumeral()
assertEquals(expected, result)
}
@Test
fun `should add two Roman Numerals together showing the result as a Roman Numeral`() {
val four = "IV"
val eleven = "XI"
val expected = "XV"
val result = four.addRomanNumeral(eleven)
assertEquals(expected, result)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment