DEV Community

Cover image for Solving the Digital Root Algorithm using JavaScript

Solving the Digital Root Algorithm using JavaScript

isabel k. on May 17, 2020

One of my favorite algorithms is finding the digital root of any given integer. A digital root is a single-digit sum that is reached when you itera...
Collapse
 
kdraypole profile image
Kobe Raypole

Very cool! I'm a Ruby enthusiast so I tried it out in that.

Your Iterative strategy was great but I think using recursion could help reduce some of the complexity and make for some cleaner code.

def d_root(num)
  return num if num < 10

  d_root(num.to_s.split('').reduce(0) {|acc, digit| acc + digit.to_i}) 
end

Ruby gives us some great helpers for integers so we can simplify this even more.

def d_root(num)
  return num if num < 10

  d_root(num.digits.sum) 
end

Nice and simple!

Collapse
 
khuongduybui profile image
Duy K. Bui

Can I cheat?

function d_root(num) {
  return (num % 9) || 9;
}
Enter fullscreen mode Exit fullscreen mode

:D

Collapse
 
pavi2410 profile image
Pavitra Golchha

I am really curious how do you know this?

Collapse
 
khuongduybui profile image
Duy K. Bui

I learnt it first as a math trick for children in Vietnam: to know if something is divisible by 9, you calculate its digitial root and see if the digital root is divisible by 9 (same goes for 3).

When I grew up, I was curious and tried to prove that mathematically, which is how I ended up with digitalRoot(num) = num % 9 (or 9 if divisible by 9) :D

Collapse
 
terkwood profile image
Felix Terkhorn

mathworld.wolfram.com/DigitalRoot....

Looking good in this corner of the thread!

Collapse
 
keltroth profile image
Django Janny

What about d_root(0) ?

Collapse
 
athul7744 profile image
Athul Anil Kumar

Amazing intuition!

Collapse
 
kushal-niroula profile image
Kushal Niroula

Are we sure this is a recursive approach? I feel like this is an iterative solution as we just run a block until a condition is met. The function is not called multiple times.

function dRoot(num) {
  const parts = num.toString().split("");
  const sum = parts.reduce((aggr,part) => parseInt(part) + parseInt(aggr));
  if(sum > 9) return dRoot(sum);
  return sum;
}

I think this qualifies as recursive. But the iterative approach in the article is much more performant I think. Nice article.

Collapse
 
ph1p profile image
Phil

Thank you! I like those tiny little programming "snacks" :)


shortest (recursion) solution I could find:

const dr = r => r < 10 ? r : dr([...r+''].reduce((b,c) => +b+(+c)));

dr(129); // 3
Collapse
 
darthbob88 profile image
Raymond Price

Cool demo, but that's not actually recursion, that's just iteration. An actual recursive solution, if you wanted to do that for some strange reason, would look more like

function digitalRoot(number) {
   let arr = number.toString().split("");
   let reducer = (a,b) => parseInt(a) + parseInt(b);
   let sum = arr.reduce(reducer)

   if (sum > 9) {
       return digitalRoot(sum);
   } else {
       return sum;
   }
}

Also, sidenote, this function does break on very large numbers. That's not OP's fault, that's because Javascript can't reasonably represent things like 1234567891234567891234567891 as an integer. digitalRoot("1234567891234567891234567891") works just fine, though

Collapse
 
luigidcapra profile image
Luigi D. Capra • Edited

function F_iRoot(P_sz0){
var sz0 = "" + P_sz0;
var iLen = sz0.length;
var iNum;
var ch;
var iSum = 0;
for (var i=0; i < iLen; i++) {
ch = sz0.charCodeAt(i);
iNum = ch - 48; // '0' = 0x30 = 48
iSum += iNum;
} /* for /
if (iSum > 9) {
iSum = F_iRoot(iSum);
} /
if /
return(iSum);
} /
F_iRoot */

Collapse
 
sylwiavargas profile image
Sylwia Vargas

I love this post! You explain it all so well! Are you planning on creating an algo series?

Collapse
 
gudimba profile image
Austin Imbastari

thank you so much omg

Collapse
 
sabyrcpu profile image
sabyr-cpu

The better solution I think:

function digital_root(n) {
return (n - 1) % 9 + 1;
}