Sum of digits - help

In this kata, you must create a digital root function.

A 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.

Here’s how it works:

digital_root(16)
=> 1 + 6
=> 7

digital_root(942)
=> 9 + 4 + 2
=> 15 ...
=> 1 + 5
=> 6

digital_root(132189)
=> 1 + 3 + 2 + 1 + 8 + 9
=> 24 ...
=> 2 + 4
=> 6

digital_root(493193)
=> 4 + 9 + 3 + 1 + 9 + 3
=> 29 ...
=> 2 + 9
=> 11 ...
=> 1 + 1
=> 2

Hi, hope you’re well. I am new to coding and would like help on this challenge:

At the moment i want to separate the strings but i get this error: Cannot read property ‘length’ of undefined. I think snumber=digital_root() is incorrect but i am not sure how to fix it. Code is below:

var  
    
    output = [],
    sNumber = digital_root().toString();

function digital_root(n) {

for (var i = 0, len = sNumber.length; i < len; i += 1) {
    output.push(+sNumber.charAt(i));
}

}

  console.log(digital_root(50));
  1. is [https://repl.it] a good console for learning? or anything better? thanks so much

Not sure why you have code outside the function at the top. The sNumber = code will call digital_root with undefined for n and then return undefined and set sNumber to undefined.
In general you want to have all the code inside your function, unless there is some specific request / need for global data.

function digital_root(n) {

  var  
    
    output = [],
    sNumber = n.toString("");

for (var i = 0, len = sNumber.length; i < len; i += 1) {
    output.push(+sNumber.charAt(i));
}

}

  console.log(digital_root(50));

Thanks, yes. That makes sense now. Now i get this error:
RangeError: toString() radix argument must be between 2 and 36

Hello @silvercut,

You have several mistakes here. I will try to explain.

You have a function digital_root and you run it by executing digital_root(50) statement. Now this function runs with a value n = 50.

function digital_root(n) {
 // n === 50 

// here you can create variable and transform value to the string like:
const numbersString = n.toString();
// numbersString === "50"

// transform it to the array
const numberStringsArray = numbersString.split('');
// numberStringsArray === ["5", "0"]

// iterate through the array, sum the values and return the result
// note that additional + here `+currentValue` will convert string to a number
// Also, read the documentation about reduce method. It is very useful when you need to find a sum of array values
return numberStringsArray.reduce((totalSum, currentValue) => totalSum + +currentValue, 0);
}

Hope it helps!

RangeError: toString() radix argument must be between 2 and 36
The error is telling you that you are giving toString and invalid value
Your code is toString("") and toString wants a number from 2-36 (10 in this case for decimal).
My suggestion is that when you see these types of problems, open your developer
tools in the browser and type in the suspect code there and see what happens

hi this is great, when i run the chrome developer tools and want to debug something, it starts to debug the html pages, not the snippets of code that i want to debug. How do i deactivate and/or prioritise the snippet to debug first (or only debug the snippet)?

thanks

Hi this is fantastic and very well. Watched a video on reduce functions. So, this does not work when the digits are over 2. Because, the challenge has to lower the sum to below 10.

I want to write an if statement that says “if the number => 10, run the code again for the new answer”. However, when i start write the if statement i get this error:

  1. message: “numberStringsArray is not defined”
  2. stack: “ReferenceError: numberStringsArray is not defined↵ at eval (eval at (:18:1), :1:1)↵ at snippet:///Script%20snippet%20%232:18:1”
  3. proto: Error

Why does this happen?

function digital_root(n) {

var numbersString = n.toString();


var numberStringsArray = numbersString.split('', 2);

return numberStringsArray.reduce((totalSum, currentValue) => totalSum + +currentValue, 0);

if numberStringsArray < 5 {}
}

digital_root(590)

thanks

edit: or even if i want to declare a new variable (like sum = numberStringsArray.reduce((totalSum, currentValue) => totalSum + +currentValue, 0):wink: ,
it wont allow it

To solve the next step of this challenge you have to use a recursion - https://javascript.info/recursion.

You already have the logic to sum all the numbers from the input, right? So you have to use this function over and over again until you have only 1 digit.

Lets look at the example:

// You run the function with n = 65. It produces the result = 11.
digital_root(65) // 6 + 5 === 11. As you see it is still not one number, so you have to run the same function one more time with this result, right?

digital_root(11) // 1 + 1 === 2. Now we have only one number, so we need to return it as a result.

Now lets enhance the function we wrote earlier:

function digital_root(n) {
  const numbersString = n.toString();
  
  // If numbersString length is only one char long, we return the result 
  if(numbersString.length === 1) {
    return n;
  }

  // and if not, we continue to run the code below
  const numberStringsArray = numbersString.split('');

  // Calculate the sum of all numbers in an array
  const sumOfStringsArray = numberStringsArray.reduce((totalSum, currentValue) => totalSum + +currentValue, 0);

  // Tell our function to run itself again
  return digital_root(sumOfStringsArray);
}

You never “have to” use recursion.

Also, in the future, please don’t just give the solution away when others before you have taken the time to only give hints and suggestions, so the user can figure the solution out.

1 Like