29
\$\begingroup\$

This is different from My Word can beat up your Word as it is less complex and only requires you to calculate it, and not compare them.

To find the digital root, take all of the digits of a number, add them, and repeat until you get a one-digit number. For example, if the number was 12345, you would add 1, 2, 3, 4, and 5, getting 15. You would then add 1 and 5, giving you 6.

Your task

Given an integer N (0 <= N <= 10000) through STDIN, print the digital root of N.

Test cases

1 -> 1
45 -> 9
341 -> 8
6801 -> 6
59613 -> 6
495106 -> 7

Remember, this is , so the code with the smallest number of bytes wins.

\$\endgroup\$
13
  • 1
    \$\begingroup\$ Maybe a subtask of this challenge. \$\endgroup\$
    – nimi
    Oct 27, 2016 at 14:17
  • 3
    \$\begingroup\$ Very closely related to this challenge ... maybe close enough for a dupe. \$\endgroup\$ Oct 27, 2016 at 14:22
  • 8
    \$\begingroup\$ Please be more precise when saying number. In particular. must input 0 be supported? \$\endgroup\$
    – Ton Hospel
    Oct 27, 2016 at 14:28
  • 2
    \$\begingroup\$ @TimmyD I think that this one is the much cleaner challenge without adding letter to integer conversion, computing the function for two values and including the literal STALEMATE. It might be better to close the other one as a dupe of this. \$\endgroup\$ Oct 27, 2016 at 14:42
  • 4
    \$\begingroup\$ @MartinEnder I retracted my close vote, I think it's unfair to close a good challenge as a dupe of another more complex challenge. \$\endgroup\$ Oct 27, 2016 at 14:48

59 Answers 59

1
2
1
\$\begingroup\$

Perl 6, 29 bytes

{($_,*.comb.sum...10>*)[*-1]}

Expanded:

{ # bare block lambda with implicit parameter 「$_」
  ( # generate a sequence

    $_,         # starting with the input
    *.comb.sum  # Whatever lambda that splits into digits, and finds sum
    ...         # keep doing that
    10 > *      # until it is less than 10

  )[ * - 1 ] # get the last value
}
\$\endgroup\$
1
\$\begingroup\$

Tcl, 57 bytes

while \$v>9 {set v [expr [join [split $v ""] +]]}
puts $v

Try it online!

\$\endgroup\$
1
\$\begingroup\$

dc, 37 bytes

[[A~rdZ1<D]dsDx[+z1<S]dsSxdZ1<M]dsMxp

Try it online!

[A~rdZ1<D]dsDx decompose. Divide by 10 leaving quotient & remainder on stack until the value on the top of the stack is a single digit.

[+z1<S]dsSx sum. Add two topmost stack values until stack depth is one.

Macro M contains both of those, and dZ1<M to keep running itself until the final result is a single digit. p to print.

\$\endgroup\$
1
\$\begingroup\$

JavaScript, 37 bytes

Input is taken as a string.

f=n=>n>9?f(eval([...n].join`+`)+""):n

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Forth (gforth), 69 bytes

: f begin 0 swap begin 10 /mod >r + r> ?dup 0= until dup 10 < until ;

Try it online!

Explanation

  1. Place sum (starting at 0) on stack
  2. Get remainder of number divided by 10
  3. Add to sum
  4. Replace number with itself divided by 10
  5. Repeat steps 2-4 until number equals 0
  6. Using sum as new starting number, repeat steps 1-5 until result is less than 10

Code Explanation

begin               \ start outer loop
  0 swap            \ place sum variable and move it down the stack
  begin             \ start inner loop
    10 /mod         \ get quotient and remainder of number/10
    >r +            \ temporarily "hide" quotient on return stack and add remainder to sum
    r> ?dup         \ retrieve quotient from return stack and duplicate if != 0
  0= until          \ end inner loop if sum is equal to 0
  dup 10 <          \ duplicate current "root" and check if less than 10
until               \ end outer loop if < 10 
\$\endgroup\$
1
\$\begingroup\$

Excel VBA, 69 bytes

An anonymous VBE immediate window function that takes input from range [A1] and outputs to the console.

n=[A1]:While n>9:s=0:For i=1To Len(n):s=s+Mid(n,i,1):Next:n=s:Wend:?n

Test Function

For each x in Array(1,45,341,6801,59613,495106):[A1]=x:n=[A1]:While n>9:s=0:For i=1To Len(n):s=s+Mid(n,i,1):Next:n=s:Wend:?x"->"n:Next
 1 -> 1
 45 -> 9
 341 -> 8
 6801 -> 6
 59613 -> 6
 495106 -> 7
\$\endgroup\$
1
\$\begingroup\$

QBasic 1.1, 66 bytes

