# Daily Challenge #264 - Digital Root

Daily Challenge (275 Part Series)

Digital root is the recursive sum of all the digits in a number. Given n, take the sum of the digits of n. If that value has more than one digit, continue reducing in this way until a single-digit number is produced. This is only applicable to the natural numbers.

### Examples

16  -->  1 + 6 = 7
942  -->  9 + 4 + 2 = 15  -->  1 + 5 = 6
132189  -->  1 + 3 + 2 + 1 + 8 + 9 = 24  -->  2 + 4 = 6
493193  -->  4 + 9 + 3 + 1 + 9 + 3 = 29  -->  2 + 9 = 11 --> 1 + 1 = 2


### Tests

digital_root(456)
digital_root(16)

Good luck!

This challenge comes from user578387 on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Daily Challenge (275 Part Series)

Posted on by:

### dev.to staff

The hardworking team behind dev.to ❤️

### Discussion

Property of the digital root is that the result would be n % 9 and n % 9 == 0 it will be 9.

int digitalRoot(int n) {
if (n == 0) return 0;
if (n % 9 == 0) return 9;
return n % 9;
}


Here is the Python code snippets with nest while loop:

def digital_root(n):
result = 0
n = str(n)

index = 0
while len(n) != 1:
while index < len(n):
result += int(n[index])
index += 1

index = 0
n = str(result)
result = 0

return int(n)


Python 3 using direct calculation. Defined as function with test cases in the tio link.

digital_root = lambda n: 0 if n == 0 else 1 + (n - 1) % 9


Try it online!

why 1 + (n - 1)?

It's important to remember that the % operator happens before +, this solves the edge cases around numbers divisible by 9 without needing extra if statements/ternaries.

For instance,

18 -> 1 + 8 = 9


however,

18 % 9 = 0


which does not fit the problem specification, so instead we do

(18 - 1) % 9 + 1 = 17 % 9 + 1 = 8 + 1 = 9


I tested it with just n and it works fine.

sumDigits :: Int -> Int
sumDigits 0 = 0
sumDigits n = (mod n 10) + sumDigits (div n 10)

digitalRoot :: Int -> Int
digitalRoot n
| n > 9     = digitalRoot (sumDigits n)
| otherwise = n


Here's my solution in Python. Not bad considering I gave it only 5 minutes. I could have gone with reduce and lambda, but it's not really pythonic, not fast and the reading would be terrible. I like the short circuit behavior.

def digital_root(n):
while True:
n_list = [int(d) for d in str(n)]
if len(n_list) == 1:
return n
n = sum(n_list)


Python 3 (indent 3 is not reflecting in comment)

ip_val = input("Enter the number?")

if ip_val.isdigit():
while len(ip_val) > 1:
res = 0
for e in ip_val:
res += int(e)
ip_val = str(res)
print(ip_val)

n % 9 is such an interesting property! But since I had no knowledge of it, I went with a naive solution in KOTLIN which I cracked within a few minutes:

fun digitalRoot(number: Int): Int {
return if(number < 10) {
number
} else {
val digits = number.toString().split("")
var sum = 0
digits.forEach {
val digit = it.toIntOrNull()
if(digit != null) { sum += digit}
}
digitalRoot(sum)
}
}


Anytime there's this sort of array summarizing is a good time for reduce
Here's a wee JS implementation of the recursive method (didn't know about the modulus one, pretty neat)

knuckle = n =>
n<10 ? n : knuckle(
[... ''+n].reduce(
(acc, char)=>acc + ~~char,
0
)
)


So, for numbers greater than ten, convert the number to a string (''+n), split the string into its digits ([... ''+n]), and accumulate the sum of those digits ([... ''+n].reduce((acc, char)=>acc + ~~char, 0). Then recuse another level just in case the sum is multi-digit too.

Note that squiggigle operator ~~ (my term, not sure if it's got a name already) reliably converts a value to an signed 32-bit int in a bit less space than doing it properly, it's pretty much the same as the bang bang op !!, just with bitwise negation. It's used here since char is a string, ~~char get's the string's parsed number.

Here's my take on the modulus one, keeping with the nsfw JS syntax theme

muckle = n => n  && (n%9 || 9)


I've always liked this problem because of the n%9 trick, it's such a neat mathematical property.

I thought I'd do the obligatory n%9 solution:

let digital_root = (n) => n == 0 ? 0 : (n - 1) % 9 + 1;

console.log(digital_root(456)); // 6
console.log(digital_root(16));  // 7


As well as a one line recursive solution that doesn't use the n%9 trick:

let digital_root = (n) => (n < 10) ? n : digital_root(Array.from(n.toString()).map(Number).reduce((a, b)=>a+b));

console.log(digital_root(456)); // 6
console.log(digital_root(16));  // 7


Here's my solution:

def digital_root(num):
num = str(num)

if len(num) == 1:
return int(num)
else:
temp = str(int(num[0]) + int(num[1]))
return digital_root(temp + num[2: len(num)])


def digital_root(number):