From dbb22b755d61dee26690f7059b33462d126e01f8 Mon Sep 17 00:00:00 2001 From: Matej Focko Date: Mon, 15 Aug 2022 09:45:52 +0200 Subject: [PATCH] =?UTF-8?q?problems:=20add=20=E2=80=9E13.=20Roman=20to=20I?= =?UTF-8?q?nteger=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matej Focko --- problems/roman-to-integer.kt | 62 ++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 problems/roman-to-integer.kt diff --git a/problems/roman-to-integer.kt b/problems/roman-to-integer.kt new file mode 100644 index 0000000..1c68415 --- /dev/null +++ b/problems/roman-to-integer.kt @@ -0,0 +1,62 @@ +class Solution { + /** + * Holds fixed mapping of roman numerals to their respective numeric value. + */ + private val values = mapOf( + 'I' to 1, 'V' to 5, 'X' to 10, 'L' to 50, 'C' to 100, 'D' to 500, 'M' to 1000 + ) + + /** + * Represents an accumulator for right fold when turning roman numeral into an integer value. + * @property sum Holds the current sum of the accumulator. + * @property next Holds the value of the previous roman numeral digit. + */ + private data class Accumulator(val sum: Int = 0, val next: Int = 0) { + /** + * @param it Current roman numeral digit. + * @return Sign that is to be used when modifying sum of the accumulator. + */ + private fun sign(it: Int): Int = when (next > it) { + true -> -1 + false -> 1 + } + + /** + * @param it Currently processed roman numeral digit. + * @return Correctly updated accumulator. + */ + fun update(it: Int): Accumulator = copy(sum = sum + sign(it) * it, next = it) + } + + fun romanToInt(s: String): Int = s + .map { values[it]!! } + .foldRight(Accumulator()) { it, acc -> + acc.update(it) + } + .sum +} + +fun main() { + val s = Solution() + + val tests = mapOf( + "I" to 1, + "II" to 2, + "III" to 3, + "IV" to 4, + "V" to 5, + "VI" to 6, + "VII" to 7, + "VIII" to 8, + "IX" to 9, + "X" to 10, + "LVIII" to 58, + "MCMXCIV" to 1994 + ) + + tests.forEach { (num, i) -> + check(s.romanToInt(num) == i) { + "$num: ${s.romanToInt(num)} == $i" + } + } +}