19
\$\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\$
  • 1
    \$\begingroup\$ Maybe a subtask of this challenge. \$\endgroup\$ – nimi Oct 27 '16 at 14:17
  • 3
    \$\begingroup\$ Very closely related to this challenge ... maybe close enough for a dupe. \$\endgroup\$ – AdmBorkBork Oct 27 '16 at 14:22
  • 8
    \$\begingroup\$ Please be more precise when saying number. In particular. must input 0 be supported? \$\endgroup\$ – Ton Hospel Oct 27 '16 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\$ – Martin Ender Oct 27 '16 at 14:42
  • 3
    \$\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\$ – Erik the Outgolfer Oct 27 '16 at 14:48

46 Answers 46

1
2
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))}
| improve this answer | |
\$\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
| improve this answer | |
\$\endgroup\$
  • \$\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 '16 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 '16 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 '16 at 17:29
  • \$\begingroup\$ perl -lpe 's%%s/\B/+/g;$_=eval%egr' \$\endgroup\$ – Ton Hospel Oct 27 '16 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
| improve this answer | |
\$\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
| improve this answer | |
\$\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
| improve this answer | |
\$\endgroup\$
  • \$\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 '16 at 21:06
0
\$\begingroup\$

J, 8 bytes

**1+9|<:

Uses the formula d(n) = ((n-1) mod 9) + 1 with the case d(0) = 0.

Usage

   f =: **1+9|<:
   (,.f"0) 0 1 45 341 6801 59613 495106
     0 0
     1 1
    45 9
   341 8
  6801 6
 59613 6
495106 7

Explanation

**1+9|<:  Input: integer n
      <:  Decrement n
    9|    Take it modulo 9
  1+      Add 1 to it
*         Sign(n) = 0 if n = 0, else 1
 *        Multiply and return
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Braingolf, 20 bytes [non-competing]

VR1>[<$_dl1-M&+vmR>]

Explanation:

VR1>[<$_dl1-M&+vmR>]  Implicit input to stack
VR                    Create new stack, then return to main stack
  1>                  Push 1 and move to beginning of stack
    [..............]  Loop, will always run once, will repeat if first item is > 0 at ]
     <$_              Silently pop first item from stack
        d             Split last item on stack into digits
         l1-          Push amount of digits minus 1
            M         Move last item (amount of digits) to next stack
             &+       Sum entire stack, pop everything, push total sum
               vmR    Move to next stack, move last item to prev stack, return to main stack
                  >   Move last item on stack to the beginning of stack
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Tcl, 57 bytes

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

Try it online!

| improve this answer | |
\$\endgroup\$
0
\$\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.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

JavaScript, 37 bytes

Input is taken as a string.

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

Try it online!

| improve this answer | |
\$\endgroup\$
0
\$\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 
| improve this answer | |
\$\endgroup\$
0
\$\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
| improve this answer | |
\$\endgroup\$
0
\$\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
| improve this answer | |
\$\endgroup\$
0
\$\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

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Ohm v2, 5 bytes

ì‹9%›

Explanation:

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

Try it online!

| improve this answer | |
\$\endgroup\$
0
\$\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. :-)

| improve this answer | |
\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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