combinatorics.odin 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. package math_big
  2. /*
  3. With `n` items, calculate how many ways that `r` of them can be ordered.
  4. */
  5. permutations_with_repetition :: int_pow_int
  6. /*
  7. With `n` items, calculate how many ways that `r` of them can be ordered without any repeats.
  8. */
  9. permutations_without_repetition :: proc(dest: ^Int, n, r: int) -> (error: Error) {
  10. if n == r {
  11. return factorial(dest, n)
  12. }
  13. tmp := &Int{}
  14. defer internal_destroy(tmp)
  15. // n!
  16. // --------
  17. // (n - r)!
  18. factorial(dest, n) or_return
  19. factorial(tmp, n - r) or_return
  20. div(dest, dest, tmp) or_return
  21. return
  22. }
  23. /*
  24. With `n` items, calculate how many ways that `r` of them can be chosen.
  25. Also known as the multiset coefficient or (n multichoose k).
  26. */
  27. combinations_with_repetition :: proc(dest: ^Int, n, r: int) -> (error: Error) {
  28. // (n + r - 1)!
  29. // ------------
  30. // r! (n - 1)!
  31. return combinations_without_repetition(dest, n + r - 1, r)
  32. }
  33. /*
  34. With `n` items, calculate how many ways that `r` of them can be chosen without any repeats.
  35. Also known as the binomial coefficient or (n choose k).
  36. */
  37. combinations_without_repetition :: proc(dest: ^Int, n, r: int) -> (error: Error) {
  38. tmp_a, tmp_b := &Int{}, &Int{}
  39. defer internal_destroy(tmp_a, tmp_b)
  40. // n!
  41. // ------------
  42. // r! (n - r)!
  43. factorial(dest, n) or_return
  44. factorial(tmp_a, r) or_return
  45. factorial(tmp_b, n - r) or_return
  46. mul(tmp_a, tmp_a, tmp_b) or_return
  47. div(dest, dest, tmp_a) or_return
  48. return
  49. }