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
ALGOL 68
PROC mean = (REF[]REAL p)REAL: # Calculates the mean of qty REALs beginning at p. # IF LWB p > UPB p THEN 0.0 ELSE REAL total := 0.0; FOR i FROM LWB p TO UPB p DO total +:= p[i] OD; total / (UPB p - LWB p + 1) FI; main:( [6]REAL test := (1.0, 2.0, 5.0, -5.0, 9.5, 3.14159); print((mean(test),new line)) )
AWK
<lang awk># work around a gawk bug in the length extended use:
- so this is a more non-gawk compliant way to get
- how many elements are in an array
function elength(v) {
l=0 for(el in v) l++ return l
}
function mean(v) {
if (elength(v) < 1) { return 0 } sum = 0 for(i=0; i < elength(v); i++) { sum += v[i] } return sum/elength(v)
}
BEGIN {
# fill a vector with random numbers for(i=0; i < 10; i++) { vett[i] = rand()*10 } print mean(vett)
}</lang>
APL
X←3 1 4 1 5 9 (+/X)÷⍴X 3.833333333
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
This implementation uses a plain old static array of doubles for the numeric vector.
<lang c>#include <stdio.h>
double mean(double *p, unsigned qty) /* Calculates the mean of qty doubles beginning at p. */
{if (qty == 0) return 0; double total = 0; for (int i = 0 ; i < qty ; ++i) total += p[i]; return total / qty;}
int main(void)
{double test[6] = {1.0, 2.0, 5.0, -5.0, 9.5, 3.14159}; printf("%lg\n", mean(test, 6)); return 0;}</lang>
C++
<lang cpp>#include <vector>
double mean(const std::vector<double>& numbers) {
if (numbers.size() == 0) return 0;
double sum = 0; for (std::vector<double>::iterator i = numbers.begin(); i != numbers.end(); i++) sum += *i; return sum / numbers.size();
}</lang>
Shorter (and more idiomatic) version:
<lang cpp>#include <vector>
- include <algorithm>
double mean(const std::vector<double>& numbers) {
if (numbers.empty()) return 0; return std::accumulate(numbers.begin(), numbers.end(), 0.0) / numbers.size();
}</lang>
C#
<lang csharp>using System.Linq;
static double avg(ICollection<int> i) {
if (i == null || i.Count == 0) return 0; return i.Sum() / (double)i.Count;
}
static void Main(string[] args) {
int[] numbers = new int[] {1, 2, 3, 4, 5, 6, 7, 8}; Console.WriteLine(avg(numbers));
}</lang>
C# already has a builtin Average function.
<lang csharp>static void Main(string[] args) {
int[] numbers = new int[] {1, 2, 3, 4, 5, 6, 7, 8}; Console.WriteLine(numbers.Average());
}</lang>
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): <lang fortran> real, target, 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)</lang>
Haskell
This function works if the element type is an instance of Fractional:
mean :: (Fractional a) => [a] -> a mean [] = 0 mean xs = sum xs / Data.List.genericLength xs
But some types, e.g. integers, are not Fractional; the following function works for all Real types:
meanReals :: (Real a, Fractional b) => [a] -> b meanReals = mean . map realToFrac
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
Lucid
avg(x) where sum = first(x) fby sum + next(x); n = 1 fby n + 1; avg = sum / n; end
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))
Nial
in the standard way, mean is
mean is / [sum, tally]
mean 6 2 4 = 4
but it fails with 0 length vectors. so using a tally with a minimum value 1
dtally is recur [ empty rest, 1 first, 1 first, plus, rest ] mean is / [sum, dtally]
mean [] =0
OCaml
These functions return a float:
<lang ocaml>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)</lang>
the previous code is easier to read and understand, though if you which the fastest implementation to use in production code notice several points: it is possible to save a call to List.length computing the length through the List.fold_left, and for mean_ints it is possible to save calling float_of_int on every numbers, converting only the result of the addition. (also when using List.map and the order is not important, you can use List.rev_map instead to save an internal List.rev.) Also the task asks to return 0 on empty lists, but in OCaml this case would rather be handled by an exception.
<lang ocaml>let mean_floats xs =
if xs = [] then invalid_arg "empty list" else let total, length = List.fold_left (fun (tot,len) x -> (x +. tot), len +. 1.) (0., 0.) xs in (total /. length)
let mean_ints xs =
if xs = [] then invalid_arg "empty list" else let total, length = List.fold_left (fun (tot,len) x -> (x + tot), len +. 1.) (0, 0.) xs in (float total /. length)
- </lang>
Octave
GNU Octave has a mean function (from statistics package), but it does not handle an empty vector; an implementation that allows that is:
<lang octave>function m = omean(l)
if ( numel(l) == 0 ) m = 0; else m = mean(l); endif
endfunction
disp(omean([])); disp(omean([1,2,3]));</lang>
Perl
<lang perl>sub avg {
@_ or return 0; my $sum = 0; $sum += $_ foreach @_; return $sum/@_;
}
print avg(qw(3 1 4 1 5 9)), "\n";</lang>
With module Data::Average. (For zero-length arrays, returns the empty list.) <lang perl>use Data::Average;
my $d = Data::Average->new; $d->add($_) foreach qw(3 1 4 1 5 9); print $d->avg, "\n";</lang>
PHP
<lang php>$nums = array(3, 1, 4, 1, 5, 9); if ($nums)
echo array_sum($nums) / count($nums), "\n";
else
echo "0\n";</lang>
Pop11
define mean(v); lvars n = length(v), i, s = 0; if n = 0 then return(0); else for i from 1 to n do s + v(i) -> s; endfor; endif; return(s/n); enddefine;
Python
.
Uses fsum which tracks multiple partial sums to avoid losing precision <lang python>from math import fsum def average(x):
return fsum(x)/float(len(x)) if x else 0
print (average([3,1,4,1,5,9])) print (average([1e20,3,1,4,1,5,9,-1e20]))</lang>
Output:
<lang python>3.83333333333333
2.875</lang>
<lang python>def average(x):
return sum(x)/float(len(x)) if x else 0
print average([3,1,4,1,5,9]) print average([1e20,3,1,4,1,5,9,-1e20])</lang>
Output
(Notice how the second call gave the wrong result)
<lang python>3.83333333333333
0.0 </lang>
<lang python>def avg(data): if len(data)==0: return 0 else: return sum(data)/float(len(data)) print avg([3,1,4,1,5,9])</lang>
Output:
<lang python>3.83333333333333</lang>
Ruby
<lang ruby>nums = [3, 1, 4, 1, 5, 9] nums.empty? ? 0 : nums.inject(:+) / Float(nums.size)</lang>
Scheme
<lang scheme>(define (mean l)
(if (null? l) 0 (/ (apply + l) (length l))))</lang>
> (mean (list 3 1 4 1 5 9)) 3 5/6
Smalltalk
<lang smalltalk>| numbers | numbers := #(1, 2, 3, 4, 5, 6, 7, 8). ^numbers isEmpty ifTrue:[0]
ifFalse: [ (numbers inject: 0 into: [:sum :aNumber | sum + aNumber]) / numbers size ]</lang>
Standard ML
These functions return a real:
<lang sml>fun mean_reals [] = 0.0
| mean_reals xs = foldl op+ 0.0 xs / real (length xs);
val mean_ints = mean_reals o (map real);</lang>
the previous code is easier to read and understand, though if you which
the fastest implementation to use in production code notice several points:
it is possible to save a call to length
computing the length through
the foldl
, and for mean_ints it is possible to save calling
real
on every numbers, converting only the result of the addition.
Also the task asks to return 0 on empty lists, but in Standard ML this case
would rather be handled by an exception.
<lang sml>fun mean_reals [] = raise Empty
| mean_reals xs = let val (total, length) = foldl (fn (x, (tot,len)) => (x + tot, len + 1.0)) (0.0, 0.0) xs in (total / length) end;
fun mean_ints [] = raise Empty
| mean_ints xs = let val (total, length) = foldl (fn (x, (tot,len)) => (x + tot, len + 1.0)) (0, 0.0) xs in (real total / length) end;
</lang>
Tcl
<lang tcl>proc mean args {
if {[set num [llength $args]] == 0} {return 0} expr "([join $args +]) / double($num)"
} mean 3 1 4 1 5 9 ;# ==> 3.8333333333333335</lang>
UnixPipes
term() { b=$1;res=$2 echo "scale=5;$res+$b" | bc }
sum() { (read B; res=$1; test -n "$B" && (term $B $res) || (term 0 $res)) }
fold() { func=$1 (while read a ; do fold $func | $func $a done) }
mean() { tee >(wc -l > count) | fold sum | xargs echo "scale=5;(1/" $(cat count) ") * " | bc }
(echo 3; echo 1; echo 4) | mean
V
[mean [sum 0 [+] fold]. dup sum swap size [[1 <] [1]] when / ].