Sum and product of an array: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Scala}}: one val for each declaration - or val (sum, product) = (0,1))
(Haskell: Removed unnecessary type to make it more uniform; added blank lines)
Line 229: Line 229:
=={{header|Haskell}}==
=={{header|Haskell}}==


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


values = [1..10] :: [Int]
values = [1..10]
s = sum values -- the easy way
s = sum values -- the easy way
p = product values
p = product values
s' = foldl (+) 0 values -- the hard way
s' = foldl (+) 0 values -- the hard way
p' = foldl (*) 1 values
p' = foldl (*) 1 values
Line 242: Line 244:
values = listArray (1,10) [1..10]
values = listArray (1,10) [1..10]
s = sum $ elems $ values
s = sum $ elems $ values
p = product $ elems $ values
p = product $ elems $ values

Revision as of 08:49, 4 December 2007

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

Ada

type Int_Array is array(Integer range <>) of Integer;
array : Int_Arrayr := (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;

Define the product function

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;

This function will raise the pre-defined exception Constraint_Error if the product overflows the values represented by type Integer

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

BASIC

 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

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++

Using the C++ standard 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 (void)
{
    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#

int sum = 0, prod = 1;
int[] arg = { 1, 2, 3, 4, 5 };
foreach (int value in arg) {
  sum += value;
  prod *= value;
}

Clean

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

ColdFusion

This example is incorrect. It does not accomplish the given task. Please fix the code and remove this message.
 <cfset myArray = listToArray("1,2,3,4,5")>
 #arraySum(myArray)#

Common Lisp

Interpreter: CLisp (ANSI Common Lisp)

(defparameter data #1A(1 2 3 4 5))
((reduce #'+ data)
 (reduce #'* data))

D

auto sum = 0, prod = 1;
auto array = [1, 2, 3, 4, 5];
foreach(v; array) {
    sum += v;
    prod *= v;
}

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 }

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> dup sum . product .
    15 120
{ 1 2 3 4 } dup sum swap product
    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

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

Groovy

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

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)

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;
    }
  }
}

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);

Lisp

Interpreter: XEmacs (beta) version 21.5.21 of February 2005 (+CVS-20050720)

 (setq array [1 2 3 4 5])
 (eval (concatenate 'list '(+) array))
 (eval (concatenate 'list '(*) array))

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

OCaml

let a = [| 1; 2; 3; 4; 5 |] in
  Array.fold_left (+) 0 a
  Array.fold_left ( * ) 1 a

Variant, using a liked list rather than an array:

 let x = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10];;
 List.fold_left (+) 0 x
 List.fold_left ( * ) 1 x

Perl

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

Alternate

Libraries: List::Util

use List::Util 'sum,product';
my @list = (1, 2, 3);
my $s = sum @list;
my $p = product @list;

Alternate

# TMTOWTDI

my $sum = 0, $prod;
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

Interpeter: Python 2.5

numbers = [1, 2, 3]
total = sum(numbers)

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

Or functionally (faster but perhaps less clear):

from functools import reduce     # Interpreter: Python 3.0
from operator import mul, add
reduce(add, numbers)
reduce(mul, numbers)

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

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

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

A recursive solution, without the n-ary operator "trick":

 (define (reduce f u L)
   (if (null? L)
       u
       (f (car L) (reduce f u (cdr L)))))
 (reduce + 0 '(1 2 3 4 5)) ;; 0 is unit for +
 (reduce * 1 '(1 2 3 4 5)) ;; 1 is unit for *

TODO: tail-recursive solution, like a good little Schemer)

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)));

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]

Standard ML

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

Tcl

 set arr [list 3 6 8]
 set sum [expr [join $arr +]]
 set prod [expr [join $arr *]]

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

Interpreter: NetBSD 3.0's ash

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

Interpreter: 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