Sum digits of an integer

From Rosetta Code
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 takes a Natural Number in a given Base and returns the sum of it digits:

1 sums to 1;
1234 sums to 10;
0xfe sums to 29;
0xf0e sums to 29.

C++

<lang cpp> // Sum the digits of an Integer // // Nigel Galloway. July 16th., 2012 //

  1. include <iostream>
  2. 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

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

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

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

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>

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>