Kotlin Program to Display Armstrong Numbers Between Intervals Using Function

An Armstrong number (also known as a narcissistic number or pluperfect number) is a number that is equal to the sum of its own digits each raised to the power of the number of digits. In this comprehensive article, we will explore Kotlin Program to Display Armstrong Numbers Between Intervals Using Function. We will provide three different solutions with code, output, and explanations for each example.

Introduction

Armstrong numbers are fascinating mathematical curiosities. For instance, 153 is an Armstrong number because 1^3+5^3+3^3=153. Our goal is to find all Armstrong numbers within a specified range.

Example 1: Basic Approach

1.1 Code

Kotlin
fun isArmstrongNumber(number: Int): Boolean {
    val digits = number.toString().length
    var sum = 0
    var temp = number

    while (temp > 0) {
        val digit = temp % 10
        sum += Math.pow(digit.toDouble(), digits.toDouble()).toInt()
        temp /= 10
    }
    return sum == number
}

fun displayArmstrongNumbers(start: Int, end: Int) {
    for (number in start..end) {
        if (isArmstrongNumber(number)) {
            println(number)
        }
    }
}

fun main() {
    val start = 100
    val end = 999
    displayArmstrongNumbers(start, end)
}

1.2 Output

Kotlin
153
370
371
407

1.3 Explanation

In this basic approach, the isArmstrongNumber function checks if a given number is an Armstrong number. The function calculates the sum of the digits raised to the power of the number of digits. The displayArmstrongNumbers function iterates through the given range and prints the Armstrong numbers.

Example 2: Using List and Higher-Order Functions

2.1 Code

Kotlin
fun isArmstrong(number: Int): Boolean {
    val digits = number.toString().map { it.toString().toInt() }
    val sum = digits.sumBy { Math.pow(it.toDouble(), digits.size.toDouble()).toInt() }
    return sum == number
}

fun displayArmstrongNumbersInRange(start: Int, end: Int) {
    (start..end).filter { isArmstrong(it) }.forEach { println(it) }
}

fun main() {
    val start = 100
    val end = 999
    displayArmstrongNumbersInRange(start, end)
}

2.2 Output

Kotlin
153
370
371
407

2.3 Explanation

This approach uses Kotlin’s higher-order functions and lists for a more idiomatic solution. The isArmstrong function uses the map function to transform the digits and sumBy to calculate the sum of the digits raised to the power of their count. The displayArmstrongNumbersInRange function uses filter to find Armstrong numbers and forEach to print them.

Example 3: Using Recursion

3.1 Code

Kotlin
fun isArmstrongRecursive(number: Int, length: Int, sum: Int = 0, temp: Int = number): Boolean {
    return if (temp == 0) {
        sum == number
    } else {
        val digit = temp % 10
        isArmstrongRecursive(number, length, sum + Math.pow(digit.toDouble(), length.toDouble()).toInt(), temp / 10)
    }
}

fun displayArmstrongNumbersWithRecursion(start: Int, end: Int) {
    for (number in start..end) {
        if (isArmstrongRecursive(number, number.toString().length)) {
            println(number)
        }
    }
}

fun main() {
    val start = 100
    val end = 999
    displayArmstrongNumbersWithRecursion(start, end)
}

3.2 Output

Kotlin
153
370
371
407

3.3 Explanation

This approach uses recursion to check for Armstrong numbers. The isArmstrongRecursive function calls itself recursively to calculate the sum of the digits raised to the power of the number of digits. The displayArmstrongNumbersWithRecursion function iterates through the given range and prints the Armstrong numbers found using the recursive function.

Conclusion

We have explored three different approaches to find Armstrong numbers between given intervals in Kotlin:

  1. Basic Approach: Simple and straightforward method using loops and conditionals.
  2. Using List and Higher-Order Functions: More idiomatic Kotlin solution using functional programming concepts.
  3. Using Recursion: A recursive approach to solve the problem.

Each method has its own advantages and can be chosen based on the specific requirements and preferences of the developer. Understanding these different approaches provides a solid foundation for solving similar problems in Kotlin.