Ad

Decimal to Factorial number system - Extension functions

Inspired by the Decimal to Factorial and Back kata.

In that kata the task was to implement two functions, one of which should convert a number in base 10 into the corresponding represnetation in the factorial number system.
The factorial number system is a non-standard positional numeral system using factorials.

Read more on Wikipedia

This is usually a good use case for Extension functions in Kotlin.

Task

Extend the Kotlin Long class to include a method that converts a Long to its string representation in the factorial number system.

  • Create an extension function for the Long class called toFactorialString. It should return a String that represents the number in the factorial number system.
  • If the number is zero, the function should return "0".

Example:

36288000L.toFactorialString()  // Should return "A0000000000"
463L.toFactorialString()  // Should return "341010"

Note:

  • The given numbers are always positive
  • The function should be optimized for performance.
package solution

val factorialCache = mutableMapOf(0L to 1L)
val digitToChar = (0..9).map { it to it.toString().first() } + (10..35).map { it to ('A' + it - 10) }

fun Long.factorial(): Long = factorialCache.getOrPut(this) { this * (this - 1).factorial() }

// Extension function to convert Long to factorial string
fun Long.toFactorialString(): String {
    var num = this
    val digits = generateSequence(0) { it + 1 }
        .takeWhile { num > 0 }
        .map {
            val remainder = num % (it + 1)
            num /= (it + 1)
            remainder
        }
        .toList()
        .reversed()
        .joinToString("") { digitToChar[it.toInt()].second.toString() }

    return digits.ifEmpty { "0" }
}

a kotlin more idiomatic way and with Long instead of Int

Code
Diff
  • fun fact(n: Long): Long = n.let { 
                require(it > 0L)
                (2L..it).fold(1L, Long::times)
            }
    • fun fact(n: Int):Int {
    • return if (n == 0) 1
    • else fact(n-1) * n
    • }
    • fun fact(n: Long): Long = n.let {
    • require(it > 0L)
    • (2L..it).fold(1L, Long::times)
    • }