INPUT N
WHILE N>9
M=N
N=0
WHILE M
N=N+M MOD 10
M=M\10
WEND
WEND
?N
\$\endgroup\$
1
\$\begingroup\$

K (oK), 9 bytes

Solution:

(+/.:'$)/

Try it online!

Explanation:

Super straightforward. Break number into digits and sum up - do this until the result converges:

(+/.:'$)/ / the solution
(      )/ / do this until result converges
      $   / string, 1234 => "1234"
   .:'    / value each, "1234" => 1 2 3 4
 +/       / sum over, 1 2 3 4 => 10
\$\endgroup\$
4
  • 1
    \$\begingroup\$ In my implementation of k I made x\y encode y in base x with as many digits as necessary, so it's slightly shorter: (+/10\)/ \$\endgroup\$
    – ngn
    Jun 21, 2018 at 0:22
  • \$\begingroup\$ Nice. In the newer versions of kdb+ (I think from 3.4 and up) you can do 10\:.. but not in oK - and .:'$ is the same number of bytes - so I went with that :) \$\endgroup\$
    – mkst
    Jun 21, 2018 at 5:42
  • \$\begingroup\$ oK uses \ and requires a list on the left: `(,10)` \$\endgroup\$
    – ngn
    Jun 21, 2018 at 6:11
  • \$\begingroup\$ Indeed, your implementation adds "as many digits as necessary", which is what you get from \: in kdb+ (3.4+), but for oK I'd need to know how many 10s to put in my list. \$\endgroup\$
    – mkst
    Jun 21, 2018 at 8:31
1
\$\begingroup\$

K (ngn/k), 8 bytes

(+/10\)/

Try it online!

this is based on @streetster's oK answer but uses a feature specific to ngn/k: 10\x is the list of digits of x

\$\endgroup\$
1
\$\begingroup\$

Ohm v2, 5 bytes

ì‹9%›

Explanation:

ì‹9%›
ì     Takes input as integer
 ‹    Decrements
  9%  Modulus 9
    › Increment

Try it online!

\$\endgroup\$
1
\$\begingroup\$

MBASIC, 105 94 bytes

1 INPUT N
2 A$=STR$(N):N=0:FOR I=1 TO LEN(A$):N=N+VAL(MID$(A$,I,1)):NEXT:IF N>9 THEN 2
3 PRINT N

Output:

? 495106
 7

? 59613
 6

? 6801
 6

Explanation:

Convert input to a string, then walk the string, adding each digit to a total. If the resulting total has more than 1 digit, repeat the process. Otherwise, print the total.

Okay, so it's not APL. But it will run on an 8-bit CP/M system. :-)

\$\endgroup\$
1
\$\begingroup\$

Keg, 6 bytes(SBCS on Keg wiki)

¿;9%1+

Explanation:

¿#      Take implicit input
 ;9%1+# Digital Root Formula
# Implicit output
\$\endgroup\$
1
\$\begingroup\$

TI-Basic, 11 bytes

1+9fPart((Ans-1)/9

Takes input in Ans.

\$\endgroup\$
1
\$\begingroup\$

Vyxal, 3 bytes

⁽∑Ẋ

Try it Online!

⁽ Ẋ # Until the result converges...
 ∑  # Sum digits
\$\endgroup\$
3
  • \$\begingroup\$ Your first answer does not work when the input is a multiple of 9. \$\endgroup\$
    – Yousername
    Oct 11, 2021 at 22:31
  • \$\begingroup\$ @Yousername Oops. Deleting. \$\endgroup\$
    – emanresu A
    Oct 11, 2021 at 22:31
  • \$\begingroup\$ vyxal.pythonanywhere.com/… another 3 byte solution \$\endgroup\$
    – pacman256
    Nov 3, 2022 at 19:29
1
\$\begingroup\$

APL (Dyalog Classic), 3 bytes

9⊤⊢

Try it online!

Anonymous tacit prefix fork train.

 ⊤      ⍝ Tail of base conversion of                   
   ⊢    ⍝ right argument to
9       ⍝ base 9
\$\endgroup\$
1
\$\begingroup\$

COBOL (GNU), 131 bytes

PROGRAM-ID.A.DATA DIVISION.
	WORKING-STORAGE SECTION.
	01 N PIC 9(9).
PROCEDURE DIVISION.ACCEPT N.COMPUTE N=FUNCTION REM(N- 1,9)+ 1

Try it online!

Explanation :

PROGRAM-ID.A.DATA DIVISION.
       * The first line is necessary and can't be removed
        WORKING-STORAGE SECTION.
       * sadly so is this (accept input / output)
        01 N PIC 9(9).
       * This accepts input N that is upto 999,999,999 (output is via same)
        PROCEDURE DIVISION.
       * Time to start working on program itself.
        ACCEPT N.
       * Accepts the input from stdin.
        COMPUTE N = FUNCTION REM(N - 1, 9) + 1
       * compute n such that it is mod of n - 1 and 9 and then add one (standard forumla of --N%9+1

Output is via display N.

\$\endgroup\$
1
\$\begingroup\$

braingolf, 20 13 bytes

[Rdl1-M&+v>]R

Try it online!
Links to the braingolf JS interpreter in TIO

Explanation

[Rdl1-M&+v>]R   Implicit input from command-line args to stack
[..........]R   Loop. Always runs once, will continue to run as long as the bottom value on the active stack is > 0
 R              Return to main stack, does nothing if already on main stack
  d             Pop top of stack, split into digits, push digits
   l            Push length of stack
    1-          Decrement top of stack
      M         Pop top of stack and push to next stack
       &+       Sum entire stack (all digits of input)
         v      Switch active stack to next stack
          >     Move top of stack to bottom

Decrementing the stack length, moving it to the second stack, and switching to the second stack before the end of the loop serves to use the decremented length as the loop counter. ie when the length is 1 (decremented to 0) the loop terminates.

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 3 bytes

ΔSO

Try it online or verify all test cases.

Or a minor alternative:

Δ1ö

Try it online or verify all test cases.

Explanation:

Δ    # Loop until the result no longer changes,
     # using the (implicit) input-integer in the first iteration
 S   #  Convert it to a list of digits
  O  #  Sum those together
     # (after which the resulting digit is output implicitly)

Δ    # Loop until the result no longer changes,
     # using the (implicit) input-integer in the first iteration
 1ö  #  Convert it from base-10 to base-1
     #  (which is a non-vectorizing way to sum an integer's digits in 05AB1E)
     # (after which the resulting digit is output implicitly)
\$\endgroup\$
1
\$\begingroup\$

Vyxal, 4 bytes

‹9%›

Try it Online!

\$\endgroup\$
1
\$\begingroup\$

Charcoal, 9 bytes

⁺﹪⁻N¹¦⁹¦¹

TryItOnline!

Explanation:

⁻N¹  - take a integer input and subtract one from it
﹪     - modulo function
⁺     - addition function which given to it n-1%9 and 1  
⁹     - number 9 which is like 10-1
¦     - just a argument separator 

PS: You could have reduced the argument separator by writing it in this order: ⁺¹﹪⁻¹N⁹ but 7 is not a cool length to have, Also you could put a before the whole thing to cast the result to printable integer value but since the numbers are represented as - characters in charcoal i ignored that.

\$\endgroup\$
1
\$\begingroup\$

Fig, \$4\log_{256}(96)\approx\$ 3.292 bytes

}%9{

Try it online!

}%9{
   {  # decrement with implicit input
 %9   # mod 9
}     # increment
\$\endgroup\$
1
\$\begingroup\$

Go, 75 bytes

func f(n int)int{if n<10{return n}
k:=0
for;n>0;n/=10{k+=n%10}
return f(k)}

Attempt This Online!

Go, Modulus solution, 29 bytes

func(n int)int{return^-n%9+1}

Attempt This Online!

\$\endgroup\$
1
\$\begingroup\$

><> (Fish), 36 bytes

>0$:1(?v:&a%+&a,:1%-20.
^v?(a:~<
n<;

Try it online! - Interactive Version

Expects input as a number pushed onto the stack in advance.

Explanation

There are 2 basic loops, one for summing the digits and one for checking if the number is less than 10 yet.

   :1(?v

Checks if the number is less than 1, if not all the digits are summed.

        :&a%+&a,:1%

Add the modulo to the accumulator, and then push the division again. We subtract the number %1 to make it a integer.

                   20.

Skip the first 3 letters of the bottom row.

^v?(a:~<
n<;

If the number is less than 10 (a is 10 in fish, it uses hexadecimal), print it and exit. Otherwise, go back to the start of the program with the number pushed to the stack.

>0$

Push the accumulator to the second from first spot on the stack.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can save 20 bytes by performing the operations on the input and erroring out: :a(?n:a%$a,:1%-+ \$\endgroup\$
    – Emigna
    Dec 6, 2022 at 12:30
0
\$\begingroup\$

Groovy, 57 Bytes

{n->for(;(n=(""+n).collect{(int)it-48}.sum())/10>1;){};n}

Repeatedly converts to string, sums the ascii conversion of the digits and continues while the resultant integer divided by 10 is greater than 1. Then it returns the mutated input.

Tried recursion too, cost more bytes though:

x={i->i?i%10+x(i.intdiv(10)):0};y={i->x(i)/10<1?x(i):y(x(i))}
\$\endgroup\$
0
\$\begingroup\$

Perl 34 28 bytes

Includes +1 for -p

s/./+$&/g,$_=eval while/../

Uses the method described in the question.

Example:

$ echo -n 495106 | perl -p DigitalRoot.pl
7
\$\endgroup\$
4
  • \$\begingroup\$ You need to count -p in your bytecount. (in that case, it will count for 3 bytes, but if you replaces the '' with "" then it's only 1 byte). And you can golf it further : the same approach can be written like s/./+$&/g,$_=eval while/../. Or you could do s/(.)(.)/$1+$2/e&&redo which is even shorter. And a shorter code (the approach is totally different) : $_=--$_%9+1. \$\endgroup\$
    – Dada
    Oct 27, 2016 at 17:19
  • \$\begingroup\$ @Dada I was trying to figure out why it wouldn't run on the command line for so long that I must have forgotten to add the extra bytes when I gave up (I don't use perl much). \$\endgroup\$
    – Riley
    Oct 27, 2016 at 17:29
  • \$\begingroup\$ @Dada s/(.)(.)/$1+$2/e&&redo doesn't exactly follow the method given in the question either. \$\endgroup\$
    – Riley
    Oct 27, 2016 at 17:29
  • \$\begingroup\$ perl -lpe 's%%s/\B/+/g;$_=eval%egr' \$\endgroup\$
    – Ton Hospel
    Oct 27, 2016 at 22:31
0
\$\begingroup\$

Element, 32 bytes

_2:1-+9/3:0<!{1-+2:0<!}1+-+9-*+`

Try it online!

This is using the typical closed-form formula, although it is noticeably more painful since Element lacks any rounding functionality.

_2:1-+9/3:0<!{1-+2:0<!}1+-+9-*+`
_2:                               make two copies of input
   1-+9/                          for one copy, subtract 1 and divide by 9
        3:0<!{1-+2:0<!}1+-+       floor it
                           9-*    multiply by -9
                              +`  add to the original input value, then output
\$\endgroup\$
0
\$\begingroup\$

Racket 152 bytes

(let p((ol'())(n n))(let*-values(((q r)(quotient/remainder n 10))((l)(cons r ol)))
(if(= q 0)(begin(let((s(apply + l)))(if(< s 10)s(p'()s))))(p l q)))))

Ungolfed:

(define (f n)
  (let loop ((ol '())
             (n n))
    (let*-values (((q r) (quotient/remainder n 10))
                 ((l) (cons r ol)))
      (if (= q 0)
          (begin
            (let ((s (apply + l)))
              (if (< s 10)
                  s
                  (loop '() s))))
          (loop l q))
      )))

Simpler version:

(define (f1 N)
  (define (getDigitList n)                   ; sub-fn  to get digits
    (let loop ((ol '())
               (n n))
      (let-values (((q r) (quotient/remainder n 10)))
        (if (= q 0) (cons r ol)
            (loop (cons r ol) q)))))

    (let loop2 ((n N))                       ; actual fn
      (define s (apply + (getDigitList n)))  ; get sum of digits
      (if (< s 10)
          s
          (loop2 s))))

Testing:

(f 1)
(f 45)
(f 341)
(f 6801)
(f 59613)
(f 495106)

Output:

1
9
8
6
6
7
\$\endgroup\$
0
\$\begingroup\$

C#, 79 Bytes

Golfed:

string R(string i){while(i.Length>1){i=i.Sum(o=>int.Parse(o+""))+"";}return i;}

Ungolfed:

string R(string i)
{
  while (i.Length > 1)
  {
    i = i.Sum(o => int.Parse(o + ""))+"";
  }

  return i;
}

Testing:

var printTheDigitalRoot = new PrintTheDigitalRoot();
Console.WriteLine(printTheDigitalRoot.S("1")); //1
Console.WriteLine(printTheDigitalRoot.S("45")); //9
Console.WriteLine(printTheDigitalRoot.S("341")); //8
Console.WriteLine(printTheDigitalRoot.S("6801")); //6
Console.WriteLine(printTheDigitalRoot.S("59613")); //6
Console.WriteLine(printTheDigitalRoot.S("495106")); //7
\$\endgroup\$
1
  • \$\begingroup\$ string is already IEnumerable<char> so you don't need to ToCharArray() before calling Sum() on it. o-48 is a shorter than int.Parse(o+""). Having said these, the mod 9 trick will be much shorter than actually summing the digits. \$\endgroup\$
    – milk
    Oct 27, 2016 at 21:06
0
\$\begingroup\$

Thunno 2 t, 2 bytes

9B

Attempt This Online!

Port of Jonathan Allan's Jelly answer.

Explanation

9B  # Implicit input
 B  # Convert the input to a
9   # list of digits in base 9
    # Implicit output of last item
\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.