1- import assert from 'assert' ;
2- import { _take } from '@iterable-iterator/slice' ;
3-
41import { 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' ;
105
116/**
127 * Yields all permutations of each possible choice of <code>r</code> elements
@@ -24,48 +19,12 @@ import {
2419 * @param {number } r - The size of the permutations to generate.
2520 * @returns {IterableIterator }
2621 */
27- export default function * permutations ( iterable , r ) {
28- assert ( Number . isInteger ( r ) && r >= 0 ) ;
22+ const permutations = ( iterable , r ) => {
2923 const pool = list ( iterable ) ;
24+ return map (
25+ ( indices ) => list ( pick ( pool , indices ) ) ,
26+ _permutations ( pool . length , r ) ,
27+ ) ;
28+ } ;
3029
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