UNPKG

2.41 kBJavaScriptView Raw
1'use strict'
2
3const isInteger = require('../../utils/number').isInteger
4
5function factory (type, config, load, typed) {
6 const factorial = load(require('./factorial'))
7 const product = require('./product')
8 /**
9 * Compute the number of ways of obtaining an ordered subset of `k` elements
10 * from a set of `n` elements.
11 *
12 * Permutations only takes integer arguments.
13 * The following condition must be enforced: k <= n.
14 *
15 * Syntax:
16 *
17 * math.permutations(n)
18 * math.permutations(n, k)
19 *
20 * Examples:
21 *
22 * math.permutations(5) // 120
23 * math.permutations(5, 3) // 60
24 *
25 * See also:
26 *
27 * combinations, factorial
28 *
29 * @param {number | BigNumber} n The number of objects in total
30 * @param {number | BigNumber} [k] The number of objects in the subset
31 * @return {number | BigNumber} The number of permutations
32 */
33 const permutations = typed('permutations', {
34 'number | BigNumber': factorial,
35 'number, number': function (n, k) {
36 if (!isInteger(n) || n < 0) {
37 throw new TypeError('Positive integer value expected in function permutations')
38 }
39 if (!isInteger(k) || k < 0) {
40 throw new TypeError('Positive integer value expected in function permutations')
41 }
42 if (k > n) {
43 throw new TypeError('second argument k must be less than or equal to first argument n')
44 }
45 // Permute n objects, k at a time
46 return product((n - k) + 1, n)
47 },
48
49 'BigNumber, BigNumber': function (n, k) {
50 let result, i
51
52 if (!isPositiveInteger(n) || !isPositiveInteger(k)) {
53 throw new TypeError('Positive integer value expected in function permutations')
54 }
55 if (k.gt(n)) {
56 throw new TypeError('second argument k must be less than or equal to first argument n')
57 }
58
59 result = new type.BigNumber(1)
60 for (i = n.minus(k).plus(1); i.lte(n); i = i.plus(1)) {
61 result = result.times(i)
62 }
63
64 return result
65 }
66
67 // TODO: implement support for collection in permutations
68 })
69
70 permutations.toTex = undefined // use default template
71
72 return permutations
73}
74
75/**
76 * Test whether BigNumber n is a positive integer
77 * @param {BigNumber} n
78 * @returns {boolean} isPositiveInteger
79 */
80function isPositiveInteger (n) {
81 return n.isInteger() && n.gte(0)
82}
83
84exports.name = 'permutations'
85exports.factory = factory