
Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: January 24, 2024
A number is a magic number if the recursive sum of its digits is one. In this tutorial, let’s look at how we can check this in Scala.
As mentioned in the previous section, we’ll check if a number is a magic number. In this context, we assume that the number is positive. As a result, we take the absolute value for the calculation to ensure this assumption.
Let’s see some sample cases before getting started with the implementation.
The number 654 isn’t a magic number since the sum of digits isn’t1 ( 6 + 5 + 4 = 15; 1 + 5 = 6)
On the other hand, 100 is a magic number since the sum of its digits(1 + 0 + 0 = 1) is 1.
Let’s look at various ways this can be checked in Scala. In all cases, we can split the implementation into two parts: a function to calculate the sum of digits and another function to check if the sum is 1.
We can use recursion to calculate the sum of the digits. In this case, we can use tail recursion to make sure that the implementation is safer by optimizing the code and reducing the stack calls to one:
def sumOfDigitsUsingRecursion(num: Long): Long = {
@tailrec
def recursiveSum(num: Long, sum: Long): Long = {
num match {
case 0 if sum < 10 => sum
case 0 if sum >= 10 => recursiveSum(sum / 10, sum % 10)
case n => recursiveSum(n / 10, sum + (num % 10))
}
}
recursiveSum(num, 0)
}
We use the integer division and modulo logic to extract each digit from the number. Additionally, we invoke the same method with the resultant sum if it’s not a single-digit number.
Now we can check if the number is a magic number easily:
assert(sumOfDigitsUsingRecursion(100) == 1)
Another approach to extract the digit is converting the number into a String and using map() on each digit. We can then use the in-built sum() method to calculate the sum:
@tailrec
def sumOfDigitsUsingAsDigit(num: Long): Long = {
if (num < 10) {
// If the number is a single digit, return it
num
} else {
// Calculate the sum of digits recursively
val digitSum = num.toString.map(_.asDigit).sum
sumOfDigitsUsingAsDigit(digitSum)
}
}
Here, we invoke the method recursively with the sum value until it’s reduced to a single digit:
assert(sumOfDigitsUsingAsDigit(100) == 1)
This approach is very similar to the previous solution. Instead of using the sum() method directly, we can use foldLeft() to calculate the sum. We then make use of recursion to reduce the sum to a single-digit value:
@tailrec
def sumOfDigitsUsingFold(num: Long): Long = {
def sum = num.toString.foldLeft(0)((acc, dig) => acc + dig.asDigit)
if (sum < 10) sum else sumOfDigitsUsingFold(sum)
}
Again, we can test the method in the same way:
assert(sumOfDigitsUsingFold(100) == 1)
Now, let’s look at a different approach to calculating the sum using Iterator:
def sumOfDigitsUsingIterator(num: Long): Long = {
Iterator
.iterate(num)(currentNum => currentNum.toString.map(_.asDigit).sum)
.dropWhile(_ >= 10)
.next()
}
Here, we create an infinite iterator that repeatedly applies the given function. In this case, we initialize an iterator with the input number and then calculate the sum of the digits of that number. We chain a dropWhile() method, which checks if the sum is a two-digit number. As a result, the iterator recalculates the sum until it becomes a single-digit number. Ultimately, we extract the value from the iterator by calling the next() method.
We can test this method in the same way:
assert(sumOfDigitsUsingIterator(100) == 1)
In this article, we explored different ways to check if a number is a magic number. Scala Collections are very powerful, and hence, there may be even more ways to calculate the sum of digits.