1
- import assert from 'assert' ;
2
- import { _take } from '@iterable-iterator/slice' ;
3
-
4
1
import { list } from '@iterable-iterator/list' ;
5
- import { pick } from '@iterable-iterator/map' ;
6
- import {
7
- forwardRangeIterator ,
8
- backwardRangeIterator ,
9
- } from '@iterable-iterator/range' ;
2
+ import { map , pick } from '@iterable-iterator/map' ;
3
+
4
+ import _permutations from './_permutations.js' ;
10
5
11
6
/**
12
7
* Yields all permutations of each possible choice of <code>r</code> elements
@@ -24,48 +19,12 @@ import {
24
19
* @param {number } r - The size of the permutations to generate.
25
20
* @returns {IterableIterator }
26
21
*/
27
- export default function * permutations ( iterable , r ) {
28
- assert ( Number . isInteger ( r ) && r >= 0 ) ;
22
+ const permutations = ( iterable , r ) => {
29
23
const pool = list ( iterable ) ;
24
+ return map (
25
+ ( indices ) => list ( pick ( pool , indices ) ) ,
26
+ _permutations ( pool . length , r ) ,
27
+ ) ;
28
+ } ;
30
29
31
- const length = pool . length ;
32
-
33
- if ( r > length ) {
34
- return ;
35
- }
36
-
37
- const indices = list ( forwardRangeIterator ( 0 , length , 1 ) ) ;
38
- const cycles = list ( backwardRangeIterator ( length , length - r , - 1 ) ) ;
39
-
40
- yield list ( pick ( pool , _take ( indices , r ) ) ) ;
41
-
42
- if ( r === 0 || length === 0 ) {
43
- return ;
44
- }
45
-
46
- while ( true ) {
47
- let i = r ;
48
-
49
- while ( i -- ) {
50
- -- cycles [ i ] ;
51
-
52
- if ( cycles [ i ] === 0 ) {
53
- // Could be costly
54
- indices . push ( indices . splice ( i , 1 ) [ 0 ] ) ;
55
-
56
- cycles [ i ] = length - i ;
57
- } else {
58
- const j = cycles [ i ] ;
59
-
60
- [ indices [ i ] , indices [ length - j ] ] = [ indices [ length - j ] , indices [ i ] ] ;
61
-
62
- yield list ( pick ( pool , _take ( indices , r ) ) ) ;
63
- break ;
64
- }
65
- }
66
-
67
- if ( i === - 1 ) {
68
- return ;
69
- }
70
- }
71
- }
30
+ export default permutations ;
0 commit comments