Skip to content

Commit 3456ca3

Browse files
committed
Simplify UniquePermutations.Iterator.next()
1 parent 62fb2f9 commit 3456ca3

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

Sources/Algorithms/Permutations.swift

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ extension UniquePermutations: Sequence {
445445
}
446446

447447
@usableFromInline
448-
var state = State.start
448+
var initial = true
449449

450450
@usableFromInline
451451
var lengths: Range<Int>
@@ -458,27 +458,29 @@ extension UniquePermutations: Sequence {
458458

459459
@inlinable
460460
public mutating func next() -> ArraySlice<Element>? {
461-
switch state {
462-
case .start:
463-
state = .middle
461+
// In the end case, `lengths` is an empty range.
462+
if lengths.isEmpty {
463+
return nil
464+
}
465+
466+
// The first iteration must produce the original sorted array, before any
467+
// permutations. We skip the permutation the first time so that we can
468+
// always mutate the array _before_ returning a slice, which avoids
469+
// copying when possible.
470+
if initial {
471+
initial = false
464472
return elements[..<lengths.lowerBound]
465-
case .middle:
466-
if !elements.nextPermutation(upperBound: lengths.lowerBound) {
467-
lengths = (lengths.lowerBound + 1)..<lengths.upperBound
473+
}
468474

469-
if lengths.isEmpty {
470-
state = .end
471-
return nil
472-
}
475+
if !elements.nextPermutation(upperBound: lengths.lowerBound) {
476+
lengths = (lengths.lowerBound + 1)..<lengths.upperBound
473477

474-
elements.sort()
475-
state = .start
478+
if lengths.isEmpty {
479+
return nil
476480
}
477-
return elements[..<lengths.lowerBound]
478-
479-
case .end:
480-
return nil
481481
}
482+
483+
return elements[..<lengths.lowerBound]
482484
}
483485
}
484486

0 commit comments

Comments
 (0)