Skip to content

Instantly share code, notes, and snippets.

@dschinkel
Last active May 17, 2019 06:16
Show Gist options
  • Save dschinkel/e83573b5b9a63bb8f7cd671d390c8835 to your computer and use it in GitHub Desktop.
Save dschinkel/e83573b5b9a63bb8f7cd671d390c8835 to your computer and use it in GitHub Desktop.
Attempt 4
package roman.numeral.calculator.kotlin
class Calculator {
private val toRoman = mapOf(
"IIIII" to "V",
"VV" to "X",
"XXXXX" to "L",
"LL" to "C",
"CCCCC" to "D",
"DD" to "M"
)
fun add(inputOne: String, inputTwo: String): String? {
val combined = "$inputOne$inputTwo"
val reversed = "$inputTwo$inputOne"
for((k,v) in toRoman){
if(foundMatch(k, combined))
return replaceWithRoman(combined, k, v)
}
if (isIllegalSubtraction(inputOne, inputTwo)) return "$inputTwo$inputOne"
if(containsDups(inputOne) && !notAllSameChars(inputOne, inputTwo) && combined.length == 4){
return subtract(inputOne, inputTwo)
}
if (notAllSameChars(inputOne, inputTwo)) return reversed
return toRoman["$inputOne$inputTwo"] ?: combined
}
private fun replaceWithRoman(combined: String, k: String, v: String) = combined.replace(k, v)
private fun foundMatch(k: String, combined: String) = k in combined
private fun isIllegalSubtraction(inputOne: String, inputTwo: String): Boolean {
if (inputOne in listOf("V", "L", "D") && inputTwo != inputOne)
return true
return false
}
private fun subtract(inputOne: String, inputTwo: String): String {
val inputOneAppendFirst = "$inputOne$inputTwo${inputOne.first()}"
val match = toRoman[inputOneAppendFirst]
val firstChar = inputOne.first()
return "$firstChar$match"
}
private fun notAllSameChars(inputOne: String, inputTwo: String) = inputOne.first() != inputTwo.first()
private fun containsDups(inputOne: String) = inputOne.count { inputOne.contains(inputOne) } > 1
}
package roman.numeral.calculator.kotlin
import kotlin.test.Test
import kotlin.test.*
/*
I == 1
V == 5
X == 10
L == 50
C == 100
D == 500
M == 1000
The symbols I, X, C, and M can be repeated at most 3 times in a row
V, L, and D can never be repeated
As arabic numbers can be split into their constituent parts (1066 becomes 1 0 6 6), so too can Roman numerals. 1066 becomes MLXVI, or M (1000) LX (60) and VI (6)
The symbols (I, X, and C) can only be subtracted from the 2 next higher values. For example,
IV and IX -- (usage of I in subtraction rule)
XL and XC -- (usage of X in subtraction rule)
CD and CM -- (usage of C in subtraction rule)
The symbols (V, L, and D) can never be subtracted.
Only one subtraction can be made per numeral (XC is allowed, XXC is not).
*/
class RomanNumeralCalculatorTest {
@Test
internal fun `one plus one is two`() {
val calculator = Calculator()
val total = calculator.add("I", "I")
assertEquals("II", total)
}
@Test
fun `one plus two is three`() {
val calculator = Calculator()
val total = calculator.add("I", "II")
assertEquals("III", total)
}
@Test
fun `two plus three is five`() {
val calculator = Calculator()
val total = calculator.add("II", "III")
assertEquals("V", total)
}
@Test
fun `five plus five is ten`() {
val calculator = Calculator()
val total = calculator.add("V", "V")
assertEquals("X", total)
}
@Test
fun `thirty plus twenty is fifty`() {
val calculator = Calculator()
val total = calculator.add("XXX", "XX")
assertEquals("L", total)
}
@Test
fun `fifty plus fifty is one hundred`() {
val calculator = Calculator()
val total = calculator.add("L", "L")
assertEquals("C", total)
}
@Test
fun `four hundred plus one hundred is five hundred`() {
val calculator = Calculator()
val total = calculator.add("CCCC", "C")
assertEquals("D", total)
}
@Test
fun `five hundred plus five hundred is one thousand`() {
val calculator = Calculator()
val total = calculator.add("D", "D")
assertEquals("M", total)
}
@Test
fun `two plus five is seven`() {
val calculator = Calculator()
val total = calculator.add("II", "V")
assertEquals("VII", total)
}
@Test
fun `three plus one is four`() {
val calculator = Calculator()
val total = calculator.add("III", "I")
assertEquals("IV", total)
}
@Test
fun `three plus three is six`() {
val calculator = Calculator()
val total = calculator.add("III", "III")
assertEquals("VI", total)
}
@Test
fun `four plus five is nine`() {
val calculator = Calculator()
val total = calculator.add("IV", "V")
assertEquals("IX", total)
}
@Test
fun `four plus ten is fourteen`() {
val calculator = Calculator()
val total = calculator.add("IV", "X")
assertEquals("XIV", total)
}
@Test
fun `five plus ten is fifteen`() {
val calculator = Calculator()
val total = calculator.add("V", "X")
assertEquals("XV", total)
}
@Test
fun `six plus ten is sixteen`() {
val calculator = Calculator()
val total = calculator.add("VI", "X")
assertEquals("XVI", total)
}
@Test
fun `nine plus ten is nineteen`() {
val calculator = Calculator()
val total = calculator.add("X", "XI")
assertEquals("XXI", total)
}
@Test
fun `three plus twenty is twenty three`() {
val calculator = Calculator()
val total = calculator.add("III", "XX")
assertEquals("XXIII", total)
}
@Test
fun `fifty plus one hundred is one hundred fifty`() {
val calculator = Calculator()
val total = calculator.add("L", "C")
assertEquals("CL", total)
}
@Test
fun `five hundred plus one thousand is fifteen hundred`() {
val calculator = Calculator()
val total = calculator.add("D", "M")
assertEquals("MD", total)
}
@Test
fun `sixty six plus one thousand is sixteen hundred`() {
val calculator = Calculator()
val total = calculator.add("LXVI", "M")
assertEquals("MLXVI", total)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment