12
\$\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\$
7
  • 4
    \$\begingroup\$ I have a feeling this is a duplicate... \$\endgroup\$
    – Seggan
    Feb 24 at 23:04
  • 3
    \$\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
  • 2
    \$\begingroup\$ Congrats on finding a non duplicate challenge which can have an answer of 0 bytes \$\endgroup\$
    – Surb
    Feb 26 at 20:40
  • 3
    \$\begingroup\$ @Surb 1 2 3 4 5 6 7 ... there's plenty more \$\endgroup\$
    – naffetS
    Mar 9 at 1:33

71 Answers 71

11
\$\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
9
\$\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
8
\$\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\$
4
  • \$\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
  • \$\begingroup\$ Make an answer that also optimises your hard drive to save memory \$\endgroup\$ May 19 at 11:40
  • \$\begingroup\$ @AitzazImtiaz FYI, it's discouraged to accept answers on CGCC. Answers aren't all competing with each other, they're competing within languages, so there's no one winner per se. An accepted answer might also discourage more answers to your question. I'd suggest unaccepting this answer. \$\endgroup\$
    – user
    Aug 4 at 19:36
7
\$\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
7
\$\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
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\$

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\$

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\$

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\$
5
\$\begingroup\$

C (gcc), 29 27 25 bytes

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

Try it online!

-2 bytes thanks to Giuseppe

-2 bytes thanks to c--

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. Thanks c-- again.

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\$
3
  • 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
  • \$\begingroup\$ you can reorder the first expression to remove the parentheses: 25 bytes \$\endgroup\$
    – c--
    May 14 at 20:54
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\$

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\$
    – noodle man
    Feb 27 at 11:12
4
\$\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
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\$

JavaScript (Node.js), 22 bytes

f=n=>n&&n%10+f(n/10|0)

Try it online!


JavaScript (Node.js), 21 bytes

f=n=>n&&n*9%9-f(n/~9)

Try it online!

It is shorter, but with floating point errors...

\$\endgroup\$
4
  • \$\begingroup\$ IMO the output of 2 for the input 3141592653589793238462643383279502884197169399375105820974944592 is slightly more than a simple "floating point error" :P \$\endgroup\$
    – Kaddath
    Feb 27 at 11:13
  • \$\begingroup\$ @Kaddath that is floating point errors. The input number is too large. A difference of 300 is much smaller compared with the input number. \$\endgroup\$
    – tsh
    Feb 27 at 12:34
  • \$\begingroup\$ Yes I was just joking, my attempt with PHP gave 78, it depends on your max int value I guess, anyway most answers just ignored the 10^100 integer rule and take the input as a string \$\endgroup\$
    – Kaddath
    Feb 27 at 14:35
  • \$\begingroup\$ This is the most beautiful thing I have ready today. Thank you! \$\endgroup\$
    – PuercoPop
    Apr 5 at 3:18
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\$ 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
3
\$\begingroup\$

Raku, 19 16 bytes

say [+] get.comb

Try it online!

get(): gets a single line from stdin (parens not required)

`.univals()`: maps a string of numerical unicode chars to a list of their values. I'm just using it in place of `.split("")`, which would be 2 bytes longer.

.comb: splits out to list of characters (thanks @Mark Reed)

[+]: reduces the list by addition.

say: writes to stdout

\$\endgroup\$
4
  • \$\begingroup\$ You don't need split in Raku anyway; just use get.comb. \$\endgroup\$
    – Mark Reed
    Mar 3 at 3:00
  • \$\begingroup\$ @MarkReed Thanks, edited to add that. I saw .combs documentation, but I didn't notice there was a nullary version. \$\endgroup\$ Mar 3 at 16:10
  • \$\begingroup\$ Welcome to Code Golf, and nice first answer! \$\endgroup\$
    – The Thonnu
    Mar 10 at 20:00
  • \$\begingroup\$ Fun tips, .sum is the same size as [+], so this could be get.comb.sum.say for the same amount of bytes, or *.comb.sum.say in function form \$\endgroup\$
    – Jo King
    May 18 at 0:38
3
\$\begingroup\$

Pascal, 114 bytes

This is a full program according to ISO standard 7185 “Standard Pascal”. The built-in data type integer comprises (at least) all integral values in the range −maxInt..maxInt. The value of maxInt is implementation-defined. In order to successfully test values up to and including one googol you will need a processor (this refers to the specific combination of machine, compiler, OS, etc.) defining maxInt ≥ 10100.

program p(input,output);var x,y:integer;begin y:=0;read(x);repeat y:=y+x mod 10;x:=x div 10 until x=0;write(y)end.

Ungolfed:

program digitSum(input, output);
    var
        x, digitSum: integer;
    begin
        digitSum := 0;
        read(x);
        
        repeat
        begin
            digitSum := digitSum + x mod 10;
            x := x div 10;
        end
        until x = 0;
        
        write(digitSum);
    end.

Because in Pascal mod is defined to always yield a non-negative result, digitSum works incorrectly for negative inputs. Injecting an x := abs(x); prior the loop will resolve this issue.


Another method is of course to process characters. In Pascal it is guaranteed that the characters '0' through '9' are in ascending order and consecutive, thus ord('9') − ord('0') is guaranteed to yield the integer value 9.

program p(input,output);var x:integer;begin x:=0;while not EOF do begin x:=x+ord(input^)-ord('0');get(input)end;write(x)end.

Input must not be followed by a newline, or replace the EOF by EOLn. This program is ≥ 124 bytes

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

bc, 35 bytes

for(;i<length(a);i++)b+=a/10^i%10;b

Try it online!

Using the default scale=0 i.e. no decimals, divide by 1,10,100,... successively (a/10^i), and %10 to add only the last digit to b. When the for loop finishes, print the sum. ;b

\$\endgroup\$
3
\$\begingroup\$

K (ngn/k), 5 bytes

+/10\

Try it online!

\$\endgroup\$
3
\$\begingroup\$

APL, 5 bytes

+/⍎¨⍞

Explanation:

  • reads standard input as a character vector
  • ⍎¨ converts each digit to its numeric value
  • +/ computes the sum

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ You need instead of . Try it online! \$\endgroup\$
    – Adám
    Apr 5 at 6:25
  • \$\begingroup\$ I was assuming the usual conventions where "take as input" could be arguments to a function instead of literal I/O. \$\endgroup\$
    – Mark Reed
    Apr 5 at 14:48
  • \$\begingroup\$ It does say Your program should take input from standard input (stdin) and output the result to standard output (stdout). but even if your solution is taken as a function, it'd not work, as it'd be a 3-train, and equivalent to {(+/⍵)⍎¨(⍕⍵)} and even if taken as a snippet (which isn't allowed per site rules), it'd fail on large numbers due to precision. \$\endgroup\$
    – Adám
    Apr 5 at 16:46
3
\$\begingroup\$

Javascript, 42 bytes

This new and improved version supports BigInt, as well as numbers and strings. It uses tsh's idea, but it first changes the type and uses the ES10 BigInt. (It also happens to be the shortest I could come up with!)

a=n=>eval("x=BigInt(n);x&&x%10n+a(x/10n)")

I also tried playing around and created these functions:

// BigInt/String/Number
b=n=>eval("l=0;(n+[]).split('').forEach(t=>l+=+t);l")
// String only
c=n=>eval("l=0;n.split('').forEach(t=>l+=+t);l")
// BigInt only
d=n=>n&&n%10n+d(n/10n)
// String/Number
e=n=>+n&&+n%10+e(+n/10|0)

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

PowerShell, 39 bytes

param([string]$i)($i|% t*y)-join"+"|iex

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Rust, 54 47 30 bytes

|n|n.map(|b|b as u64-48).sum()

A function that takes a std::str::Bytes and returns a u64. For the purpose of this challenge, I consider std::str::Bytes to be an iterator of ASCII-characters, which meets our general criteria for a string.

Previous versions:

|mut n|{let mut s=0;while n>0{s+=n%10;n/=10;}s}
|n|n.to_string().bytes().map(|d|u64::from(d)-48).sum()
\$\endgroup\$
3
  • \$\begingroup\$ -5 bytes \$\endgroup\$
    – JSorngard
    Apr 6 at 12:54
  • \$\begingroup\$ Here's one using only 34 bytes, but it can feel a bit like cheating. \$\endgroup\$
    – JSorngard
    Apr 6 at 13:00
  • \$\begingroup\$ @JSorngard Thanks. I think choosing the correct input and output types is an important part of solving a challenge, especially for Rust. \$\endgroup\$
    – corvus_192
    Apr 7 at 10:02
3
\$\begingroup\$

Leaf-Lang, 95 bytes

macro p pop pop end""input splitString 0:s""=0=while p p toNumber s+:s""=0=stop p p 1p s print

Explaination

Leaf Lang is a lang I made in my free time in college. It is a stack-based programming language. It can be hard to understand, so I wrote a step-by-step golf of my solution.

The readable solution

"" input splitString # split input into array of strings
0 : sum              # sum = 0
"" = 0 =             # loop condition
while
        pop pop pop pop      # clean stack of condition
        toNumber sum + : sum # sum = sum + toNumber
        "" = 0 =             # loop condition
stop

pop pop pop pop # clean stack of condition
pop             # clean stack of stop condition

sum # add sum to stack
print

Compressed readable solution, 109 bytes

""input splitString 0:sum""=0=while pop pop pop pop toNumber sum+:sum""=0=stop pop pop pop pop pop sum print

Macro optimization #1, 98 bytes

macro p pop end""input splitString 0:s""=0=while p p p p toNumber s+:s""=0=stop p p p p p s print

This uses a macro to shorten the long chains of pop calls.

Macro optimization #2, 96 bytes

macro p pop pop end""input splitString 0:s""=0=while p p toNumber s+:s""=0=stop p p pop s print

The final golf code, 95 bytes

macro p pop pop end""input splitString 0:s""=0=while p p toNumber s+:s""=0=stop p p 1p s print

The final code abuses my parser to push a 1 to the stack then call the p macro to essentially make a single pop call.

\$\endgroup\$

Your Answer

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

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