8
\$\begingroup\$

Challenge

  • Given a non-negative integer, find the sum of its digits.

Rules

  • Your program must take a non-negative integer as input.
  • Your program should output the sum of the digits of the input integer.
  • Your program should be able to handle inputs up to 10^100.

Examples

  • If the input is 123, the output should be 6 (1 + 2 + 3).
  • If the input is 888, the output should be 24 (8 + 8 + 8).
  • If the input is 1024, the output should be 7 (1 + 0 + 2 + 4).
  • If the input is 3141592653589793238462643383279502884197169399375105820974944592, the output should be 315.

Format

  • Your program should take input from standard input (stdin) and output the result to standard output (stdout).
  • Your program should be runnable in a Unix-like environment.

Test cases

Input:

123

Output:

6

Input:

888

Output:

24

Input:

1024

Output:

7

Input:

3141592653589793238462643383279502884197169399375105820974944592

Output:

315

Scoring

  • This is a code-golf challenge, so the shortest code (in bytes) wins.
\$\endgroup\$
6
  • 3
    \$\begingroup\$ I have a feeling this is a duplicate... \$\endgroup\$
    – Seggan
    Feb 24 at 23:04
  • 2
    \$\begingroup\$ this is OEIS A007953 \$\endgroup\$
    – c--
    Feb 24 at 23:24
  • \$\begingroup\$ Can I take it as an array with 1 element in it? \$\endgroup\$ Feb 25 at 0:05
  • \$\begingroup\$ Related \$\endgroup\$
    – EzioMercer
    Feb 25 at 17:08
  • 1
    \$\begingroup\$ @Surb 1 2 3 4 5 6 7 ... there's plenty more \$\endgroup\$
    – naffetS
    Mar 9 at 1:33

51 Answers 51

9
\$\begingroup\$

Vyxal s, 0 bytes


Try it Online!

That's right. No bytes needed.

Alternatively

Vyxal, 1 byte

Try it Online!

Just the built-in that works on numbers

\$\endgroup\$
2
  • \$\begingroup\$ 0 bytes is a really cool one and quite rare! \$\endgroup\$
    – Surb
    Feb 26 at 20:38
  • \$\begingroup\$ @lyxal I think no answer can defeat you now, you rock \$\endgroup\$ Feb 26 at 21:00
9
\$\begingroup\$

Trilangle, 15 bytes

'0.<"@(+>i(^-<!

Test it on the online interpreter!


Roughly equivalent to this C code:

#include <stdio.h>

int main() {
    int total = 0;
    int i;
    while ((i = getchar()) != EOF) {
        total += i - '0';
    }
    printf("%d\n", total);
}

Control flow is kinda weird so it actually calls getchar() a couple times even after EOF is reached.


