ddc-code-0.4.2.1: tetra/base/Math/Combinations.ds
module Math.Combinations
export { factorial
; choose; chooseMany }
import Data.Numeric.Nat
import Data.List
where
-- | Compute the factorial of a number.
--
-- factorial n is the number of possible permutations
-- of a sequence of n things.
--
factorial (n: Nat#): Nat#
= if n == 0
then 1
else n * factorial (n - 1)
-- | Compute the number of was of choosing r things from n things.
---
-- Note that the textbook definition of this is,
-- div (factorial n) ( factorial (n - 1) * factorial r )
-- but we factor out the (factorial (n - 1)) term beforehand to
-- make it easier to compute.
--
choose (n r: Nat#): Nat#
= if r > n
then 0
else div (prodRange n (n - (r - 1))) (factorial r)
-- | Compute the product of the range [n, n-1 .. m] inclusive.
prodRange (n m: Nat#): Nat#
= if n == m
then n
else n * prodRange (n - 1) m
-- | Compute the number of ways of choosing collections of things
-- of sizes rs from n things.
chooseMany (n: Nat#) (rs: List Nat#): Nat#
= div (factorial n) (prod (map factorial rs))