Sum and product of an array: Difference between revisions

From Rosetta Code
Content added Content deleted
(Slate implementation)
Line 726: Line 726:
=={{header|Slate}}==
=={{header|Slate}}==
<lang slate>
<lang slate>
#(1 2 3 4 5) reduce: [:sum :number | sum + number]
#(1 2 3 4 5) reduce: [:sum :number | sum + number]
#(1 2 3 4 5) reduce: [:product :number | product * number]
#(1 2 3 4 5) reduce: [:product :number | product * number]
</lang>
Shorthand for the above with a macro:
<lang slate>
#(1 2 3 4 5) reduce: #+ `er
#(1 2 3 4 5) reduce: #* `er
</lang>
</lang>



Revision as of 17:54, 5 June 2009

Task
Sum and product of an array
You are encouraged to solve this task according to the task description, using any language you may know.

Compute the sum and product of an array of integers.

4D

ARRAY INTEGER($list;0)
For ($i;1;5)
       APPEND TO ARRAY($list;$i)
End for

$sum:=0
$product:=1
For ($i;1;Size of array($list))
   $sum:=$var+$list{$i}
   $product:=$product*$list{$i}
End for

ActionScript

<lang actionscript> package { import flash.display.Sprite;

public class SumAndProduct extends Sprite { public function SumAndProduct() { var arr:Array = [1, 2, 3, 4, 5]; var sum:int = 0; var prod:int = 1;

for (var i:int = 0; i < arr.length; i++) { sum += arr[i]; prod *= arr[i]; }

trace("Sum: " + sum); // 15 trace("Product: " + prod); // 120 } } } </lang>

Ada

<lang ada>

type Int_Array is array(Integer range <>) of Integer;
array : Int_Array := (1,2,3,4,5,6,7,8,9,10);
Sum : Integer := 0;
for I in array'range loop
   Sum := Sum + array(I);
end loop;

</lang> Define the product function <lang ada>

function Product(Item : Int_Array) return Integer is
  Prod : Integer := 1;
begin
  for I in Item'range loop
     Prod := Prod * Item(I);
  end loop;
  return Prod;
end Product;

</lang> This function will raise the predefined exception Constraint_Error if the product overflows the values represented by type Integer

ALGOL 68

main:(
  INT default upb := 3;
  MODE INTARRAY = [default upb]INT;
 
  INTARRAY array = (1,2,3,4,5,6,7,8,9,10);
  INT sum := 0;
  FOR i FROM LWB array TO UPB array DO
     sum +:= array[i]
  OD;
 
  # Define the product function #
  PROC int product = (INTARRAY item)INT:
  (
    INT prod :=1;
    FOR i FROM LWB item TO UPB item DO
       prod *:= item[i]
    OD;
    prod
  ) # int product # ;
  printf(($" Sum: "g(0)$,sum,$", Product:"g(0)";"l$,int product(array)))
)

Output:

Sum: 55, Product:3628800;

APL

Works with: APL2
      sum  ←  +/
      prod ←  ×/
      
      list ←  1 2 3 4 5 
      
      sum  list
15
      
      prod list
120

AppleScript

set array to {1, 2, 3, 4, 5}
set sum to 0
set product to 1
repeat with i in array
    set sum to sum + i
    set product to product * i
end repeat

AWK

For array input, it is easiest to "deserialize" it from a string with the split() function. <lang awk> $ awk 'func sum(s){split(s,a);r=0;for(i in a)r+=a[i];return r}{print sum($0)}' 1 2 3 4 5 6 7 8 9 10 55

$ awk 'func prod(s){split(s,a);r=1;for(i in a)r*=a[i];return r}{print prod($0)}' 1 2 3 4 5 6 7 8 9 10 3628800 </lang>

BASIC

Interpreter: unknown

 10 REM Create an array with some test data in it
 20 DIM ARRAY(5)
 30 FOR I = 1 TO 5: READ ARRAY(I): NEXT I
 40 DATA 1, 2, 3, 4, 5
 50 REM Find the sum of elements in the array
 60 SUM = 0
 65 PRODUCT = 1
 70 FOR I = 1 TO 5
 72 SUM = SUM + ARRAY(I)
 75 PRODUCT = PRODUCT + ARRAY(I)
 77 NEXT I
 80 PRINT "The sum is ";SUM;
 90 PRINT " and the product is ";PRODUCT
Works with: FreeBASIC
 dim array(5) as integer = { 1, 2, 3, 4, 5 }
 dim sum as integer = 0
 dim prod as integer = 1
 for index as integer = lbound(array) to ubound(array)
   sum += array(index)
   prod *= array(index)
 next

C

 /* using pointer arithmetic (because we can, I guess) */
 int arg[] = { 1,2,3,4,5 };
 int arg_length = sizeof(arg)/sizeof(arg[0]);
 int *end = arg+arg_length;
 int sum = 0, prod = 1;
 int *p;
 
 for (p = arg; p!=end; ++p) {
    sum += *p;
    prod *= *p;
 }

C++

Library: STL
 #include <numeric>
 #include <functional>
 
 int arg[] = { 1, 2, 3, 4, 5 };
 int sum  = std::accumulate(arg, arg+5, 0, std::plus<int>());
 // or just
 // std::accumulate(arg, arg + 5, 0);
 // since plus() is the default functor for accumulate
 int prod = std::accumulate(arg, arg+5, 1, std::multiplies<int>());

Template alternative:

// this would be more elegant using STL collections
template <typename T> T sum (const T *array, const unsigned n)
{
    T accum = 0;
    for (unsigned i=0; i<n; i++)
        accum += array[i];
    return accum;
}
template <typename T> T prod (const T *array, const unsigned n)
{
    T accum = 1;
    for (unsigned i=0; i<n; i++)
        accum *= array[i];
    return accum;
}

#include <iostream>
using std::cout;
using std::endl;

int main ()
{
    int aint[] = {1, 2, 3};
    cout << sum(aint,3) << " " << prod(aint, 3) << endl;
    float aflo[] = {1.1, 2.02, 3.003, 4.0004};
    cout << sum(aflo,4) << " " << prod(aflo,4) << endl;
    return 0;
}

C#

<lang csharp>int sum = 0, prod = 1; int[] arg = { 1, 2, 3, 4, 5 }; foreach (int value in arg) {

 sum += value;
 prod *= value;

}</lang>

Clean

array = {1, 2, 3, 4, 5}
Sum = sum [x \\ x <-: array]
Prod = foldl (*) 1 [x \\ x <-: array]

ColdFusion

Sum of an Array,

<cfset Variables.myArray = [1,2,3,4,5,6,7,8,9,10]>
<cfoutput>#ArraySum(Variables.myArray)#</cfoutput>

Product of an Array,

<cfset Variables.myArray = [1,2,3,4,5,6,7,8,9,10]>
<cfset Variables.Product = 1>
<cfloop array="#Variables.myArray#" index="i">
 <cfset Variables.Product *= i>
</cfloop>
<cfoutput>#Variables.Product#</cfoutput>

Common Lisp

<lang lisp>(let ((data #(1 2 3 4 5)))  ; the array

 (values (reduce #'+ data)       ; sum
         (reduce #'* data)))     ; product</lang>

D

<lang d>auto sum = 0, prod = 1; auto array = [1, 2, 3, 4, 5]; foreach(v; array) {

   sum += v;
   prod *= v;

}</lang> Compute sum and product of array in one pass using std.algorithm: <lang d>auto array = [1, 2, 3, 4, 5]; auto r = reduce!("a + b", "a * b")(0, 1, array); // 0 and 1 are seeds for corresponding functions writefln("Sum: ", r._0); // Results are stored in a tuple writefln("Product: ", r._1); </lang>

Delphi

 var
   Ints   : array[1..5] of integer = (1,2,3,4,5) ;
   i,Sum  : integer = 0 ;
   Prod   : integer = 1 ;
 begin
   for i := 1 to length(ints) do begin
     inc(sum,ints[i]) ;
     prod := prod * ints[i]
   end;
 end;

E

pragma.enable("accumulator")
accum 0 for x in [1,2,3,4,5] { _ + x }
accum 1 for x in [1,2,3,4,5] { _ * x }

Emacs Lisp

Works with: XEmacs version version 21.5.21
 (setq array [1 2 3 4 5])
 (eval (concatenate 'list '(+) array))
 (eval (concatenate 'list '(*) array))

Erlang

Using the standard libraries:

% create the list:
L = lists:seq(1, 10).
% and compute its sum:
S = lists:sum(L).
P = lists:foldl(fun (X, P) -> X * P end, 1, L).

Or defining our own versions:

-module(list_sum).
-export([sum_rec/1, sum_tail/1]).
% recursive definition:
sum_rec([]) ->
    0;
sum_rec([Head|Tail]) ->
    Head + sum_rec(Tail).
% tail-recursive definition:
sum_tail(L) ->
    sum_tail(L, 0).
sum_tail([], Acc) ->
    Acc;
sum_tail([Head|Tail], Acc) ->
    sum_tail(Tail, Head + Acc).

Factor

1 5 1 <range> [ sum . ] [ product . ] bi
    15 120
{ 1 2 3 4 } [ sum ] [ product ] bi
    10 24

sum and product are defined in the sequences vocabulary:

   : sum ( seq -- n ) 0 [+] reduce ;
   : product ( seq -- n ) 1 [ * ] reduce ;

Forth

: third ( a b c -- a b c a ) 2 pick ;
: reduce ( xt n addr cnt -- n' ) \ where xt ( a b -- n )
  cells bounds do i @ third execute  cell +loop nip ;
create a 1 , 2 , 3 , 4 , 5 ,

' + 0 a 5 reduce .    \ 15
' * 1 a 5 reduce .    \ 120

Fortran

In ISO Fortran 90 and later, use SUM and PRODUCT intrinsics:

 integer, dimension(10) :: a = (/ (i, i=1, 10) /)
 integer :: sresult, presult
 
 sresult = sum(a);
 presult = product(a);

Groovy

Groovy adds a "sum()" method for collections, but not a "product()" method: <lang groovy>

[1,2,3,4,5].sum()

</lang>

However, for general purpose "reduction" or "folding" operations, Groovy does provide an "inject()" method for collections similar to "inject" in Ruby. <lang groovy>

[1,2,3,4,5].inject(0) { sum, val -> sum + val }
[1,2,3,4,5].inject(1) { prod, val -> prod * val }

</lang>

Haskell

For lists, sum and product are already defined in the Prelude:

 values = [1..10]

 s = sum values           -- the easy way
 p = product values

 s' = foldl (+) 0 values  -- the hard way
 p' = foldl (*) 1 values

To do the same for an array, just convert it lazily to a list:

import Data.Array

values = listArray (1,10) [1..10]

s = sum . elems $ values
p = product . elems $ values

IDL

 array = [3,6,8]
 print,total(array)
 print,product(array)

J

sum=: +/
product=: */

For example:

   sum 1 3 5 7 9 11 13
49
   product 1 3 5 7 9 11 13
135135

   a=: 3 10 ?@$ 100  NB. random array
   a
90 47 58 29 22 32 55  5 55 73
58 50 40  5 69 46 34 40 46 84
29  8 75 97 24 40 21 82 77  9

   sum a
177 105 173 131 115 118 110 127 178 166
   product a
151380 18800 174000 14065 36432 58880 39270 16400 194810 55188

   sum"1 a
466 472 462
   product"1 a
5.53041e15 9.67411e15 1.93356e15

Java

Works with: Java version 1.5+

<lang java>public class SumProd{

 public static void main(String[] args){
   int sum= 0;
   int prod= 1
   int[] arg= {1,2,3,4,5};
   for (int i: arg) {
     sum+= i;
     prod*= i;
   }
 }

}</lang>

JavaScript

var array = [1, 2, 3, 4, 5];
var sum = 0, prod = 1;
for(var i in array) {
  sum += array[i];
  prod *= array[i];
}
alert(sum + " " + prod);

print apply "sum arraytolist {1 2 3 4 5}
print apply "product arraytolist {1 2 3 4 5}

Lucid

prints a running sum and product of sequence 1,2,3...

[%sum,product%]
 where
    x = 1 fby x + 1;
    sum = 0 fby sum + x;
    product = 1 fby product * x
 end

MAXScript

arr = #(1, 2, 3, 4, 5)
sum = 0
for i in arr do sum += i
product = 1
for i in arr do product *= i

Nial

Nial being an array language, what applies to individual elements are extended to cover array operations by default strand notation

+ 1 2 3
= 6
* 1 2 3
= 6

array notation

+ [1,2,3]

grouped notation

(* 1 2 3)
= 6
* (1 2 3)
= 6

(All these notations are equivalent)

Modula-3

MODULE Sumprod EXPORTS Main;

FROM IO IMPORT Put;
FROM Fmt IMPORT Int;

VAR a := ARRAY [1..5] OF INTEGER {1, 2, 3, 4, 5};
VAR sum: INTEGER := 0;
VAR prod: INTEGER := 1;

BEGIN
  FOR i := FIRST(a) TO LAST(a) DO
    INC(sum, a[i]);
    prod := prod * a[i];
  END;
  Put("Sum of array: " & Int(sum) & "\n");
  Put("Product of array: " & Int(prod) & "\n");
END Sumprod.

Output:

Sum of array: 15
Product of array: 120

Objective-C

Works with: GCC version 4.0.1 (apple)

Sum:

- (float) sum:(NSMutableArray *)array
{ 
	int i, sum, value;
	sum = 0;
	value = 0;
	
	for (i = 0; i < [array count]; i++) {
		value = [[array objectAtIndex: i] intValue];
		sum += value;
	}
	
	return suml;
}

Product:

- (float) prod:(NSMutableArray *)array
{ 
	int i, prod, value;
	prod = 0;
	value = 0;
	
	for (i = 0; i < [array count]; i++) {
		value = [[array objectAtIndex: i] intValue];
		prod *= value;
	}
	
	return suml;
}

OCaml

Arrays

(* ints *)
let a = [| 1; 2; 3; 4; 5 |];;
Array.fold_left (+) 0 a;;
Array.fold_left ( * ) 1 a;;
(* floats *)
let a = [| 1.0; 2.0; 3.0; 4.0; 5.0 |];;
Array.fold_left (+.) 0.0 a;;
Array.fold_left ( *.) 1.0 a;;

Lists

(* ints *)
let x = [1; 2; 3; 4; 5];;
List.fold_left (+) 0 x;;
List.fold_left ( * ) 1 x;;
(* floats *)
let x = [1; 2; 3; 4; 5];;
List.fold_left (+.) 0.0 x;;
List.fold_left ( *.) 1.0 x;;

Octave

<lang octave>a = [ 1, 2, 3, 4, 5, 6 ]; b = [ 10, 20, 30, 40, 50, 60 ]; vsum = a + b; vprod = a .* b;</lang>


Oz

functor
import
  Application System
define 

  Print = System.showInfo

  Arr = [1 2 3 4 5]

  {Print {FoldL Arr Number.'+' 0}}
  {Print {FoldL Arr Number.'*' 1}}

  {Application.exit 0}
end

Perl

my ($sum, $prod) = (0, 1);
my @list = (1, 2, 3);
$sum += $_ foreach @list;
$prod *= $_ foreach @list;

Alternate:

use List::Util qw(sum reduce);

my @list = (1, 2, 3);
my $sum1 = sum 0, @list;                    # 0 identity to allow empty list
my $sum2 = reduce { $a + $b } 0, @list;
my $product = reduce { $a * $b } 1, @list;

Alternate

# TMTOWTDI

my ($sum, $prod) = (0, 1);
my @list = qw(1 2 3);
map { $sum += $_ } @list;
map($prod *= $_, @list);

PHP

 $array = array(1,2,3,4,5,6,7,8,9);
 echo array_sum($array);
 echo array_product($array);

Pop11

Simple loop:

lvars i, sum = 0, prod = 1, ar = {1 2 3 4 5 6 7 8 9};
for i from 1 to length(ar) do
    ar(i) + sum -> sum;
    ar(i) * prod -> prod;
endfor;

One can alternativly use second order iterator:

lvars sum = 0, prod = 1, ar = {1 2 3 4 5 6 7 8 9};
appdata(ar, procedure(x); x + sum -> sum; endprocedure);
appdata(ar, procedure(x); x * prod -> prod; endprocedure);

Prolog

sum([],0).
sum([H|T],X) :- sum(T,Y), X is H + Y.
product([],1).
product([H|T],X) :- product(T,Y), X is H * X.

test

:- sum([1,2,3,4,5,6,7,8,9],X).
X =45;
:- product([1,2,3,4,5],X).
X = 120;

Python

Works with: Python version 2.5
numbers = [1, 2, 3]
total = sum(numbers)

product = 1
for i in numbers:
    product *= i

Or functionally (faster but perhaps less clear):

Works with: Python version 2.5
from operator import mul, add
sum = reduce(add, numbers) # note: this version doesn't work with empty lists
sum = reduce(add, numbers, 0)
product = reduce(mul, numbers) # note: this version doesn't work with empty lists
product = reduce(mul, numbers, 1)
Library: numpy
from numpy import r_
numbers = r_[1:4]
total = numbers.sum()
product = numbers.prod()

R

 arr <- c(1,2,3,4,5)
 total <- sum(arr)
 product <- prod(arr)

Raven

0 [ 1 2 3 ] each +
1 [ 1 2 3 ] each *

Ruby

 arr = [1,2,3,4,5]     # or ary = *1..5
 sum = arr.inject { |sum, item| sum + item }
 # => 15
 product = ary.inject{ |prod, element| prod * element }
 # => 120

Ruby 1.9

 arr = [1,2,3,4,5]     # or ary = *1..5
 sum = arr.inject(:+)
 # => 15
 product = ary.inject(:*)
 # => 120

Scala

val a = Array(1,2,3,4,5)
val sum = a.foldLeft(0)(_ + _)
val product = a.foldLeft(1)(_ * _)  
    // (_ * _) is a shortcut for  {(x,y) => x * y}

It may also be done in a classic imperative way :

 var sum = 0; val product = 1
 for (val x <- a) sum = sum + x
 for (val x <- a) product = product * x

Scheme

(apply + '(1 2 3 4 5))
(apply * '(1 2 3 4 5))

A tail-recursive solution, without the n-ary operator "trick". Because Scheme supports tail call optimization, this is as space-efficient as an imperative loop.

(define (reduce f i l)
  (if (null? l)
    i
    (reduce f (f i (car l)) (cdr l))))

(reduce + 0 '(1 2 3 4 5)) ;; 0 is unit for +
(reduce * 1 '(1 2 3 4 5)) ;; 1 is unit for *

Seed7

const func integer: sumArray (in array integer: valueArray) is func
  result
    var integer: sum is 0;
  local
    var integer: value is 0;
  begin
    for value range valueArray do
      sum +:= value;
    end for;
  end func;

const func integer: prodArray (in array integer: valueArray) is func
  result
    var integer: prod is 1;
  local
    var integer: value is 0;
  begin
    for value range valueArray do
      prod *:= value;
    end for;
  end func;

Call these functions with:

writeln(sumArray([](1, 2, 3, 4, 5)));
writeln(prodArray([](1, 2, 3, 4, 5)));

SETL

<lang SETL>numbers := [1 2 3 4 5 6 7 8 9]; print(+/ numbers, */ numbers);</lang>

=> 45 362880

Slate

<lang slate>

  1. (1 2 3 4 5) reduce: [:sum :number | sum + number]
  2. (1 2 3 4 5) reduce: [:product :number | product * number]

</lang> Shorthand for the above with a macro: <lang slate>

  1. (1 2 3 4 5) reduce: #+ `er
  2. (1 2 3 4 5) reduce: #* `er

</lang>

Smalltalk

#(1 2 3 4 5) inject: 0 into: [:sum :number | sum + number]
#(1 2 3 4 5) inject: 1 into: [:product :number | product * number]

Some implementation also provide a fold: message:

#(1 2 3 4 5) fold: [:sum :number | sum + number]
#(1 2 3 4 5) fold: [:product :number | product * number]

Standard ML

 val array = [1,2,3,4,5];
 foldl op+ 0 array;
 foldl (op*) 1 array;

Standard ML

Arrays

(* ints *)
val a = Array.fromList [1, 2, 3, 4, 5];
Array.foldl op+ 0 a;
Array.foldl op* 1 a;
(* reals *)
val a = Array.fromList [1.0, 2.0, 3.0, 4.0, 5.0];
Array.foldl op+ 0.0 a;
Array.foldl op* 1.0 a;

Lists

(* ints *)
val x = [1, 2, 3, 4, 5];
foldl op+ 0 x;
foldl op* 1 x;
(* reals *)
val x = [1.0, 2.0, 3.0, 4.0, 5.0];
foldl op+ 0.0 x;
foldl op* 1.0 x;

Tcl

<lang tcl>set arr [list 3 6 8] set sum [expr [join $arr +]] set prod [expr [join $arr *]]</lang>

Works with: Tcl version 8.5

<lang tcl>set arr [list 3 6 8] set sum [tcl::mathop::+ {*}$arr] set prod [tcl::mathop::* {*}$arr]</lang>

Toka

4 cells is-array foo

212 1 foo array.put
51 2 foo array.put
12 3 foo array.put
91 4 foo array.put

[ ( array size -- sum )
  >r 0 r> 0 [ over i swap array.get + ] countedLoop nip ] is sum-array
( product )
reset 1 4 0 [ i foo array.get * ] countedLoop .

UNIX Shell

Works with: NetBSD version 3.0

From an internal variable, $IFS delimited:

 sum=0
 prod=1
 list="1 2 3"
 for n in $list
 do sum="$(($sum + $n))"; prod="$(($prod * $n))"
 done
 echo $sum $prod

From the argument list (ARGV):

 sum=0
 prod=1
 for n
 do sum="$(($sum + $n))"; prod="$(($prod * $n))"
 done
 echo $sum $prod

From STDIN, one integer per line:

 sum=0
 prod=1
 while read n
 do sum="$(($sum + $n))"; prod="$(($prod * $n))"
 done
 echo $sum $prod
Works with: GNU bash version 3.2.0(1)-release (i386-unknown-freebsd6.1)

From variable:

 LIST='20 20 2';
 SUM=0; PROD=1;
 for i in $LIST; do
   SUM=$[$SUM + $i]; PROD=$[$PROD * $i];
 done;
 echo $SUM $PROD


UnixPipes

prod() {
   (read B; res=$1; test -n "$B" && expr $res \* $B || echo $res)
}
sum() {
   (read B; res=$1; test -n "$B" && expr $res + $B || echo $res)
}
fold() {
   (func=$1; while read a ; do ; fold $func | $func $a done)
}


(echo 3; echo 1; echo 4;echo 1;echo 5;echo 9) | tee >(fold sum) >(fold prod) > /dev/null

V

[sp dup 0 [+] fold 'product=' put puts 1 [*] fold 'sum=' put puts].

Using it

[1 2 3 4 5] sp
=
product=15
sum=120

XSLT

XSLT (or XPath rather) has a few built-in functions for reducing from a collection, but product is not among them. Because of referential transparency, one must resort to recursive solutions for general iterative operations upon collections. The following code represents the array by numeric values in <price> elements in the source document.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" />
  
  <xsl:template name="sum-prod">
    <xsl:param name="values" />
    <xsl:param name="sum"  select="0" />
    <xsl:param name="prod" select="1" />
    <xsl:choose>
      <xsl:when test="not($values)">
        <xsl:text>
Sum: </xsl:text>
        <xsl:value-of select="$sum" />
        <xsl:text>
Product: </xsl:text>
        <xsl:value-of select="$prod" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="sum-prod">
          <xsl:with-param name="values" select="$values[position() > 1]" />
          <xsl:with-param name="sum"  select="$sum  + $values[1]" />
          <xsl:with-param name="prod" select="$prod * $values[1]" />
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template match="/">
     <xsl:text>
Sum (built-in): </xsl:text>
    <xsl:value-of select="sum(//price)" />
    
    <xsl:call-template name="sum-prod">
      <xsl:with-param name="values" select="//price" />
    </xsl:call-template>
  </xsl:template>
</xsl:stylesheet>