Unfolds to this:

    '
   0 .
  < " @
 ( + > i
( ^ - < !

With code paths highlighted:

Control flow starts at the north corner heading southwest (on the red path). Instructions are executed as follows:

  • '0: Push a 0 to the stack

  • <: Change the direction of control flow

    (Walk off the edge of the grid and wrap around)

  • i: Get a single character from stdin (-1 on EOF) and push it to the stack

  • >: Branch on the sign of the top of the stack

If the value is positive (any character that isn't EOF), the IP takes the green path:

  • "0: Push the value of the character '0' (i.e. 48) to the stack
  • -: Subtract the two values on top of the stack
  • +: Add the two values on top of the stack
  • <: Redirect control flow, merging with the red path

Once EOF is read, the IP takes the blue path, printing out the stored value... eventually. As you can see from the image it takes the scenic route.

  • -: Subtract the two values on top of the stack. There's now only one value, total - -1 (i.e. total + 1).
  • i: Attempt to read another character from stdin (always sees EOF)
  • <: Redirect control flow
  • - Subtract the two values on top of the stack. Again, there's now only one value: total + 2.
  • ^: Redirect control flow
  • ((: Decrement the top of the stack twice, undoing the effects of i-i-.
  • !: Print the value on top of the stack as a decimal integer
  • i: Another attempt to read stdin, though at this point the values on the stack don't matter
  • @: End program.
\$\endgroup\$
1
  • \$\begingroup\$ And if anyone wants to make a tool like HexagonyColorer so I can make the diagrams look nice instead of hand-drawing them in paint, that'd be appreciated. If not I'll just keep doing them in paint, I don't honestly care enough to make a tool of my own. \$\endgroup\$
    – Bbrk24
    Feb 24 at 23:48
6
\$\begingroup\$

MATL, 3 bytes

!Us

Try it out at MATL Online

Explanation

      % Implicitly read in first input, a 1 x N string
!     % Flip it so that it is N x 1 character array (one character per row)
U     % Convert each row from a string to a number
s     % Sum the resulting N x 1 numeric array
      % Implicitly display the result
\$\endgroup\$
6
\$\begingroup\$

C (gcc), 30 bytes

f(int*s){s=*s?*s-48+f(s+1):0;}

Try it online!

C (clang), 31 bytes

f(*s){return*s?*s-48+f(s+1):0;}

Try it online!

C89, 35 bytes

f(char*s){return*s?*s-48+f(s+1):0;}

Try it online!

\$\endgroup\$
0
5
\$\begingroup\$

05AB1E, 2 bytes

SO

Try it online!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ 2 bytes alternative: (useful if you want to sum the digits of numbers within a list, since is 1 byte less than €SO). :) For this challenge it's just an alternative though. 🤷 \$\endgroup\$ Feb 26 at 18:36
5
\$\begingroup\$

Proton, 14 bytes

digits(10)+sum

Try it online!

digits(x, y) converts y into digits in base x and sum performs sum. Therefore, digits(10) is a partial function that becomes y => digits(10, y) and + sum chains it with sum so an input will be called with digits(10)(...) first, and then the result is called with sum(...).

This is 6 bytes shorter than the straightforward x=>sum(digits(10,x)).

\$\endgroup\$
5
\$\begingroup\$

Python, 24 bytes

lambda n:sum(map(int,n))

Attempt This Online!

Input as a string.

Python, 29 bytes

lambda n:sum(map(int,str(n)))

Attempt This Online!

Input as an integer.

\$\endgroup\$
5
\$\begingroup\$

Excel, 32 31 30 bytes

=SUM(0+(0&MID(A1,ROW(A:A),1)))

Input in cell A1.

Thanks to user117069 and EngineerToast for the two bytes saved.

\$\endgroup\$
4
  • \$\begingroup\$ You might save a byte by summing only up to row 99. The rules only require accepting input up to 10^100, not explicitly including 10^100. \$\endgroup\$
    – user117069
    Feb 26 at 12:29
  • \$\begingroup\$ Ah, ok. I've always interpreted "up to" as "up to and including" when not told otherwise, though your interpretation does make more sense. Thanks a lot, will amend. \$\endgroup\$ Feb 26 at 12:48
  • 1
    \$\begingroup\$ You can save another byte with ROW(A:A). \$\endgroup\$ Feb 27 at 12:27
  • \$\begingroup\$ @EngineerToast Ah, of course! I'd never use that in a real situation due to the inefficiency, but here every byte counts, thanks! \$\endgroup\$ Feb 27 at 14:37
5
\$\begingroup\$

Vyxal 3.0.0-beta.1, 9 bytes

'%%O48-/+

Try it online! (link is to literate version)

Unlike my v2 answer, there is no sum flag, sum built-in, cast to int or cast to string built in in this version of vyxal (because it's a beta release - what do you expect?).

Explained

'%%O48-/+
'%%        ## Format the input as a string
   O48-    ## get the ordinal value of each character and subtract 48 to get the digit value
       /+  ## fold by addition
\$\endgroup\$
4
\$\begingroup\$

Fig, \$1\log_{256}(96)\approx\$ 0.823 bytes

S

Try it online!

Builtin

\$\endgroup\$
2
  • \$\begingroup\$ What's with the logarithm? Did the scoring change? \$\endgroup\$
    – Mark Reed
    Mar 3 at 2:58
  • \$\begingroup\$ @MarkReed Fig uses an irrational byte scoring system, which is allowed \$\endgroup\$
    – Seggan
    Mar 3 at 16:15
4
\$\begingroup\$

Pari/GP, 9 bytes

sumdigits

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Retina 0.8.2, 6 bytes

.
$*
1

Try it online! Link includes test cases. Explanation:

.
$*

Convert each digit to unary.

1

Convert the sum to decimal.

\$\endgroup\$
4
\$\begingroup\$

C (gcc), 29 27 bytes

f(i){i=i%10+(i?f(i/10):0);}

Try it online!

-2 bytes thanks to Giuseppe

Takes input as int.

C's int isn't large enough for the last test case.

The bracket around the ternary is truly awful. Wish I could remove that.

C (gcc), 38 36 bytes (no recursion).

a;f(i){for(a=0;i;i/=10)a+=i%10;a=a;}

Try it online!

-2 bytes thanks to Giuseppe

Takes input as int.

C's int isn't large enough for the last test case.

C (gcc), 56 bytes (no recursion) (outgolfed by c-- using recursion).

a,n;f(char*s){for(a=0,n=strlen(s);n--;++s)a+=*s-48;a=a;}

Takes input as string

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Your first two answers should be able to drop the /1 if I'm not mistaken. \$\endgroup\$
    – Giuseppe
    Feb 26 at 13:10
  • \$\begingroup\$ @Giuseppe yeah, had a brainfart \$\endgroup\$
    – badatgolf
    Feb 26 at 14:12
4
\$\begingroup\$

Typescript Type System + hotscript, 92 87 bytes

import{Pipe,S,T}from"hotscript"
type _<U>=Pipe<U,[S.Split<"">,T.Map<S.ToNumber>,T.Sum]>

I just found out about this library that basically turns the Typescript Type System into a full-on functional programming language and it's amazing

Saved 5 bytes by taking input as a string instead of a number

TS Playground Link

import{Pipe,S,T}from"hotscript"
type _<U>=           // define hotscript lambda with string argument U
Pipe<U,[             // pipe U to:
  S.Split<"">,       //   split on "" (= character list)
  T.Map<S.ToNumber>, //   map each letter to number
  T.Sum              //   sum 
]>                   // end pipe
\$\endgroup\$
2
  • 1
    \$\begingroup\$ you forgot to update the playground link and golfed snippet \$\endgroup\$
    – ASCII-only
    Feb 27 at 6:03
  • \$\begingroup\$ @ASCII-only fixed, thanks \$\endgroup\$
    – Jacob
    Feb 27 at 11:12
3
\$\begingroup\$

Thunno, \$2 \log_{256}(96)\approx\$ 1.646 bytes

dS

Attempt This Online!

d    digits of input
 S   calculate sum
\$\endgroup\$
3
\$\begingroup\$

Perl 5 -p, 19 bytes

s/./$s+=$&/ge;$_=$s

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ s/./$\+=$&/ge}{ for 15 \$\endgroup\$
    – naffetS
    Mar 9 at 1:29
3
\$\begingroup\$

NOTE: Since many/most of the answers seem to ignore the requirement in the question that the input must be taken from stdin and the output must be sent to stdout, I suppose it is reasonable if I do so, too. I think that's a silly and arbitrary requirement, because it makes many languages non-competitive. The standard on Code Golf is to allow functions, and to allow functions taking input via arguments and outputting via their return value(s), so this is what I will follow.

x86-64 Assembly, standard Linux calling convention, 17 bytes

64 31 C0 0F B6 0F E3 09 48 FF C7 8D 44 01 D0 EB F2 C3   

Try it online!

This is a minor, iterative improvement on qwr's answer, which is 18 bytes.

It saves 1 byte by using the relatively-obscure JECXZ instruction (actually JRCXZ, since this is 64-bit mode), which jumps if the value of the rcx register is zero.

It also improves on qwr's original (arguably fixes a bug?) in that it supports the case where the input is an empty string, returning a sum of zero. (To be fair, the challenge doesn't specify whether it is required to handle this, so maybe it cannot be termed a "bug", and, in fact, my next attempt will have this same "bug", so I can hardly ding qwr for taking advantage of it, too!)

SumDigits:
  31 C0         xor    eax, eax
Loop:
  0F B6 0F      movzx  ecx, BYTE PTR [rdi]
  E3 09         jrcxz  End
  48 FF C7      inc    rdi
  8D 44 01 D0   lea    eax, [rcx + rax - '0']
  EB F2         jmp    Loop
End:
  C3            ret    ; result is in eax

x86-64 Assembly, fully custom calling convention, 14 bytes

64 31 C0 31 D2 AC 8D 54 02 D0 38 26 75 F7 C3   

Try it online!

This is a variation on the same theme (it still takes the input as a pointer to the beginning of a NUL-terminated ASCII string), but it pulls out all the stops to really optimize for size:

  • It uses the ultra-compact x86 string instructions. In this case, lods, which loads a byte into al from the address in rsi, and also increments rsi to point to the next byte, using a single-byte encoding.

    • In order to know whether to increment or decrement the source pointer, the rsi instruction implicitly depends on the direction flag (DF). Normally, you'd need to explicitly clear that flag with the cld instruction, but, in this case, since we're running on a *nix-like operating system, per the challenge, we can assume it is already clear. (Also, when you're defining a custom calling convention, the state of the flags can be part of that; see below.)
  • It uses a custom calling convention so that we can (A) take the input string in the rsi register, which is what the lods instruction expects, saving us from having to copy it from one register to another, and (B) build the result in a custom register (edx), freeing up eax to use as a scratch register (because this is what the lods instruction uses as an implicit destination operand).

  • The lods instruction is only loading a single byte, so it only modified the low-order byte of the eax register (al). But the lea instruction that we use to perform multiple arithmetic operations in a single instruction only works on the full 64-bit register, so we need to make sure that the high values are clear. We could do this with an explicit movzx after the lods instruction, but that would consume a lot of bytes. So, instead, we do it once, outside of the loop, with a single xor instruction. This clears the entire rax register, which works because we only ever touch the low-order byte (al).

    • Another neat trick falls out of this: because we don't touch the high-order byte (ah), it's guaranteed to be zero through all iterations of our loop, so we can compare (cmp) the source pointer (string) to ah instead of comparing it to a literal 0, which saves us one byte in the encoding.
SumDigits:
  --          ; cld                           ; can assume DF is always clear on Linux)
  31 C0         xor    eax, eax               ; eax  = 0 (al = 0, ah = 0)
  31 D2         xor    edx, edx               ; edx  = 0 (holds result)
Loop:
  AC            lods                          ; al   = BYTE PTR [rsi]
  8D 54 02 D0   lea    edx, [rdx + rax - '0'] ; edx += (eax - '0')
  38 26         cmp    BYTE PTR [rsi], ah     ; is BYTE PTR [rsi] == ah (which is 0)?
  75 F7         jne    Loop                   ; loop back if not equal (non-zero)
  C3            ret                           ; result is in edx

The custom calling convention is a pretty major "cheat" here, but it's not unusual in the "real world" to use a custom calling convention when writing code in assembly. If you're going to call it from C, you need to take steps to match the standard C calling convention, but who says we're calling it from C?! We don't need no stinkin' C! :-)

\$\endgroup\$
2
  • \$\begingroup\$ Yes, you're right about the stdin/stout requirement, as the challenge author explicitly allowed in the question comments "function declaration" (which I and most interpreted as standard I/O rules) \$\endgroup\$
    – qwr
    Feb 26 at 18:34
  • \$\begingroup\$ I don't think empty string needs to be handled based on the challenge requirement: "given a non-negative integer", which an empty string isn't. Also a fully custom calling convention isn't cheating at all, per the x86 golfing tips page. \$\endgroup\$
    – qwr
    Feb 26 at 18:54
3
\$\begingroup\$

JavaScript (Node.js), 23 bytes

n=>eval([...n].join`+`)

Try it online!

Takes input as a string

JavaScript (Node.js), 26 bytes

n=>eval([...""+n].join`+`)

Try it online!

Takes input as a number, doesn't work if the number is too large for JavaScript to stringify naturally

\$\endgroup\$
1
  • 2
    \$\begingroup\$ I think there's nothing wrong with taking the input as a string, which would save you 3 bytes and allow to support the last test case. \$\endgroup\$
    – Arnauld
    Feb 26 at 10:26
3
\$\begingroup\$

x86-64 Linux assembly, 18 bytes

Lazy C translation. Follows calling convention of System V AMD64 ABI: input null-terminated string in rdi, output in rax.

sum_digits:
        xor     eax, eax            ; sum = 0
L:
        movsx   edx, BYTE [rdi]     ; c = *str
        inc     rdi                 ; ++str
        lea     eax, [rax-48+rdx]   ; sum += c - '0'
        cmp     BYTE [rdi], 0
        jne     L                   ; while (*str)
        ret

Objdump:

0000000000401110 <sum_digits>:
  401110:   31 c0                   xor    eax,eax

0000000000401112 <L>:
  401112:   0f be 17                movsx  edx,BYTE PTR [rdi]
  401115:   48 ff c7                inc    rdi
  401118:   8d 44 10 d0             lea    eax,[rax+rdx*1-0x30]
  40111c:   80 3f 00                cmp    BYTE PTR [rdi],0x0
  40111f:   75 f1                   jne    401112 <L>
  401121:   c3                      ret    
\$\endgroup\$
3
  • \$\begingroup\$ This appears to be 18 bytes, not 16. I think you may have forgotten to count the initial xor instruction outside of the loop? Also, fun fact, this is almost exactly the machine code that GCC will generate for the "obvious" C code when optimizing for size (-Os): Godbolt demo (it swaps the order of the cmp and lea; the advantage of that is unclear, but at least it's not harmful, since the cmp with a memory operand isn't going to be able to macro-fuse with the jne anyway). \$\endgroup\$
    – Cody Gray
    Feb 26 at 13:58
  • \$\begingroup\$ @CodyGray you're right about counting the xor. I think I got confused with a program starting at _start being initialized with zeros in most registers codegolf.stackexchange.com/questions/132981/… \$\endgroup\$
    – qwr
    Feb 26 at 18:44
  • \$\begingroup\$ The comment indexing with i is also misleading too. I started with assembly-like C and cheated by seeing what the compiler generated which is why they're so similar \$\endgroup\$
    – qwr
    Feb 26 at 18:46
2
\$\begingroup\$

Japt -x, 1 byte

ì

Try it

ì gets the digits of the number, the -x flag sums the resulting array

\$\endgroup\$
2
  • \$\begingroup\$ Who downvoted this? Can they explain themselves? \$\endgroup\$
    – Jacob
    Feb 28 at 0:06
  • 1
    \$\begingroup\$ Well, I am going to upvote it @Jacob cz this is one of the best answer. \$\endgroup\$ Feb 28 at 16:00
2
\$\begingroup\$

Arturo, 15 bytes

$=>[∑digits&]

Try it

Even though the question says input and output must be via standard IO, the author of the question said functions are allowed in the comments. So this is a function.

\$\endgroup\$
2
\$\begingroup\$

Charcoal, 3 bytes

IΣN

Try it online! Link is to verbose version of code. Explanation:

  N Input number
 Σ  Sum of digits
I   Cast to string
    Implicitly print
\$\endgroup\$
2
\$\begingroup\$

Standard ML, 43 bytes

(foldl op+ 0)o map(fn x=>ord x-48)o explode

Lack of sum function strikes again

\$\endgroup\$
2
\$\begingroup\$

Ruby, 17 bytes

->x{x.digits.sum}

This defines an anonymous function that accepts a single input (a number), breaks it up into an array of digits, then sums this array and returns the result

\$\endgroup\$
2
\$\begingroup\$

Brachylog, 2 bytes

ẹ+

Try it online!

Explanation

is a pretty disgusting built-in for a declarative logic language, but it’s useful. A "better" alternative would be ∋ᶠ (find all elements) but it’s longer.

ẹ     Split into a list of elements
 +    Sum
\$\endgroup\$
2
\$\begingroup\$

Julia, 12 10 bytes

Tacit Julia strikes again!

sum∘digits

Explanation:

digits: take an integer and return a vector of its digits in base 10 (default)
∘: function composition
sum: sum a collection

Try it online!

-2 thanks to MarcMush

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can remove s= \$\endgroup\$
    – MarcMush
    Mar 5 at 19:22
1
\$\begingroup\$

Factor + math.unicode, 18 bytes

[ >dec 48 v-n Σ ]

Attempt This Online!

  • >dec Convert the input to a string
  • 48 v-n Subtract 48 from each code point
  • Σ Sum
\$\endgroup\$
1
\$\begingroup\$

Ly, 3 bytes

S&+

Try it online!

Breaks STDIN into digits and pushes onto the stack, then uses &+ to sum them. Prints the stack as a number be default when the code exits.

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

Jelly, 2 bytes

DS

Try it online!

D    digits
 S   sum
\$\endgroup\$
1
\$\begingroup\$

Pip, 3 bytes

$+a

Attempt This Online!

$+    sum of
      (the digits of)
  a   the input
\$\endgroup\$

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.