DEV Community

dev.to staff
dev.to staff

Posted on

9 2

Daily Challenge #264 - Digital Root

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!

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (16)

Collapse
 
ayanb profile image
Ayan Banerjee • Edited

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;
}
Collapse
 
peter279k profile image
peter279k

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)
Collapse
 
agtoever profile image
agtoever • Edited

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!

Collapse
 
rafaacioly profile image
Rafael Acioly

why 1 + (n - 1)?

Collapse
 
dry profile image
Hayden Mankin

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
Collapse
 
jmplourde profile image
Jean-Michel Plourde

I tested it with just n and it works fine.

Collapse
 
aminnairi profile image
Amin

Haskell

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
Collapse
 
jmplourde profile image
Jean-Michel Plourde • Edited

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)
Collapse
 
johnmilimo profile image
JMW

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)
    }
}
Collapse
 
filopd profile image
Priyesh Naik • Edited

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)

Collapse
 
willsmart profile image
willsmart • Edited

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.

Collapse
 
willsmart profile image
willsmart • Edited

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

muckle = n => n  && (n%9 || 9)
Collapse
 
dry profile image
Hayden Mankin

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
Collapse
 
tam360 profile image
Mirza

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)])

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay