Skip to content

Commit a6fab1e

Browse files
committed
Add uniquePermutations as wrapper for nextPermutation
1 parent d2546b8 commit a6fab1e

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

Sources/Algorithms/Permutations.swift

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,3 +359,82 @@ extension Collection {
359359
return Permutations(self, k: k)
360360
}
361361
}
362+
363+
//===----------------------------------------------------------------------===//
364+
// uniquePermutations()
365+
//===----------------------------------------------------------------------===//
366+
367+
public struct UniquePermutations<Element: Comparable> {
368+
@usableFromInline
369+
let elements: [Element]
370+
371+
@inlinable
372+
init<S: Sequence>(_ elements: S) where S.Element == Element {
373+
self.elements = elements.sorted()
374+
}
375+
}
376+
377+
extension UniquePermutations: Sequence {
378+
public struct Iterator: IteratorProtocol {
379+
@usableFromInline
380+
var elements: [Element]
381+
382+
@usableFromInline
383+
var finished = false
384+
385+
@inlinable
386+
init(_ elements: [Element]) {
387+
self.elements = elements
388+
}
389+
390+
@inlinable
391+
public mutating func next() -> [Element]? {
392+
if finished {
393+
return nil
394+
} else {
395+
defer { finished = !elements.nextPermutation() }
396+
return elements
397+
}
398+
}
399+
}
400+
401+
@inlinable
402+
public func makeIterator() -> Iterator {
403+
Iterator(elements)
404+
}
405+
}
406+
407+
extension Sequence where Element: Comparable {
408+
/// Returns a sequence of the unique permutations of this sequence.
409+
///
410+
/// Use this method to iterate over the unique permutations of a sequence
411+
/// with repeating elements. This example prints every permutation of an
412+
/// array of numbers:
413+
///
414+
/// let numbers = [1, 2, 2]
415+
/// for perm in numbers.uniquePermutations() {
416+
/// print(perm)
417+
/// }
418+
/// // [1, 2, 2]
419+
/// // [2, 1, 2]
420+
/// // [2, 2, 1]
421+
///
422+
/// By contrast, the unadorned `permutations()` method permutes over a
423+
/// collection by position, which includes permutations with equal elements
424+
/// in each permutation:
425+
///
426+
/// for perm in numbers.permutations()
427+
/// print(perm)
428+
/// }
429+
/// // [1, 2, 2]
430+
/// // [1, 2, 2]
431+
/// // [2, 1, 2]
432+
/// // [2, 2, 1]
433+
/// // [2, 1, 2]
434+
/// // [2, 2, 1]
435+
///
436+
/// The returned permutations are in lexicographically sorted order.
437+
public func uniquePermutations() -> UniquePermutations<Element> {
438+
UniquePermutations(self)
439+
}
440+
}

0 commit comments

Comments
 (0)