Averages/Arithmetic mean
You are encouraged to solve this task according to the task description, using any language you may know.
Write a program to find the mean (arithmetic average) of a numeric vector. The program should work on a zero-length vector (with an answer of 0).
Ada
This example shows how to pass a zero length vector as well as a larger vector.
with Ada.Float_Text_Io; use Ada.Float_Text_Io; with Ada.Text_IO; use Ada.Text_IO; procedure Mean_Main is type Vector is array(Positive range <>) of Float; function Mean(Item : Vector) return Float is Sum : Float := 0.0; Result : Float := 0.0; begin for I in Item'range loop Sum := Sum + Item(I); end loop; if Item'Length > 0 then Result := Sum / Float(Item'Length); end if; return Result; end Mean; A : Vector := (3.0, 1.0, 4.0, 1.0, 5.0, 9.0); begin Put(Item => Mean(A), Fore => 1, Exp => 0); New_Line; -- test for zero length vector Put(Item => Mean(A(1..0)), Fore => 1, Exp => 0); New_Line; end Mean_Main;
Output:
3.83333 0.00000
BASIC
Assume the numbers are in a DIM named nums.
mean = 0 sum = 0; FOR i = LBOUND(nums) TO UBOUND(nums) sum = sum + nums(i); NEXT i size = UBOUND(nums) - LBOUND(nums) + 1 PRINT "The mean is: "; IF size <> 0 THEN PRINT (sum / size) ELSE PRINT 0 END IF
C++
double mean(std::vector<double> const& vNumbers) { double sum = 0; for( std::vector<double>::iterator i = vNumbers.begin(); vNumbers.end() != i; ++i ) sum += *i; if( 0 == vNumbers.size() ) return 0; else return sum / vNumbers.size(); }
Shorter (and more idiomatic) version:
#include <vector> #include <algorithm> double mean(std::vector<double> const& numbers) { if (numbers.empty()) return 0; return std::accumulate(numbers.begin(), numbers.end(), 0.0) / numbers.size(); }
Common Lisp
(defun mean (sequence) (let ((length (length sequence))) (if (zerop length) 0 (/ (reduce #'+ sequence) length))))
D
Using template to make the mean function work for higher-rank array.
module mean ; import std.stdio ; real mean(T)(T[] a) { static if(is(T U : U[])) { // recursively unfold the multi-array T u ; foreach(e ; a) u ~= e ; return u.mean() ; } else { // do the math if(a.length == 0) return 0.0 ; real sum = 0.0 ; foreach(e ; a) sum += e ; return sum / a.length ; } } void main() { int[] array = [3,1,4,1,5,9]; real[][][] multi = [[[1,2,2],[2,3,4],[4,5,7]], [[4,1,3],[0,3,1],[4,4,6]], [[1,3,3],[2,7,8],[9,1,5]]] ; writefln("array : ", array.mean()) ; writefln("multi : ", multi.mean()) ; }
Forth
: fmean ( addr n -- f ) 0e dup 0= if 2drop exit then tuck floats bounds do i f@ f+ 1 floats +loop 0 d>f f/ ; create test 3e f, 1e f, 4e f, 1e f, 5e f, 9e f, test 6 fmean f. \ 3.83333333333333
Fortran
In ISO Fortran 90 or later, use the SUM intrinsic, the SIZE intrinsic and the MAX intrinsic (to avoid divide by zero):
REAL, DIMENSION(100) :: A = (/ (i, i=1, 100) /) REAL, DIMENSION(5,20) :: B = RESHAPE( A, (/ 5,20 /) ) REAL, POINTER, DIMENSION(:) :: P => A(2:1) ! pointer to zero-length array REAL :: MEAN, ZMEAN, BMEAN REAL, DIMENSION(20) :: COLMEANS REAL, DIMENSION(5) :: ROWMEANS MEAN = SUM(A)/SIZE(A) ! SUM of A's elements divided by SIZE of A MEAN = SUM(A)/MAX(SIZE(A),1) ! Same result, but safer code ! MAX of SIZE and 1 prevents divide by zero if SIZE == 0 (zero-length array) ZMEAN = SUM(P)/MAX(SIZE(P),1) ! Here the safety check pays off. Since P is a zero-length array, ! expression becomes "0 / MAX( 0, 1 ) -> 0 / 1 -> 0", rather than "0 / 0 -> NaN" BMEAN = SUM(B)/MAX(SIZE(B),1) ! multidimensional SUM over multidimensional SIZE ROWMEANS = SUM(B,1)/MAX(SIZE(B,2),1) ! SUM elements in each row (dimension 1) ! dividing by the length of the row, which is the number of columns (SIZE of dimension 2) COLMEANS = SUM(B,2)/MAX(SIZE(B,1),1) ! SUM elements in each column (dimension 2) ! dividing by the length of the column, which is the number of rows (SIZE of dimension 1)
Haskell
mean xs = sum xs / Data.List.genericLength xs
IDL
If truly only the mean is wanted, one could use
x = [3,1,4,1,5,9] print,mean(x)
But mean() is just a thin wrapper returning the zeroth element of moment() :
print,moment(x) ; ==> 3.83333 8.96667 0.580037 -1.25081
which are mean, variance, skewness and kurtosis.
There are no zero-length vectors in IDL. Every variable has at least one value or otherwise it is <Undefined>.
J
mean=: +/ % #
That is, sum divided by the number of items. The verb also works on higher-ranked arrays. For example:
mean 3 1 4 1 5 9 3.83333 mean $0 NB. $0 is a zero-length vector 0 x=: 20 4 ?@$ 0 NB. a 20-by-4 table of random (0,1) numbers mean x 0.58243 0.402948 0.477066 0.511155
The computation can also be written as a loop. It is shown here for comparison only and is highly non-preferred compared to the version above.
mean1=: 3 : 0 z=. 0 for_i. i.#y do. z=. z+i{y end. z % #y ) mean1 3 1 4 1 5 9 3.83333 mean1 $0 0 mean1 x 0.58243 0.402948 0.477066 0.511155
Java
Assume the numbers are in a double array called "nums".
... double mean = 0; double sum = 0; for(double i : nums){ sum += i; } System.out.println("The mean is: " + ((nums.length != 0) ? (sum / nums.length) : 0)); ...
JavaScript
function mean(array) { var sum = 0; for(var i in array) sum += array[i]; return array.length ? sum / array.length : 0; } alert( mean( [1,2,3,4,5] ) ); // 3
function mean(a) { return a.length ? Functional.reduce('+', 0, a) / a.length : 0; }
Logo
to average :l if empty? :l [output 0] output quotient apply "sum :l count :l end print average [1 2 3 4] ; 2.5
MAXScript
fn mean data = ( total = 0 for i in data do ( total += i ) if data.count == 0 then 0 else total as float/data.count ) print (mean #(3, 1, 4, 1, 5, 9))
OCaml
These functions return a float:
let mean_floats xs = if xs = [] then 0. else List.fold_left (+.) 0. xs /. float_of_int (List.length xs)
let mean_ints xs = mean_floats (List.map float_of_int xs)
Perl
sub avg(@_) { $count = 0; $sum = 0; foreach (@_) { $sum += $_; $count++; } return $count > 0 ? $sum / $count : 0; } print avg(qw(3 1 4 1 5 9))."\n";
Output:
3.83333333333333
With module Data::Average. (For zero-length array returns ().)
use Data::Average; my $d = Data::Average->new; $d->add($_) foreach (qw(3 1 4 1 5 9)); print $d->avg."\n"
Output:
3.83333333333333
Python
def avg(data): return sum(data)/float(len(data)) if len(data)!=0 else 0 print avg([3,1,4,1,5,9])
Output:
3.83333333333333
def avg(data): if len(data)==0: return 0 else: return sum(data)/float(len(data)) print avg([3,1,4,1,5,9])
Output:
3.83333333333333
Scheme
(define (mean l) (if (null? l) 0 (/ (apply + l) (length l))))
> (mean (list 3 1 4 1 5 9)) 3 5/6