Averages/Arithmetic mean: Difference between revisions
m (Added works with template, removed whitespace) |
(added D code) |
||
Line 84: | Line 84: | ||
0 |
0 |
||
(/ (reduce #'+ sequence) length)))) |
(/ (reduce #'+ sequence) length)))) |
||
=={{header|D}}== |
|||
Using template to make the mean function work for higher-rank array. |
|||
<pre>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()) ; |
|||
}</pre> |
|||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
: fmean ( addr n -- f ) |
: fmean ( addr n -- f ) |
Revision as of 15:20, 24 February 2008
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
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
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