I am new to Kotlin and I am trying to write a function to convert a number to Roman Numerals; however, I am unable to set the values of "numberBeingChecked" and "romanNumeral" from inside the loop, would you know why?
fun encode(num: Int): String {
var numberBeingChecked: Int = num
var romanNumeral: String = ""
myLoop@ while (numberBeingChecked > 0) {
when (numberBeingChecked) {
0 -> {
return romanNumeral
}
in 1..4 -> {
romanNumeral "I"
numberBeingChecked - 1
break@myLoop
}
in 5..9 -> {
romanNumeral "V"
numberBeingChecked - 5
break@myLoop
}
in 10..49 -> {
romanNumeral "X"
numberBeingChecked - 10
break@myLoop
}
in 50..99 -> {
romanNumeral "L"
numberBeingChecked - 50
break@myLoop
}
in 100..499 -> {
romanNumeral "C"
numberBeingChecked - 100
break@myLoop
}
in 500..999 -> {
romanNumeral "D"
numberBeingChecked - 500
break@myLoop
}
else -> {
romanNumeral "M"
numberBeingChecked - 1000
break@myLoop
}
}
}
return romanNumeral
}
fun main(args: Array<String>) {
encode(0)
encode(1)
encode(21)
encode(2008)
encode(1666)
}
Please let me know if I am doing something wrong, your help will be appreciated.
Kind regards
CodePudding user response:
You're not performing an assignment. You need either an equals sign as i=i 1
, or a shorthand like i
.
CodePudding user response:
You don't really reassign these variables in your code. numberBeingChecked - 5
expression does not decrease the value of numberBeingChecked
. It just subtracts 5
from numberBeingChecked
and does nothing with the result. To decrease numberBeingChecked
by 5
you need to use -=
operator: numberBeingChecked -= 5
. Same applies to romanNumeral
, e.g.: romanNumeral = "V"
.
Another bug in your code is that you always break from the loop after the first step. You should only get out of the loop when numberBeingChecked
is zero, so you really need to remove all these break
instructions.
Additionally, you should avoid creating strings by concatenating multiple times, because it results in copying the whole string with each step. Instead, create a StringBuilder
, append to it and at the last step invoke toString()
on it to get a result.
The resulting code looks like this:
var numberBeingChecked: Int = num
var romanNumeral = StringBuilder()
while (numberBeingChecked > 0) {
when (numberBeingChecked) {
in 1..4 -> {
romanNumeral.append("I")
numberBeingChecked -= 1
}
...
}
}
return romanNumeral.toString()
We can simplify it even further with buildString()
utility which helps us create the StringBuilder
and convert it to a string:
var numberBeingChecked: Int = num
return buildString {
while (numberBeingChecked > 0) {
when (numberBeingChecked) {
in 1..4 -> {
append("I")
numberBeingChecked -= 1
}
...
}
}
}
However, the latter uses some advanced features of Kotlin, it is harder to explain/understand how it works internally and therefore it may not be the best for learning purposes.