Averages/Pythagorean means
Compute all three of the Pythagorean means of the set of integers 1 through 10.
You are encouraged to solve this task according to the task description, using any language you may know.
Show that for this set of positive integers.
- The most common of the three means, the arithmetic mean, is the sum of the list divided by its length:
- The geometric mean is the th root of the product of the list:
- The harmonic mean is divided by the sum of the reciprocal of each item in the list:
Clojure
<lang lisp>(use '[clojure.contrib.math :only (expt)])
(defn a-mean [coll]
(/ (reduce + coll) (count coll)))
(defn g-mean [coll]
(expt (reduce * coll) (/ (count coll))))
(defn h-mean [coll]
(/ (count coll) (reduce + (map / coll))))
(let [numbers (range 1 11)
a (a-mean numbers) g (g-mean numbers) h (h-mean numbers)] (println a ">=" g ">=" h) (>= a g h))</lang>
Factor
<lang factor>: a-mean ( seq -- mean )
[ sum ] [ length ] bi / ;
- g-mean ( seq -- mean )
[ product ] [ length recip ] bi ^ ;
- h-mean ( seq -- mean )
[ length ] [ [ recip ] map-sum ] bi / ;</lang>
( scratchpad ) 10 [1,b] [ a-mean ] [ g-mean ] [ h-mean ] tri "%f >= %f >= %f\n" printf 5.500000 >= 4.528729 >= 3.414172
Fortran
<lang fortran>program Mean
real :: a(10) = (/ (i, i=1,10) /) real :: amean, gmean, hmean
amean = sum(a) / size(a) gmean = product(a)**(1.0/size(a)) hmean = size(a) / sum(1.0/a)
if ((amean < gmean) .or. (gmean < hmean)) then print*, "Error!" else print*, amean, gmean, hmean end if
end program Mean</lang>
Haskell
The general function given here yields an arithmetic mean when its first argument is 1
, a geometric mean when its first argument is 0
, and a harmonic mean when its first argument is -1
.
<lang haskell>import Data.List (genericLength) import Control.Monad (zipWithM_)
mean :: Double -> [Double] -> Double mean 0 xs = product xs ** (1 / genericLength xs) mean p xs = (1 / genericLength xs * sum (map (** p) xs)) ** (1/p)
main = zipWithM_ f "agh" (map (flip mean [1 .. 10]) [1, 0, -1])
where f c n = putStrLn $ c : ": " ++ show n</lang>
J
Solution: <lang j>amean=: +/ % # gmean=: # %: */ hmean=: amean&.:%</lang>
Example Usage: <lang j> (amean , gmean , hmean) >: i. 10 5.5 4.528729 3.414172
assert 2 >:/\ (amean , gmean , hmean) >: i. 10 NB. check amean >= gmean and gmean >= hmean</lang>
Lua
<lang lua>function fsum(f, a, ...) return a and f(a) + fsum(f, ...) or 0 end function pymean(t, f, finv) return finv(fsum(f, unpack(t)) / #t) end nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
--arithmetic a = pymean(nums, function(n) return n end, function(n) return n end) --geometric g = pymean(nums, math.log, math.exp) --harmonic h = pymean(nums, function(n) return 1/n end, function(n) return 1/n end) print(a, g, h) assert(a >= g and g >= h)</lang>
Oz
<lang oz>declare
%% helpers fun {Sum Xs} {FoldL Xs Number.'+' 0.0} end fun {Product Xs} {FoldL Xs Number.'*' 1.0} end fun {Len Xs} {Int.toFloat {Length Xs}} end
fun {AMean Xs} {Sum Xs} / {Len Xs} end
fun {GMean Xs} {Pow {Product Xs} 1.0/{Len Xs}} end
fun {HMean Xs} {Len Xs} / {Sum {Map Xs fun {$ X} 1.0 / X end}} end
Numbers = {Map {List.number 1 10 1} Int.toFloat}
[A G H] = [{AMean Numbers} {GMean Numbers} {HMean Numbers}]
in
{Show [A G H]} A >= G = true G >= H = true</lang>
PL/I
<lang PL/I> declare n fixed binary,
(Average, Geometric, Harmonic) float;
declare A(10) float static initial (1,2,3,4,5,6,7,8,9,10);
n = hbound(A,1);
/* compute the average */ Average = sum(A)/n;
/* Compute the geometric mean: */ Geometric = prod(A)**(1/n);
/* Compute the Harmonic mean: */ Harmonic = n / sum(1/A);
put skip data (Average); put skip data (Geometric); put skip data (Harmonic);
if Average < Geometric then put skip list ('Error'); if Geometric < Harmonic then put skip list ('Error'); </lang>
Python
<lang Python>from operator import mul from functools import reduce
def amean(num): return sum(num)/len(num)
def gmean(num): return reduce(mul, num, 1)**(1/len(num))
def hmean(num): return len(num)/sum(1/n for n in num)
numbers = range(1,11) # 1..10 a, g, h = amean(numbers), gmean(numbers), hmean(numbers) print(a, g, h) assert( a >= g >= h ) </lang>
Output:
5.5 4.52872868812 3.41417152147
Tcl
<lang tcl>proc arithmeticMean list {
set sum 0.0 foreach value $list { set sum [expr {$sum + $value}] } return [expr {$sum / [llength $list]}]
} proc geometricMean list {
set product 1.0 foreach value $list { set product [expr {$product * $value}] } return [expr {$product ** (1.0/[llength $list])}]
} proc harmonicMean list {
set sum 0.0 foreach value $list { set sum [expr {$sum + 1.0/$value}] } return [expr {[llength $list] / $sum}]
}
set nums {1 2 3 4 5 6 7 8 9 10} set A10 [arithmeticMean $nums] set G10 [geometricMean $nums] set H10 [harmonicMean $nums] puts "A10=$A10, G10=$G10, H10=$H10" if {$A10 >= $G10} { puts "A10 >= G10" } if {$G10 >= $H10} { puts "G10 >= H10" }</lang>
Output:
A10=5.5, G10=4.528728688116765, H10=3.414171521474055 A10 >= G10 G10 >= H10