Sum digits of an integer

From Rosetta Code
Jump to: navigation, search
Task
Sum digits of an integer
You are encouraged to solve this task according to the task description, using any language you may know.

This task is to take a Natural Number   [[1]]   in a given Base and return the sum of its digits:

110 sums to 1;
123410 sums to 10;
fe16 sums to 29;
f0e16 sums to 29.

Contents

[edit] Ada

Numeric constants in Ada are either decimal or written as B#Digits#. Here B is the base, written as a decimal number, and Digits is a base-B number. E.g., 30, 10#30# 2#11110#, and 16#1E# are the same number -- either written in decimal, binary or hexadecimal notation.

with Ada.Integer_Text_IO;
 
procedure Sum_Digits is
-- sums the digits of an integer (in whatever base)
-- outputs the sum (in base 10)
 
function Sum_Of_Digits(N: Natural; Base: Natural := 10) return Natural is
Sum: Natural := 0;
Val: Natural := N;
begin
while Val > 0 loop
Sum := Sum + (Val mod Base);
Val := Val / Base;
end loop;
return Sum;
end Sum_Of_Digits;
 
use Ada.Integer_Text_IO;
 
begin -- main procedure Sum_Digits
Put(Sum_OF_Digits(1)); -- 1
Put(Sum_OF_Digits(12345)); -- 15
Put(Sum_OF_Digits(123045)); -- 15
Put(Sum_OF_Digits(123045, 50)); -- 104
Put(Sum_OF_Digits(16#fe#, 10)); -- 11
Put(Sum_OF_Digits(16#fe#, 16)); -- 29
Put(Sum_OF_Digits(16#f0e#, 16)); -- 29
end Sum_Digits;
Output:
          1         15         15        104         11         29         29

[edit] AutoHotkey

Translated from the C version.

MsgBox % sprintf("%d %d %d %d %d`n"
,SumDigits(1, 10)
,SumDigits(12345, 10)
,SumDigits(123045, 10)
,SumDigits(0xfe, 16)
,SumDigits(0xf0e, 16) )
 
SumDigits(n,base) {
sum := 0
while (n)
{
sum += Mod(n,base)
n /= base
}
return sum
}
 
sprintf(s,fmt*) {
for each, f in fmt
StringReplace,s,s,`%d, % f
return s
}

Output:

1 15 15 29 29

[edit] AWK

MAWK only support base 10 numeric constants, so a conversion function is necessary.

Will sum digits in numbers from base 2 to base 16.

The output is in decimal. Output in other bases would require a function to do the conversion because MAWK's printf() does not support bases other than 10.

Other versions of AWK may not have these limitations.

#!/usr/bin/awk -f
 
BEGIN {
print sumDigits("1")
print sumDigits("12")
print sumDigits("fe")
print sumDigits("f0e")
}
 
function sumDigits(num, nDigs, digits, sum, d, dig, val, sum) {
nDigs = split(num, digits, "")
sum = 0
for (d = 1; d <= nDigs; d++) {
dig = digits[d]
val = digToDec(dig)
sum += val
}
return sum
}
 
function digToDec(dig) {
return index("0123456789abcdef", tolower(dig)) - 1
}
 

Example output:

1
3
29
29

[edit] BASIC

Works with: QBasic
Works with: PowerBASIC
Translation of: Visual Basic

Note that in order for this to work with the Windows versions of PowerBASIC, the test code needs to be with FUNCTION PBMAIN.

FUNCTION sumDigits(num AS STRING, bas AS LONG) AS LONG
'can handle up to base 36
DIM outp AS LONG
DIM validNums AS STRING, tmp AS LONG, x AS LONG, lennum AS LONG, L0 AS LONG
'ensure num contains only valid characters
validNums = LEFT$("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", bas)
lennum = LEN(num)
FOR L0 = lennum TO 1 STEP -1
x = INSTR(validNums, MID$(num, L0, 1)) - 1
IF -1 = x THEN EXIT FUNCTION
tmp = tmp + (x * (bas ^ (lennum - L0)))
NEXT
WHILE tmp
outp = outp + (tmp MOD bas)
tmp = tmp \ bas
WEND
sumDigits = outp
END FUNCTION
 
PRINT sumDigits(LTRIM$(STR$(1)), 10)
PRINT sumDigits(LTRIM$(STR$(1234)), 10)
PRINT sumDigits(LTRIM$(STR$(&HFE)), 16)
PRINT sumDigits(LTRIM$(STR$(&HF0E)), 16)
PRINT sumDigits("2", 2)

Output:

1
10
11
20
0

See also: BBC BASIC, Run BASIC, Visual Basic

[edit] Applesoft BASIC

10 BASE = 10
20 N$ = "1" : GOSUB 100 : PRINT N
30 N$ = "1234" : GOSUB 100 : PRINT N
40 BASE = 16
50 N$ = "FE" : GOSUB 100 : PRINT N
60 N$ = "F0E" : GOSUB 100 : PRINT N
90 END
 
100 REM SUM DIGITS OF N$, BASE
110 IF BASE = 1 THEN N = LEN(N$) : RETURN
120 IF BASE < 2 THEN BASE = 10
130 N = 0 : V$ = LEFT$("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", BASE)
140 FOR I = 1 TO LEN(N$) : C$ = MID$(N$, I, 1)
150 FOR J = 1 TO LEN(V$)
160 IF C$ <> MID$(V$, J, 1) THEN NEXT J : N = SQR(-1) : STOP
170 N = N + J - 1
180 NEXT I
190 RETURN

[edit] BBC BASIC

This solution deliberately avoids MOD and DIV so it is not restricted to 32-bit integers.

      *FLOAT64
PRINT "Digit sum of 1 (base 10) is "; FNdigitsum(1, 10)
PRINT "Digit sum of 12345 (base 10) is "; FNdigitsum(12345, 10)
PRINT "Digit sum of 9876543210 (base 10) is "; FNdigitsum(9876543210, 10)
PRINT "Digit sum of FE (base 16) is "; ~FNdigitsum(&FE, 16) " (base 16)"
PRINT "Digit sum of F0E (base 16) is "; ~FNdigitsum(&F0E, 16) " (base 16)"
END
 
DEF FNdigitsum(n, b)
LOCAL q, s
WHILE n <> 0
q = INT(n / b)
s += n - q * b
n = q
ENDWHILE
= s

Output:

Digit sum of 1 (base 10) is 1
Digit sum of 12345 (base 10) is 15
Digit sum of 9876543210 (base 10) is 45
Digit sum of FE (base 16) is 1D (base 16)
Digit sum of F0E (base 16) is 1D (base 16)

[edit] bc

define s(n) {
auto i, o, s
 
o = scale
scale = 0
 
for (i = n; i > 0; i /= ibase) {
s += i % ibase
}
 
scale = o
return(s)
}
 
ibase = 10
s(1)
s(1234)
ibase = 16
s(FE)
s(F0E)
Output:
1
10
29
29

[edit] C

#include <stdio.h>
 
int SumDigits(unsigned long long n, const int base) {
int sum = 0;
for (; n; n /= base)
sum += n % base;
return sum;
}
 
int main() {
printf("%d %d %d %d %d\n",
SumDigits(1, 10),
SumDigits(12345, 10),
SumDigits(123045, 10),
SumDigits(0xfe, 16),
SumDigits(0xf0e, 16) );
return 0;
}
Output:
1 15 15 29 29

[edit] C#

namespace RosettaCode.SumDigitsOfAnInteger
{
using System;
using System.Collections.Generic;
using System.Linq;
 
internal static class Program
{
/// <summary>
/// Enumerates the digits of a number in a given base.
/// </summary>
/// <param name="number"> The number. </param>
/// <param name="base"> The base. </param>
/// <returns> The digits of the number in the given base. </returns>
/// <remarks>
/// The digits are enumerated from least to most significant.
/// </remarks>
private static IEnumerable<int> Digits(this int number, int @base = 10)
{
while (number != 0)
{
int digit;
number = Math.DivRem(number, @base, out digit);
yield return digit;
}
}
 
/// <summary>
/// Sums the digits of a number in a given base.
/// </summary>
/// <param name="number"> The number. </param>
/// <param name="base"> The base. </param>
/// <returns> The sum of the digits of the number in the given base. </returns>
private static int SumOfDigits(this int number, int @base = 10)
{
return number.Digits(@base).Sum();
}
 
/// <summary>
/// Demonstrates <see cref="SumOfDigits" />.
/// </summary>
private static void Main()
{
foreach (var example in
new[]
{
new {Number = 1, Base = 10},
new {Number = 12345, Base = 10},
new {Number = 123045, Base = 10},
new {Number = 0xfe, Base = 0x10},
new {Number = 0xf0e, Base = 0x10}
})
{
Console.WriteLine(example.Number.SumOfDigits(example.Base));
}
}
}
}

Output:

1
15
15
29
29

[edit] C++

#include <iostream>
#include <cmath>
int SumDigits(const unsigned long long int digits, const int BASE = 10) {
int sum = 0;
unsigned long long int x = digits;
for (int i = log(digits)/log(BASE); i>0; i--){
const double z = std::pow(BASE,i);
const unsigned long long int t = x/z;
sum += t;
x -= t*z;
}
return x+sum;
}
 
int main() {
std::cout << SumDigits(1) << ' '
<< SumDigits(12345) << ' '
<< SumDigits(123045) << ' '
<< SumDigits(0xfe, 16) << ' '
<< SumDigits(0xf0e, 16) << std::endl;
return 0;
}
Output:
1 15 15 29 29

[edit] Template metaprogramming version

Tested with g++-4.6.3 (Ubuntu).

 
// Template Metaprogramming version by Martin Ettl
#include <iostream>
#include <cmath>
 
typedef unsigned long long int T;
template <typename T, T i> void For(T &sum, T &x, const T &BASE)
{
const double z(std::pow(BASE,i));
const T t = x/z;
sum += t;
x -= t*z;
For<T, i-1>(sum,x,BASE);
}
template <> void For<T,0>(T &, T &, const T &){}
 
template <typename T, T digits, int BASE> T SumDigits()
{
T sum(0);
T x(digits);
const T end(log(digits)/log(BASE));
For<T,end>(sum,x,BASE);
return x+sum;
}
 
int main()
{
std::cout << SumDigits<T, 1 , 10>() << ' '
<< SumDigits<T, 12345 , 10>() << ' '
<< SumDigits<T, 123045, 10>() << ' '
<< SumDigits<T, 0xfe , 16>() << ' '
<< SumDigits<T, 0xf0e , 16>() << std::endl;
return 0;
}
 
Output:
1 15 15 29 29

[edit] Common Lisp

(defun sum-digits (number base)
(loop for n = number then q
for (q r) = (multiple-value-list (truncate n base))
sum r until (zerop q)))

Example:

(loop for (number base) in '((1 10) (1234 10) (#xfe 16) (#xf0e 16))
do (format t "(~a)_~a = ~a~%" number base (sum-digits number base)))
Output:
(1)_10 = 1
(1234)_10 = 10
(254)_16 = 29
(3854)_16 = 29

[edit] D

import std.stdio, std.bigint;
 
uint sumDigits(T)(T n, in uint base=10) pure /*nothrow*/
in {
assert(base > 1);
} body {
typeof(return) total = 0;
for ( ; n; n /= base)
total += n % base;
return total;
}
 
void main() {
1.sumDigits.writeln;
1_234.sumDigits.writeln;
sumDigits(0xfe, 16).writeln;
sumDigits(0xf0e, 16).writeln;
1_234.BigInt.sumDigits.writeln;
}
Output:
1
10
29
29
10

[edit] Erlang

 
-module(sum_digits).
-export([sum_digits/2, sum_digits/1]).
 
sum_digits(N) ->
sum_digits(N,10).
 
sum_digits(N,B) ->
sum_digits(N,B,0).
 
sum_digits(0,_,Acc) ->
Acc;
sum_digits(N,B,Acc) when N < B ->
Acc+N;
sum_digits(N,B,Acc) ->
sum_digits(N div B, B, Acc + (N rem B)).
 

Example usage:

2> sum_digits:sum_digits(1).
1
3> sum_digits:sum_digits(1234).
10
4> sum_digits:sum_digits(16#fe,16).
29
5> sum_digits:sum_digits(16#f0e,16).
29

[edit] Ezhil

 
# இது ஒரு எழில் தமிழ் நிரலாக்க மொழி உதாரணம்
 
# sum of digits of a number
# எண்ணிக்கையிலான இலக்கங்களின் தொகை
 
நிரல்பாகம் எண்_கூட்டல்( எண் )
தொகை = 0
@( எண் > 0 ) வரை
d = எண்%10;
பதிப்பி "digit = ",d
எண் = (எண்-d)/10;
தொகை = தொகை + d
முடி
பின்கொடு தொகை
முடி
 
 
பதிப்பி எண்_கூட்டல்( 1289)#20
பதிப்பி எண்_கூட்டல்( 123456789)# 45
 

[edit] F#

open System
 
let digsum b n =
let rec loop acc = function
| n when n > 0 ->
let m, r = Math.DivRem(n, b)
loop (acc + r) m
| _ -> acc
loop 0 n
 
[<EntryPoint>]
let main argv =
let rec show = function
| n :: b :: r -> printf " %d" (digsum b n); show r
| _ -> ()
 
show [1; 10; 1234; 10; 0xFE; 16; 0xF0E; 16] // -> 1 10 29 29
0

[edit] Forth

This is an easy task for Forth, that has built in support for radices up to 36. You set the radix by storing the value in variable BASE.

: sum_int 0 begin over while swap base @ /mod swap rot + repeat nip ;
 
2 base ! 11110 sum_int decimal . cr
10 base ! 12345 sum_int decimal . cr
16 base ! f0e sum_int decimal . cr

[edit] Fortran

Please find GNU/linux compilation instructions along with the sample output within the comments at the start of this FORTRAN 2008 source. Thank you. Review of this page shows a solution to this task with the number input as text. The solution is the sum of index positions in an ordered list of digit characters. (awk). Other solutions ignore the representations of the input, encode digits using the base, then sum the encoding. Both methods appear in this implementation.

 
!-*- mode: compilation; default-directory: "/tmp/" -*-
!Compilation started at Fri Jun 7 21:00:12
!
!a=./f && make $a && $a
!gfortran -std=f2008 -Wall -fopenmp -ffree-form -fall-intrinsics -fimplicit-none f.f08 -o f
!f.f08:57.29:
!
! subroutine process1(fmt,s,b)
! 1
!Warning: Unused dummy argument 'b' at (1)
!digit sum n
! 1 1
! 10 1234
! 29 fe
! 29 f0e
! sum of digits of n expressed in base is...
! n base sum
! 1 10 1
! 1234 10 10
! 254 16 29
! 3854 16 29
!
!Compilation finished at Fri Jun 7 21:00:12
 
module base_mod
private :: reverse
contains
subroutine reverse(a)
integer, dimension(:), intent(inout) :: a
integer :: i, j, t
do i=1,size(a)/2
j = size(a) - i + 1
t = a(i)
a(i) = a(j)
a(j) = t
end do
end subroutine reverse
 
function antibase(b, n) result(a)
integer, intent(in) :: b,n
integer, dimension(32) :: a
integer :: m, i
a = 0
m = n
i = 1
do while (m .ne. 0)
a(i) = mod(m, b)
m = m/b
i = i+1
end do
call reverse(a)
end function antibase
end module base_mod
 
program digit_sum
use base_mod
call still
call confused
contains
subroutine still
character(len=6),parameter :: fmt = '(i9,a)'
print'(a9,a8)','digit sum','n'
call process1(fmt,'1',10)
call process1(fmt,'1234',10)
call process1(fmt,'fe',16)
call process1(fmt,'f0e',16)
end subroutine still
 
subroutine process1(fmt,s,b)
character(len=*), intent(in) :: fmt, s
integer, intent(in), optional :: b
integer :: i
print fmt,sum((/(index('123456789abcdef',s(i:i)),i=1,len(s))/)),' '//s
end subroutine process1
 
subroutine confused
character(len=5),parameter :: fmt = '(3i7)'
print*,'sum of digits of n expressed in base is...'
print'(3a7)','n','base','sum'
call process0(10,1,fmt)
call process0(10,1234,fmt)
call process0(16,254,fmt)
call process0(16,3854,fmt)
end subroutine confused
 
subroutine process0(b,n,fmt)
integer, intent(in) :: b, n
character(len=*), intent(in) :: fmt
print fmt,n,b,sum(antibase(b, n))
end subroutine process0
end program digit_sum
 

[edit] Go

Handling numbers up to 2^63 and bases from 2 to 36 is pretty easy.

package digit
 
import (
"errors"
"strconv"
)
 
func Sum(n string, base int) (int64, error) {
if base < 2 || base > 36 {
return 0, errors.New("base must be from 2 to 36")
}
i, err := strconv.ParseInt(n, base, 64)
if err != nil {
return 0, err
}
if i < 0 {
return 0, errors.New("number must be non-negative")
}
b64 := int64(base)
var sum int64
for i > 0 {
sum += i % b64
i /= b64
}
return sum, nil
}
package digit_test
 
import (
"testing"
 
"digit"
)
 
type testCase struct {
n string
base int
dSum int64
}
 
var testData = []testCase{
{"1", 10, 1},
{"1234", 10, 10},
{"fe", 16, 29},
{"f0e", 16, 29},
}
 
func testSum(t *testing.T) {
for _, tc := range testData {
ds, err := digit.Sum(tc.n, tc.base)
if err != nil {
t.Fatal("test case", tc, err)
}
if ds != tc.dSum {
t.Fatal("test case", tc, "got", ds, "expected", tc.dSum)
}
}
}

[edit] Groovy

Solution:

def digitsum = { number, radix = 10 ->
Integer.toString(number, radix).collect { Integer.parseInt(it, radix) }.sum()
}

Test:

[[30, 2], [30, 10], [1, 10], [12345, 10], [123405, 10], [0xfe, 16], [0xf0e, 16]].each {
println """
Decimal value: ${it[0]}
Radix: ${it[1]}
Radix value: ${Integer.toString(it[0], it[1])}
Decimal Digit Sum: ${digitsum(it[0], it[1])}
Radix Digit Sum: ${Integer.toString(digitsum(it[0], it[1]), it[1])}
"""

}

Output:

    Decimal value:     30
    Radix:             2
    Radix value:       11110
    Decimal Digit Sum: 4
    Radix Digit Sum:   100
    

    Decimal value:     30
    Radix:             10
    Radix value:       30
    Decimal Digit Sum: 3
    Radix Digit Sum:   3
    

    Decimal value:     1
    Radix:             10
    Radix value:       1
    Decimal Digit Sum: 1
    Radix Digit Sum:   1
    

    Decimal value:     12345
    Radix:             10
    Radix value:       12345
    Decimal Digit Sum: 15
    Radix Digit Sum:   15
    

    Decimal value:     123405
    Radix:             10
    Radix value:       123405
    Decimal Digit Sum: 15
    Radix Digit Sum:   15
    

    Decimal value:     254
    Radix:             16
    Radix value:       fe
    Decimal Digit Sum: 29
    Radix Digit Sum:   1d
    

    Decimal value:     3854
    Radix:             16
    Radix value:       f0e
    Decimal Digit Sum: 29
    Radix Digit Sum:   1d

[edit] Haskell

digsum base = f 0 where
f a 0 = a
f a n = f (a+r) q where
(q,r) = n `divMod` base
 
main = print $ digsum 16 255 -- "FF": 15 + 15 = 30

[edit] Icon and Unicon

This solution works in both languages. This solution assumes the input number is expressed in the indicated base. This assumption differs from that made in some of the other solutions.

procedure main(a)
write(dsum(a[1]|1234,a[2]|10))
end
 
procedure dsum(n,b)
n := integer((\b|10)||"r"||n)
sum := 0
while sum +:= (0 < n) % b do n /:= b
return sum
end

Sample runs:

->sdi 1
1
->sdi 1234
10
->sdi fe 16
29
->sdi f0e 16
29
->sdi ff 16
30
->sdi 255 16
12
->sdi fffff 16
75
->sdi 254 16
11
->

[edit] J

digsum=: 10&$: : (+/@(#.inv))

Example use:

   digsum 1234
10
10 digsum 254
11
16 digsum 254
29

Illustration of mechanics:

   10 #. 1 2 3 4
1234
10 #.inv 1234
1 2 3 4
10 +/ 1 2 3 4
10
10 +/@(#.inv) 1234
10

So #.inv gives us the digits, +/ gives us the sum, and @ glues them together with +/ being a "post processor" for #.inv or, as we say in the expression: (#.inv). We need the parenthesis or inv will try to look up the inverse of +/@#. and that's not well defined.

The rest of it is about using 10 as the default left argument when no left argument is defined. A J verb has a monadic definition (for use with one argument) and a dyadic definition (for use with two arguments) and : derives a new verb where the monadic definition is used from the verb on the left and the dyadic definition is used from the verb on the right. $: is a self reference to the top-level defined verb.

Full examples:

   digsum 1
1
digsum 1234
10
16 digsum 16bfe
29
16 digsum 16bf0e
29

Note that J implements numeric types -- J tries to ensure that the semantics of numbers match their mathematical properties. So it doesn't matter how we originally obtained a number.

   200+54
254
254
254
2.54e2
254
16bfe
254
254b10 , 1r254b0.1 NB. 10 in base 254 , 0.1 in base 1/254
254 254

[edit] Java

import java.math.BigInteger;
public class SumDigits {
public static int sumDigits(long num) {
return sumDigits(num, 10);
}
public static int sumDigits(long num, int base) {
String s = Long.toString(num, base);
int result = 0;
for (int i = 0; i < s.length(); i++)
result += Character.digit(s.charAt(i), base);
return result;
}
public static int sumDigits(BigInteger num) {
return sumDigits(num, 10);
}
public static int sumDigits(BigInteger num, int base) {
String s = num.toString(base);
int result = 0;
for (int i = 0; i < s.length(); i++)
result += Character.digit(s.charAt(i), base);
return result;
}
 
public static void main(String[] args) {
System.out.println(sumDigits(1));
System.out.println(sumDigits(12345));
System.out.println(sumDigits(123045));
System.out.println(sumDigits(0xfe, 16));
System.out.println(sumDigits(0xf0e, 16));
System.out.println(sumDigits(new BigInteger("12345678901234567890")));
}
}
Output:
1
15
15
29
29
90


[edit] Julia

Using the built-in digits function:

sumdigits(n, base=10) = sum(digits(n, base))

[edit] Lasso

define br => '<br />\n'
 
define sumdigits(int, base = 10) => {
fail_if(#base < 2, -1, 'Base need to be at least 2')
local(
out = integer,
divmod
)
while(#int) => {
#divmod = #int -> div(#base)
#int = #divmod -> first
#out += #divmod -> second
}
return #out
}
 
sumdigits(1)
br
sumdigits(12345)
br
sumdigits(123045)
br
sumdigits(0xfe, 16)
br
sumdigits(0xf0e, 16)

Output:

1
15
15
29
29

[edit] Mathematica

Total[IntegerDigits[1234]]
Total[IntegerDigits[16^^FE, 16]]
Output:
10
29

[edit] МК-61/52

П0	<->	П1	Сx	П2	ИП1	^	ИП0	/	[x]
П3 ИП0 * - ИП2 + П2 ИП3 П1 x=0
05 ИП2 С/П

[edit] NetRexx

[edit] Strings

Processes data as text from the command line. Provides a representative sample if no input is supplied:

/* NetRexx */
options replace format comments java crossref symbols nobinary
 
parse arg input
inputs = ['1234', '01234', '0xfe', '0xf0e', '0', '00', '0,2' '1', '070', '77, 8' '0xf0e, 10', '070, 16', '0xf0e, 36', '000999ABCXYZ, 36', 'ff, 16', 'f, 10', 'z, 37'] -- test data
if input.length() > 0 then inputs = [input] -- replace test data with user input
loop i_ = 0 to inputs.length - 1
in = inputs[i_]
parse in val . ',' base .
dSum = sumDigits(val, base)
say 'Sum of digits for integer "'val'" for a given base of "'base'":' dSum'\-'
-- Carry the exercise to it's logical conclusion and sum the results to give a single digit in range 0-9
loop while dSum.length() > 1 & dSum.datatype('n')
dSum = sumDigits(dSum, 10)
say ',' dSum'\-'
end
say
end i_
 
-- Sum digits of an integer
method sumDigits(val = Rexx, base = Rexx '') public static returns Rexx
 
rVal = 0
parse normalizeValue(val, base) val base .
loop label digs for val.length()
-- loop to extract digits from input and sum them
parse val dv +1 val
do
rVal = rVal + Integer.valueOf(dv.toString(), base).intValue()
catch ex = NumberFormatException
rVal = 'NumberFormatException:' ex.getMessage()
leave digs
end
end digs
return rVal
 
-- Clean up the input, normalize the data and determine which base to use
method normalizeValue(inV = Rexx, base = Rexx '') private static returns Rexx
inV = inV.strip('l')
base = base.strip()
parse inV xpref +2 . -
=0 opref +1 . -
=0 . '0x' xval . ',' . -
=0 . '0' oval . ',' . -
=0 dval .
 
select
when xpref = '0x' & base.length() = 0 then do
-- value starts with '0x' and no base supplied. Assign hex as base
inval = xval
base = 16
end
when opref = '0' & base.length() = 0 then do
-- value starts with '0' and no base supplied. Assign octal as base
inval = oval
base = 8
end
otherwise do
inval = dval
end
end
if base.length() = 0 then base = 10 -- base not set. Assign decimal as base
if inval.length() <= 0 then inval = 0 -- boundary condition. Invalid input or a single zero
rVal = inval base
 
return rVal
 

Output

Sum of digits for integer "1234" for a given base of "": 10, 1
Sum of digits for integer "01234" for a given base of "": 10, 1
Sum of digits for integer "0xfe" for a given base of "": 29, 11, 2
Sum of digits for integer "0xf0e" for a given base of "": 29, 11, 2
Sum of digits for integer "0" for a given base of "": 0
Sum of digits for integer "00" for a given base of "": 0
Sum of digits for integer "0" for a given base of "2": 0
Sum of digits for integer "070" for a given base of "": 7
Sum of digits for integer "77" for a given base of "8": 14, 5
Sum of digits for integer "070" for a given base of "16": 7
Sum of digits for integer "0xf0e" for a given base of "36": 62, 8
Sum of digits for integer "000999ABCXYZ" for a given base of "36": 162, 9
Sum of digits for integer "ff" for a given base of "16": 30, 3
Sum of digits for integer "f" for a given base of "10": NumberFormatException: For input string: "f"
Sum of digits for integer "z" for a given base of "37": NumberFormatException: radix 37 greater than Character.MAX_RADIX

[edit] Type int

Processes sample data as int arrays:

/* NetRexx */
options replace format comments java crossref symbols binary
 
inputs = [[int 1234, 10], [octal('01234'), 8], [0xfe, 16], [0xf0e,16], [8b0, 2], [16b10101100, 2], [octal('077'), 8]] -- test data
loop i_ = 0 to inputs.length - 1
in = inputs[i_, 0]
ib = inputs[i_, 1]
dSum = sumDigits(in, ib)
say 'Sum of digits for integer "'Integer.toString(in, ib)'" for a given base of "'ib'":' dSum'\-'
-- Carry the exercise to it's logical conclusion and sum the results to give a single digit in range 0-9
loop while dSum.length() > 1 & dSum.datatype('n')
dSum = sumDigits(dSum, 10)
say ',' dSum'\-'
end
say
end i_
 
-- Sum digits of an integer
method sumDigits(val = int, base = int 10) public static returns Rexx
rVal = Rexx 0
sVal = Rexx(Integer.toString(val, base))
loop label digs for sVal.length()
-- loop to extract digits from input and sum them
parse sVal dv +1 sVal
do
rVal = rVal + Integer.valueOf(dv.toString(), base).intValue()
catch ex = NumberFormatException
rVal = 'NumberFormatException:' ex.getMessage()
leave digs
end
end digs
return rVal
 
-- if there's a way to insert octal constants into an int in NetRexx I don't remember it
method octal(oVal = String) private constant returns int signals NumberFormatException
iVal = Integer.valueOf(oVal, 8).intValue()
return iVal
 

Output

Sum of digits for integer "1234" for a given base of "10": 10, 1
Sum of digits for integer "1234" for a given base of "8": 10, 1
Sum of digits for integer "fe" for a given base of "16": 29, 11, 2
Sum of digits for integer "f0e" for a given base of "16": 29, 11, 2
Sum of digits for integer "0" for a given base of "2": 0
Sum of digits for integer "10101100" for a given base of "2": 4
Sum of digits for integer "77" for a given base of "8": 14, 5

[edit] Oberon-2

 
MODULE SumDigits;
IMPORT Out;
PROCEDURE Sum(n: LONGINT;base: INTEGER): LONGINT;
VAR
sum: LONGINT;
BEGIN
sum := 0;
WHILE (n > 0) DO
INC(sum,(n MOD base));
n := n DIV base
END;
RETURN sum
END Sum;
BEGIN
Out.String("1  : ");Out.LongInt(Sum(1,10),10);Out.Ln;
Out.String("1234  : ");Out.LongInt(Sum(1234,10),10);Out.Ln;
Out.String("0FEH  : ");Out.LongInt(Sum(0FEH,16),10);Out.Ln;
Out.String("OF0EH : ");Out.LongInt(Sum(0F0EH,16),10);Out.Ln
END SumDigits.
 

Output:

1     :          1
1234  :         10
0FEH  :         29
OF0EH :         29

[edit] OCaml

let sum_digits ~digits ~base =
let rec aux sum x =
if x <= 0 then sum else
aux (sum + x mod base) (x / base)
in
aux 0 digits
 
let () =
Printf.printf "%d %d %d %d %d\n"
(sum_digits 1 10)
(sum_digits 12345 10)
(sum_digits 123045 10)
(sum_digits 0xfe 16)
(sum_digits 0xf0e 16)
Output:
1 15 15 29 29

[edit] PARI/GP

dsum(n,base)=my(s); while(n, s += n%base; n \= base); s

Also the built-in sumdigits can be used for base 10.

[edit] Perl

#!/usr/bin/perl
use strict ;
use warnings ;
 
#whatever the number base, a number stands for itself, and the letters start
#at number 10 !
 
sub sumdigits {
my $number = shift ;
my $hashref = shift ;
my $sum = 0 ;
map { if ( /\d/ ) { $sum += $_ } else { $sum += ${$hashref}{ $_ } } }
split( // , $number ) ;
return $sum ;
}
 
my %lettervals ;
my $base = 10 ;
for my $letter ( 'a'..'z' ) {
$lettervals{ $letter } = $base++ ;
}
map { print "$_ sums to " . sumdigits( $_ , \%lettervals) . " !\n" }
( 1 , 1234 , 'fe' , 'f0e' ) ;
 

Output:

1 sums to 1 !
1234 sums to 10 !
fe sums to 29 !
f0e sums to 29 !

[edit] Perl 6

This will handle input numbers in any base from 2 to 36. The results are in base 10.

say Σ $_ for <1 1234 1020304 fe f0e DEADBEEF>;
 
sub Σ { [+] $^n.comb.map: { :36($_) } }
Output:
1
10
10
29
29
104

[edit] PHP

<?php
function sumDigits($num, $base = 10) {
$s = base_convert($num, 10, $base);
foreach (str_split($s) as $c)
$result += intval($c, $base);
return $result;
}
echo sumDigits(1), "\n";
echo sumDigits(12345), "\n";
echo sumDigits(123045), "\n";
echo sumDigits(0xfe, 16), "\n";
echo sumDigits(0xf0e, 16), "\n";
?>
Output:
1
15
15
29
29

[edit] PicoLisp

(de sumDigits (N Base)
(or
(=0 N)
(+ (% N Base) (sumDigits (/ N Base) Base)) ) )

Test:

: (sumDigits 1 10)
-> 1
 
: (sumDigits 1234 10)
-> 10
 
: (sumDigits (hex "fe") 16)
-> 29
 
: (sumDigits (hex "f0e") 16)
-> 29

[edit] PL/I

 
sum_digits: procedure options (main); /* 4/9/2012 */
declare ch character (1);
declare (k, sd) fixed;
 
on endfile (sysin) begin; put skip data (sd); stop; end;
sd = 0;
do forever;
get edit (ch) (a(1)); put edit (ch) (a);
k = index('abcdef', ch);
if k > 0 then /* we have a base above 10 */
sd = sd + 9 + k;
else
sd = sd + ch;
end;
end sum_digits;
 

results:

5c7e
SD=      38;
10111000001
SD=       5;

[edit] PowerShell

function Get-DigitalSum ($n)
{
if ($n -lt 10) {$n}
else {
($n % 10) + (Get-DigitalSum ([math]::Floor($n / 10)))
}
}

[edit] Python

def toBaseX(num, base):
output = []
while num:
num, rem = divmod(num, base)
output.append(rem)
return output
 
def sumDigits(num, base=10):
if base < 2:
print "Error: Base must be at least 2"
return
return sum(toBaseX(num, base))
 
print sumDigits(1)
print sumDigits(12345)
print sumDigits(123045)
print sumDigits(0xfe, 16)
print sumDigits(0xf0e, 16)

Output

1
15
15
29
29

[edit] Racket

#lang racket
(define (sum-of-digits n base (sum 0))
(if (= n 0)
sum
(sum-of-digits (quotient n base)
base
(+ (remainder n base) sum))))
 
(for-each
(lambda (number-base-pair)
(define number (car number-base-pair))
(define base (cadr number-base-pair))
(displayln (format "(~a)_~a = ~a" number base (sum-of-digits number base))))
'((1 10) (1234 10) (#xfe 16) (#xf0e 16)))
 
 
 
; outputs:
; (1)_10 = 1
; (1234)_10 = 10
; (254)_16 = 29
; (3854)_16 = 29

[edit] REXX

[edit] version 1

 
/* REXX **************************************************************
* 04.12.2012 Walter Pachl
**********************************************************************/

digits='0123456789ABCDEF'
Do i=1 To length(digits)
d=substr(digits,i,1)
value.d=i-1
End
Call test '1'
Call test '1234'
Call test 'FE'
Call test 'F0E'
Exit
test:
Parse Arg number
res=right(number,4)
dsum=0
Do While number<>''
Parse Var number d +1 number
dsum=dsum+value.d
End
Say res '->' right(dsum,2)
Return

Output:

   1 ->  1
1234 -> 10
  FE -> 29
 F0E -> 29

[edit] version 2

This REXX version allows:

  • leading signs   (+ -)
  • decimal points
  • leading and/or trailing whitespace
  • numbers may be in mixed case
  • numbers may include commas   (,)
  • numbers may be expressed up to base 36
  • numbers may be any length (size)
/*REXX pgm sums the digits of natural numbers in any base up to base 36.*/
parse arg z /*get optional #s or use default.*/
if z='' then z='1 1234 fe f0e +F0E -666.00 11111112222222333333344444449'
do j=1 for words(z); _=word(z,j)
say right(sumDigs(_),9) ' is the sum of the digits for the number ' _
end /*j*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────SUMDIGS subroutine──────────────────*/
sumDigs: procedure; arg x; @=123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
s=0; do k=1 for length(x); s=s+pos(substr(x,k,1),@)
end /*k*/
return s

output when using the default input

        1  is the sum of the digits for the number  1
       10  is the sum of the digits for the number  1234
       29  is the sum of the digits for the number  fe
       29  is the sum of the digits for the number  f0e
       29  is the sum of the digits for the number  +F0E
       18  is the sum of the digits for the number  -666.00
       79  is the sum of the digits for the number  11111112222222333333344444449

[edit] Ruby

>> def sumDigits(num, base = 10)
>> num.to_s(base).split(//).inject(0) {|z, x| z + x.to_i(base)}
>> end
=> nil
>> sumDigits(1)
=> 1
>> sumDigits(12345)
=> 15
>> sumDigits(123045)
=> 15
>> sumDigits(0xfe, 16)
=> 29
>> sumDigits(0xf0e, 16)
=> 29
 

[edit] Run BASIC

This example is incorrect. It only handles base 10, but should be able to handle multiple and/or arbitrary bases. Please fix the code and remove this message.


input "Gimme a number:";n
 
print "Sum of digits :";n;" is ";sum(n)
end
function sum(n)
n$ = str$(n)
for i = 1 to len(n$)
sum = sum + val(mid$(n$,i,1))
next i
end function
Gimme a number:?123456789
Sum of digits :123456789 is 45

[edit] Scala

def sumDigits(x:BigInt, base:Int=10):BigInt=sumDigits(x.toString(base), base)
def sumDigits(x:String, base:Int):BigInt = x map(_.asDigit) sum

Test:

sumDigits(0)                                // => 0
sumDigits(0, 2) // => 0
sumDigits(0, 16) // => 0
sumDigits("00", 2) // => 0
sumDigits("00", 10) // => 0
sumDigits("00", 16) // => 0
sumDigits(1234) // => 10
sumDigits(0xfe) // => 11
sumDigits(0xfe, 16) // => 29
sumDigits(0xf0e, 16) // => 29
sumDigits(077) // => 9
sumDigits(077, 8) // => 14
sumDigits("077", 8) // => 14
sumDigits("077", 10) // => 14
sumDigits("077", 16) // => 14
sumDigits("0xf0e", 36) // => 62
sumDigits("000999ABCXYZ", 36) // => 162
sumDigits(BigInt("12345678901234567890")) // => 90
sumDigits("12345678901234567890", 10) // => 90

[edit] Seed7

$ include "seed7_05.s7i";
 
const func integer: sumDigits (in var integer: num, in integer: base) is func
result
var integer: sum is 0;
begin
while num > 0 do
sum +:= num rem base;
num := num div base;
end while;
end func;
 
const proc: main is func
begin
writeln(sumDigits(1, 10));
writeln(sumDigits(12345, 10));
writeln(sumDigits(123045, 10));
writeln(sumDigits(123045, 50));
writeln(sumDigits(16#fe, 10));
writeln(sumDigits(16#fe, 16));
writeln(sumDigits(16#f0e, 16));
end func;

Output:

1
15
15
104
11
29
29

[edit] Tcl

Supporting arbitrary bases makes this primarily a string operation.

proc sumDigits {num {base 10}} {
set total 0
foreach d [split $num ""] {
if {[string is alpha $d]} {
set d [expr {[scan [string tolower $d] %c] - 87}]
} elseif {![string is digit $d]} {
error "bad digit: $d"
}
if {$d >= $base} {
error "bad digit: $d"
}
incr total $d
}
return $total
}

Demonstrating:

puts [sumDigits 1]
puts [sumDigits 12345]
puts [sumDigits 123045]
puts [sumDigits fe 16]
puts [sumDigits f0e 16]
puts [sumDigits 000999ABCXYZ 36]
Output:
1
15
15
29
29
162

[edit] Visual Basic

This version checks that only valid digits for the indicated base are passed in, exiting otherwise.

Function sumDigits(num As Variant, base As Long) As Long
'can handle up to base 36
Dim outp As Long
Dim validNums As String, tmp As Variant, x As Long, lennum As Long
'ensure num contains only valid characters
validNums = Left$("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", base)
lennum = Len(num)
For L0 = lennum To 1 Step -1
x = InStr(validNums, Mid$(num, L0, 1)) - 1
If -1 = x Then Exit Function
tmp = tmp + (x * (base ^ (lennum - L0)))
Next
While tmp
outp = outp + (tmp Mod base)
tmp = tmp \ base
Wend
sumDigits = outp
End Function
 
Sub tester()
Debug.Print sumDigits(1, 10)
Debug.Print sumDigits(1234, 10)
Debug.Print sumDigits(&HFE, 16)
Debug.Print sumDigits(&HF0E, 16)
Debug.Print sumDigits("2", 2)
End Sub

Output (in the debug window):

1
10
11
20
0

[edit] XPL0

code    ChOut=8, CrLf=9, IntOut=11;
 
func SumDigits(N, Base);
int N, Base, Sum;
[Sum:= 0;
repeat N:= N/Base;
Sum:= Sum + rem(0);
until N=0;
return Sum;
];
 
[IntOut(0, SumDigits(1, 10)); ChOut(0, ^ );
IntOut(0, SumDigits(12345, 10)); ChOut(0, ^ );
IntOut(0, SumDigits(123045, 10)); ChOut(0, ^ );
IntOut(0, SumDigits($FE, 10)); ChOut(0, ^ );
IntOut(0, SumDigits($FE, 16)); ChOut(0, ^ );
IntOut(0, SumDigits($F0E, 16)); CrLf(0);
]

Output:

1 15 15 11 29 29

[edit] zkl

fcn sum(n,b){n.toString(b).split("").apply("toInt",b).sum()}

Convert the int into a string in the proper base, blow it apart into a list of digits, convert each character back into a int and add it up.

Output:
sum(1,10);     //--> 1
sum(1234,10);  //--> 10
sum(0xfe,16);  //--> 29
sum(0xf0e,16); //--> 29
sum(0b1101,2); //--> 3
Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox