Sum digits of an integer: Difference between revisions
(new program for PL/I) |
|||
Line 153: | Line 153: | ||
=={{header|C++}}== |
=={{header|C++}}== |
||
<lang cpp> |
<lang cpp> |
||
// |
//Sum of the digits of an Integer |
||
// |
// |
||
// |
//Zachary Parchman September 5, 2012 |
||
// |
// |
||
#include <iostream> |
#include <iostream> |
||
#include <cmath> |
|||
int |
int sumDigits ( const unsigned long int digitsIn, const int base = 10 ){ |
||
int sum = 0; |
unsigned int sum = 0 ; |
||
unsigned long int x = digitsIn; |
|||
for (int i = log(digits)/log(BASE); i>0; i--){ |
|||
while ( x > 0 ){ |
|||
const double z = std::pow(BASE,i); |
|||
//use integer truncation to do a div mod, largePart being the div and part the mod |
|||
unsigned long int largePart = x / base; |
|||
⚫ | |||
unsigned int part = x - largePart * base; |
|||
x -= t*z; |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
} |
} |
||
int main() |
int main(){ |
||
std::cout << SumDigits(1) << ' ' |
|||
std::cout << sumDigits(1) << " " |
|||
<< sumDigits(12345) << " " |
|||
<< sumDigits(123045) << " " |
|||
<< sumDigits(0xfe, 16) << " " |
|||
<< sumDigits(0xf0e, 16) << " "<< std::endl; |
|||
⚫ | |||
return 0; |
|||
} |
|||
}</lang> |
}</lang> |
||
{{out}} |
{{out}} |
Revision as of 16:10, 5 September 2012
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
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> //Sum of the digits of an Integer // //Zachary Parchman September 5, 2012 //
- include <iostream>
int sumDigits ( const unsigned long int digitsIn, const int base = 10 ){
unsigned int sum = 0 ; unsigned long int x = digitsIn;
while ( x > 0 ){ //use integer truncation to do a div mod, largePart being the div and part the mod unsigned long int largePart = x / base; unsigned int part = x - largePart * base; x = largePart;
sum += part; } return 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
D
<lang d>uint sumDigits(T)(T n, in uint base=10) /*pure nothrow*/ in {
assert(base > 1);
} body {
typeof(return) total = 0; //while (n) { while (n != 0) { total += n % base; n /= base; } return total;
}
void main() {
import std.stdio, std.bigint; writeln(sumDigits(1)); writeln(sumDigits(1_234)); writeln(sumDigits(0xfe, 16)); writeln(sumDigits(0xf0e, 16)); writeln(sumDigits(BigInt(1_234)));
}</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
Haskell
Base 10: <lang Haskell> sumDigits :: String -> Int sumDigits = sum . map Char.digitToInt </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
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
PARI/GP
<lang parigp>dsum(n,base)=my(s); while(n, s += n%b; n \= b); 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
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>
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>
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