@@ -57,9 +57,11 @@ extension MutableCollection
57
57
}
58
58
}
59
59
}
60
+ }
60
61
62
+ extension MutableCollection where Self: BidirectionalCollection {
61
63
@inlinable
62
- internal mutating func nextPermutation( upperBound: Index ) -> Bool {
64
+ internal mutating func nextPermutation( upperBound: Index , by areInIncreasingOrder : ( Element , Element ) -> Bool ) -> Bool {
63
65
// Ensure we have > 1 element in the collection.
64
66
guard !isEmpty else { return false }
65
67
var i = index ( before: endIndex)
@@ -70,10 +72,10 @@ extension MutableCollection
70
72
formIndex ( before: & i)
71
73
72
74
// Find the last ascending pair (ie. ..., a, b, ... where a < b)
73
- if self [ i] < self [ ip1] {
75
+ if areInIncreasingOrder ( self [ i] , self [ ip1] ) {
74
76
// Find the last element greater than self[i]
75
77
// This is _always_ at most `ip1` due to if statement above
76
- let j = lastIndex ( where: { $0 > self [ i] } ) !
78
+ let j = lastIndex ( where: { areInIncreasingOrder ( self [ i] , $0 ) } ) !
77
79
78
80
// At this point we have something like this:
79
81
// 0, 1, 4, 3, 2
@@ -410,23 +412,27 @@ extension Collection {
410
412
// uniquePermutations()
411
413
//===----------------------------------------------------------------------===//
412
414
413
- public struct UniquePermutations < Element: Comparable > {
415
+ public struct UniquePermutations < Element> {
414
416
@usableFromInline
415
417
internal let elements : [ Element ]
416
418
417
419
@usableFromInline
418
420
internal let kRange : Range < Int >
419
421
422
+ @usableFromInline
423
+ internal let areInIncreasingOrder : ( Element , Element ) -> Bool
424
+
420
425
@inlinable
421
- internal init < S: Sequence > ( _ elements: S ) where S. Element == Element {
422
- self . init ( elements, 0 ..< Int . max)
426
+ internal init < S: Sequence > ( _ elements: S , by areInIncreasingOrder : @escaping ( Element , Element ) -> Bool ) where S. Element == Element {
427
+ self . init ( elements, 0 ..< Int . max, by : areInIncreasingOrder )
423
428
}
424
429
425
430
@inlinable
426
- internal init < S: Sequence , R: RangeExpression > ( _ elements: S , _ range: R )
431
+ internal init < S: Sequence , R: RangeExpression > ( _ elements: S , _ range: R , by areInIncreasingOrder : @escaping ( Element , Element ) -> Bool )
427
432
where S. Element == Element , R. Bound == Int
428
433
{
429
- self . elements = elements. sorted ( )
434
+ self . elements = elements. sorted ( by: areInIncreasingOrder)
435
+ self . areInIncreasingOrder = areInIncreasingOrder
430
436
431
437
let upperBound = self . elements. count + 1
432
438
self . kRange = range. relative ( to: 0 ..< . max)
@@ -438,22 +444,21 @@ extension UniquePermutations: Sequence {
438
444
public struct Iterator : IteratorProtocol {
439
445
@usableFromInline
440
446
var elements : [ Element ]
441
-
442
- @usableFromInline
443
- enum State {
444
- case start, middle, end
445
- }
446
-
447
+
447
448
@usableFromInline
448
449
var initial = true
449
450
450
451
@usableFromInline
451
452
var lengths : Range < Int >
452
453
454
+ @usableFromInline
455
+ internal let areInIncreasingOrder : ( Element , Element ) -> Bool
456
+
453
457
@inlinable
454
- init ( _ elements: [ Element ] , lengths: Range < Int > ) {
458
+ init ( _ elements: [ Element ] , lengths: Range < Int > , by areInIncreasingOrder : @escaping ( Element , Element ) -> Bool ) {
455
459
self . elements = elements
456
460
self . lengths = lengths
461
+ self . areInIncreasingOrder = areInIncreasingOrder
457
462
}
458
463
459
464
@inlinable
@@ -472,7 +477,7 @@ extension UniquePermutations: Sequence {
472
477
return elements [ ..< lengths. lowerBound]
473
478
}
474
479
475
- if !elements. nextPermutation ( upperBound: lengths. lowerBound) {
480
+ if !elements. nextPermutation ( upperBound: lengths. lowerBound, by : areInIncreasingOrder ) {
476
481
lengths = ( lengths. lowerBound + 1 ) ..< lengths. upperBound
477
482
478
483
if lengths. isEmpty {
@@ -486,7 +491,7 @@ extension UniquePermutations: Sequence {
486
491
487
492
@inlinable
488
493
public func makeIterator( ) -> Iterator {
489
- Iterator ( elements, lengths: kRange)
494
+ Iterator ( elements, lengths: kRange, by : areInIncreasingOrder )
490
495
}
491
496
}
492
497
@@ -521,16 +526,32 @@ extension Sequence where Element: Comparable {
521
526
///
522
527
/// The returned permutations are in lexicographically sorted order.
523
528
public func uniquePermutations( ) -> UniquePermutations < Element > {
524
- UniquePermutations ( self )
529
+ UniquePermutations ( self , by : < )
525
530
}
526
531
527
532
public func uniquePermutations( ofCount k: Int ) -> UniquePermutations < Element > {
528
- UniquePermutations ( self , k ..< ( k + 1 ) )
533
+ UniquePermutations ( self , k ..< ( k + 1 ) , by : < )
529
534
}
530
535
531
536
public func uniquePermutations< R: RangeExpression > ( ofCount kRange: R ) -> UniquePermutations < Element >
532
537
where R. Bound == Int
533
538
{
534
- UniquePermutations ( self , kRange)
539
+ UniquePermutations ( self , kRange, by: < )
540
+ }
541
+ }
542
+
543
+ extension Sequence {
544
+ public func uniquePermutations( by areInIncreasingOrder: @escaping ( Element , Element ) -> Bool ) -> UniquePermutations < Element > {
545
+ UniquePermutations ( self , by: areInIncreasingOrder)
546
+ }
547
+
548
+ public func uniquePermutations( ofCount k: Int , by areInIncreasingOrder: @escaping ( Element , Element ) -> Bool ) -> UniquePermutations < Element > {
549
+ UniquePermutations ( self , k ..< ( k + 1 ) , by: areInIncreasingOrder)
550
+ }
551
+
552
+ public func uniquePermutations< R: RangeExpression > ( ofCount kRange: R , by areInIncreasingOrder: @escaping ( Element , Element ) -> Bool ) -> UniquePermutations < Element >
553
+ where R. Bound == Int
554
+ {
555
+ UniquePermutations ( self , kRange, by: areInIncreasingOrder)
535
556
}
536
557
}
0 commit comments