Sum digits of an integer: Difference between revisions
Updated D entry |
Updated D entry |
||
Line 283: | Line 283: | ||
=={{header|D}}== |
=={{header|D}}== |
||
⚫ | |||
⚫ | |||
⚫ | |||
in { |
in { |
||
assert(base > 1); |
assert(base > 1); |
||
Line 294: | Line 296: | ||
void main() { |
void main() { |
||
sumDigits(1).writeln; |
|||
⚫ | |||
sumDigits(1_234).writeln; |
|||
sumDigits(0xfe, 16).writeln; |
|||
sumDigits(0xf0e, 16).writeln; |
|||
sumDigits(1_234.BigInt).writeln; |
|||
writeln(sumDigits(BigInt(1_234))); |
|||
}</lang> |
}</lang> |
||
{{out}} |
{{out}} |
Revision as of 20:02, 14 April 2013
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
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 in a given Base and return the sum of its digits:
1
10
sums to ;1234
10
sums to ;fe
16
sums to ;f0e
16
sums to .
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.
<lang Ada>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;</lang>
- Output:
1 15 15 104 11 29 29
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.
<lang AWK>#!/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
} </lang>
Example output:
1 3 29 29
BBC BASIC
This solution deliberately avoids MOD and DIV so it is not restricted to 32-bit integers. <lang bbcbasic> *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</lang>
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)
C
<lang 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;
}</lang>
- Output:
1 15 15 29 29
C#
<lang csharp>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)); } } }
}</lang> Output:
1 15 15 29 29
C++
<lang cpp>#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;
}</lang>
- Output:
1 15 15 29 29
C++ (template)
Template metaprogramming version. Tested with g++-4.6.3 (Ubuntu). <lang cpp> // 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;
} </lang>
- Output:
1 15 15 29 29
Common Lisp
<lang 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)))</lang>
Example: <lang lisp>(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)))</lang>
- Output:
(1)_10 = 1 (1234)_10 = 10 (254)_16 = 29 (3854)_16 = 29
D
<lang 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() {
sumDigits(1).writeln; sumDigits(1_234).writeln; sumDigits(0xfe, 16).writeln; sumDigits(0xf0e, 16).writeln; sumDigits(1_234.BigInt).writeln;
}</lang>
- Output:
1 10 29 29 10
Erlang
<lang 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)).
</lang>
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
F#
<lang fsharp>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</lang>
Go
Handling numbers up to 2^63 and bases from 2 to 36 is pretty easy. <lang go>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
}</lang> <lang go>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) } }
}</lang>
Groovy
Solution: <lang groovy>def digitsum = { number, radix = 10 ->
Integer.toString(number, radix).collect { Integer.parseInt(it, radix) }.sum()
}</lang>
Test: <lang groovy>[[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])} """
}</lang>
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
Haskell
<lang 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</lang>
J
<lang j>digsum=: 10&$: : (+/@(#.inv))</lang>
Example use:
<lang J> digsum 1234 10
10 digsum 254
11
16 digsum 254
29</lang>
Illustration of mechanics:
<lang j> 10 #. 1 2 3 4 1234
10 #.inv 1234
1 2 3 4
10 +/ 1 2 3 4
10
10 +/@(#.inv) 1234
10</lang>
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:
<lang j> digsum 1 1
digsum 1234
10
16 digsum 16bfe
29
16 digsum 16bf0e
29</lang>
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.
<lang j> 200+54 254
254
254
2.54e2
254
16bfe
254</lang>
Java
<lang 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")));
}
}</lang>
- Output:
1 15 15 29 29 90
Mathematica
<lang Mathematica>Total[IntegerDigits[1234]] Total[IntegerDigits[16^^FE, 16]]</lang>
- Output:
10 29
NetRexx
Strings
Processes data as text from the command line. Provides a representative sample if no input is supplied: <lang NetRexx>/* 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
</lang> 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
Type int
Processes sample data as int arrays: <lang NetRexx>/* 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
</lang> 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
Oberon-2
<lang oberon2> 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. </lang> Output:
1 : 1 1234 : 10 0FEH : 29 OF0EH : 29
OCaml
<lang 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)</lang>
- Output:
1 15 15 29 29
PARI/GP
<lang parigp>dsum(n,base)=my(s); while(n, s += n%base; n \= base); s</lang>
Also the built-in sumdigits
can be used for base 10.
Perl
<lang 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' ) ;
</lang> Output:
1 sums to 1 ! 1234 sums to 10 ! fe sums to 29 ! f0e sums to 29 !
Perl 6
This will handle input numbers in any base from 2 to 36. The results are in base 10. <lang perl6>say Σ $_ for <1 1234 1020304 fe f0e DEADBEEF>;
sub Σ { [+] $^n.comb.map: { :36($_) } }</lang>
- Output:
1 10 10 29 29 104
PHP
<lang 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"; ?></lang>
- Output:
1 15 15 29 29
PicoLisp
<lang PicoLisp>(de sumDigits (N Base)
(or (=0 N) (+ (% N Base) (sumDigits (/ N Base) Base)) ) )</lang>
Test: <lang PicoLisp>: (sumDigits 1 10) -> 1
- (sumDigits 1234 10)
-> 10
- (sumDigits (hex "fe") 16)
-> 29
- (sumDigits (hex "f0e") 16)
-> 29</lang>
PL/I
<lang 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; </lang> results:
5c7e SD= 38; 10111000001 SD= 5;
Python
<lang python>def toBaseX(num, base): output = [] index = 0 while num: num, rem = divmod(num, base) output.append(str(rem)) return output
def sumDigits( *args ): if len(args) == 1: number = str(args[0]) else: num = args[0] base = args[1] if base < 2: print "Base must be between 2 and 36" exit(1) if num < base or num == base: number = str(num) else: number = toBaseX(num,base)
sumVal = 0 for x in number: sumVal += int(x) return sumVal
print sumDigits(1) print sumDigits(12345) print sumDigits(123045) print sumDigits(0xfe, 16) print sumDigits(0xf0e, 16)</lang> Output
1 15 15 29 29
REXX
version 1
<lang rexx> /* 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</lang>
Output:
1 -> 1 1234 -> 10 FE -> 29 F0E -> 29
version 2
This REXX version allows:
- user-specified number (or numbers)
- leading sign
- decimal points
- numbers may be in mixed case
- numbers up to base 36
- numbers of any length (size)
<lang rexx>/*REXX pgm sums the digits of natural numbers in any base up to base 36.*/ parse arg nums; if nums= then nums='1 1234 fe f0e +F0E -666.00'
do j=1 for words(nums); _=word(nums,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 i=1 for length(x)
s=s+index(@,substr(x,i,1)) end /*i*/
return s</lang> 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
Ruby
<lang 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 </lang>
Run BASIC
<lang runbasic>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</lang>
Gimme a number:?123456789 Sum of digits :123456789 is 45
Scala
<lang 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</lang> Test: <lang scala>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</lang>
Seed7
<lang 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;</lang>
Output:
1 15 15 104 11 29 29
Tcl
Supporting arbitrary bases makes this primarily a string operation. <lang tcl>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
}</lang> Demonstrating: <lang tcl>puts [sumDigits 1] puts [sumDigits 12345] puts [sumDigits 123045] puts [sumDigits fe 16] puts [sumDigits f0e 16] puts [sumDigits 000999ABCXYZ 36]</lang>
- Output:
1 15 15 29 29 162
XPL0
<lang 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);
]</lang>
Output:
1 15 15 11 29 29