combinationsWithRep.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import { factory } from '../../utils/factory.js';
  2. import { isInteger } from '../../utils/number.js';
  3. import { product } from '../../utils/product.js';
  4. var name = 'combinationsWithRep';
  5. var dependencies = ['typed'];
  6. export var createCombinationsWithRep = /* #__PURE__ */factory(name, dependencies, _ref => {
  7. var {
  8. typed
  9. } = _ref;
  10. /**
  11. * Compute the number of ways of picking `k` unordered outcomes from `n`
  12. * possibilities, allowing individual outcomes to be repeated more than once.
  13. *
  14. * CombinationsWithRep only takes integer arguments.
  15. * The following condition must be enforced: k <= n + k -1.
  16. *
  17. * Syntax:
  18. *
  19. * math.combinationsWithRep(n, k)
  20. *
  21. * Examples:
  22. *
  23. * math.combinationsWithRep(7, 5) // returns 462
  24. *
  25. * See also:
  26. *
  27. * combinations, permutations, factorial
  28. *
  29. * @param {number | BigNumber} n Total number of objects in the set
  30. * @param {number | BigNumber} k Number of objects in the subset
  31. * @return {number | BigNumber} Number of possible combinations with replacement.
  32. */
  33. return typed(name, {
  34. 'number, number': function numberNumber(n, k) {
  35. if (!isInteger(n) || n < 0) {
  36. throw new TypeError('Positive integer value expected in function combinationsWithRep');
  37. }
  38. if (!isInteger(k) || k < 0) {
  39. throw new TypeError('Positive integer value expected in function combinationsWithRep');
  40. }
  41. if (n < 1) {
  42. throw new TypeError('k must be less than or equal to n + k - 1');
  43. }
  44. if (k < n - 1) {
  45. var _prodrange = product(n, n + k - 1);
  46. return _prodrange / product(1, k);
  47. }
  48. var prodrange = product(k + 1, n + k - 1);
  49. return prodrange / product(1, n - 1);
  50. },
  51. 'BigNumber, BigNumber': function BigNumberBigNumber(n, k) {
  52. var BigNumber = n.constructor;
  53. var result, i;
  54. var one = new BigNumber(1);
  55. var nMinusOne = n.minus(one);
  56. if (!isPositiveInteger(n) || !isPositiveInteger(k)) {
  57. throw new TypeError('Positive integer value expected in function combinationsWithRep');
  58. }
  59. if (n.lt(one)) {
  60. throw new TypeError('k must be less than or equal to n + k - 1 in function combinationsWithRep');
  61. }
  62. result = one;
  63. if (k.lt(nMinusOne)) {
  64. for (i = one; i.lte(nMinusOne); i = i.plus(one)) {
  65. result = result.times(k.plus(i)).dividedBy(i);
  66. }
  67. } else {
  68. for (i = one; i.lte(k); i = i.plus(one)) {
  69. result = result.times(nMinusOne.plus(i)).dividedBy(i);
  70. }
  71. }
  72. return result;
  73. }
  74. });
  75. });
  76. /**
  77. * Test whether BigNumber n is a positive integer
  78. * @param {BigNumber} n
  79. * @returns {boolean} isPositiveInteger
  80. */
  81. function isPositiveInteger(n) {
  82. return n.isInteger() && n.gte(0);
  83. }