librarylibs/Combinatorics/src/Combinatorics.xtl
Combinatorics: counting and listing -- factorials, binomials, combinations, permutations, subsets, Cartesian products. Import it with an alias of your choice: "cb:" u_se< "Combinatorics". Put libs/Combinatorics/src on XETAL_PATH ("just path"); the reference is libs/Combinatorics/docs. Names with l: are exported; those under h: are private to this file.
Lists come as matrices, one combination (or permutation, subset, pair) per row, in lexicographic order.
Counting
ˡf̲actorial : Int -> Int
f_actorial n: n!, item by item (0! is 1).
ˡf̲actorial ← { n → '{ '× r̲/ r̲ange ⍵ } e̲ach n }
ʰc̲h : Int -> Int -> Int
C(n, k) for one k and n, exactly: C(n, j) = C(n, j - 1) * (n - j + 1) / j.
ʰc̲h ← { k n → (k < 0) ∨ k > n ? 0 j ← k m̲in n − k j = 0 ? 1 ((1 + n − j) × (j − 1) ʰc̲h n) d̲iv j }
ˡc̲hoose : Int -> Int -> Int
k c_hoose n: how many ways to choose k things of n, item by item.
ˡc̲hoose ← { k n → k 'ʰc̲h e̲ach n }
Listing
ˡc̲ombinations : Int -> Int -> Int
k c_ombinations n: every choice of k of 1..n, one per row, in lexicographic order (dfns cmat).
ˡc̲ombinations ← { k n → (k < 0) ∨ k > n ? (0 c̲at k) r̲eshape 0 k = 0 ? 1 0 r̲eshape 0 k = n ? (1 c̲at n) r̲eshape r̲ange n (1 c̲at₂ 1 + (k − 1) ˡc̲ombinations n − 1) c̲at 1 + k ˡc̲ombinations n − 1 }
ʰf̲irstThen : (Num a, Truthy a) => a -> a -> a
The rows of P (permutations of 1..n-1) with i put first and the others renumbered around it.
ʰf̲irstThen ← { i p → i c̲at₂ p + p ≥ i }
ˡp̲ermutations : Int -> Int
p_ermutations n: every ordering of 1..n, one per row, in lexicographic order (dfns pmat).
ˡp̲ermutations ← { n → n ≤ 1 ? (1 c̲at n) r̲eshape 1 p ← ˡp̲ermutations n − 1 d̲isclose '{ e̲nclose (d̲isclose ⍺) c̲at d̲isclose ⍵ } r̲/ '{ i → i ʰf̲irstThen p } m̲ap r̲ange n }
ˡs̲ubsets : Int -> Int
s_ubsets n: every subset of 1..n as a mask, one per row: 2^n rows, counting in binary (the empty set first).
ˡs̲ubsets ← { n → o̲\ (n r̲eshape 2) e̲ncode o̲ffsets 2 ^ n }
ˡp̲owerset : a -> Box a
p_owerset v: every subset of the items of v, as a list (Box), in the order of s_ubsets.
ˡp̲owerset ← { v → m ← ˡs̲ubsets t̲ally v '{ i → (i s̲elect m) r̲eplicate v } m̲ap r̲ange t̲ally m }