Add permutation & combination procedures to core:math/big

This commit is contained in:
Feoramund
2024-06-09 20:29:09 -04:00
parent 4ea593bde0
commit 5fbd876db1

View File

@@ -0,0 +1,60 @@
package math_big
/*
With `n` items, calculate how many ways that `r` of them can be ordered.
*/
permutations_with_repetition :: int_pow_int
/*
With `n` items, calculate how many ways that `r` of them can be ordered without any repeats.
*/
permutations_without_repetition :: proc(dest: ^Int, n, r: int) -> (error: Error) {
if n == r {
return factorial(dest, n)
}
tmp := &Int{}
defer internal_destroy(tmp)
// n!
// --------
// (n - r)!
factorial(dest, n) or_return
factorial(tmp, n - r) or_return
div(dest, dest, tmp) or_return
return
}
/*
With `n` items, calculate how many ways that `r` of them can be chosen.
Also known as the multiset coefficient or (n multichoose k).
*/
combinations_with_repetition :: proc(dest: ^Int, n, r: int) -> (error: Error) {
// (n + r - 1)!
// ------------
// r! (n - 1)!
return combinations_without_repetition(dest, n + r - 1, r)
}
/*
With `n` items, calculate how many ways that `r` of them can be chosen without any repeats.
Also known as the binomial coefficient or (n choose k).
*/
combinations_without_repetition :: proc(dest: ^Int, n, r: int) -> (error: Error) {
tmp_a, tmp_b := &Int{}, &Int{}
defer internal_destroy(tmp_a, tmp_b)
// n!
// ------------
// r! (n - r)!
factorial(dest, n) or_return
factorial(tmp_a, r) or_return
factorial(tmp_b, n - r) or_return
mul(tmp_a, tmp_a, tmp_b) or_return
div(dest, dest, tmp_a) or_return
return
}