@@ -134,36 +134,91 @@ extension TypeIdentifier
134
134
}
135
135
}
136
136
137
- func _forAllPermutationsImpl(
138
- _ index: Int , _ size: Int ,
139
- _ perm: inout [ Int ] , _ visited: inout [ Bool ] ,
140
- _ body: ( [ Int ] ) -> Void
141
- ) {
142
- if index == size {
143
- body ( perm)
144
- return
137
+ enum FormNextPermutationResult {
138
+ case success
139
+ case formedFirstPermutation
140
+ }
141
+
142
+ extension MutableCollection
143
+ where
144
+ Self : BidirectionalCollection ,
145
+ Iterator. Element : Comparable
146
+ {
147
+ mutating func _reverseSubrange( _ subrange: Range < Index > ) {
148
+ if subrange. isEmpty { return }
149
+ var f = subrange. lowerBound
150
+ var l = index ( before: subrange. upperBound)
151
+ while f < l {
152
+ swap ( & self [ f] , & self [ l] )
153
+ formIndex ( after: & f)
154
+ formIndex ( before: & l)
155
+ }
145
156
}
146
157
147
- for i in 0 ..< size {
148
- if visited [ i] {
149
- continue
158
+ mutating func formNextPermutation( ) -> FormNextPermutationResult {
159
+ if isEmpty {
160
+ // There are 0 elements, only one permutation is possible.
161
+ return . formedFirstPermutation
162
+ }
163
+
164
+ do {
165
+ var i = startIndex
166
+ formIndex ( after: & i)
167
+ if i == endIndex {
168
+ // There is only element, only one permutation is possible.
169
+ return . formedFirstPermutation
170
+ }
171
+ }
172
+
173
+ var i = endIndex
174
+ formIndex ( before: & i)
175
+ var beforeI = i
176
+ formIndex ( before: & beforeI)
177
+ var elementAtI = self [ i]
178
+ var elementAtBeforeI = self [ beforeI]
179
+ while true {
180
+ if elementAtBeforeI < elementAtI {
181
+ // Elements at `i..<endIndex` are in non-increasing order. To form the
182
+ // next permutation in lexicographical order we need to replace
183
+ // `self[i-1]` with the next larger element found in the tail, and
184
+ // reverse the tail. For example:
185
+ //
186
+ // i-1 i endIndex
187
+ // V V V
188
+ // 6 2 8 7 4 1 [ ] // Input.
189
+ // 6 (4) 8 7 (2) 1 [ ] // Exchanged self[i-1] with the
190
+ // ^--------^ // next larger element
191
+ // // from the tail.
192
+ // 6 4 (1)(2)(7)(8)[ ] // Reversed the tail.
193
+ // <-------->
194
+ var j = endIndex
195
+ repeat {
196
+ formIndex ( before: & j)
197
+ } while !( elementAtBeforeI < self [ j] )
198
+ swap ( & self [ beforeI] , & self [ j] )
199
+ _reverseSubrange ( i..< endIndex)
200
+ return . success
201
+ }
202
+ if beforeI == startIndex {
203
+ // All elements are in non-increasing order. Reverse to form the first
204
+ // pemutation, where all elements are sorted (in non-increasing order).
205
+ reverse ( )
206
+ return . formedFirstPermutation
207
+ }
208
+ i = beforeI
209
+ formIndex ( before: & beforeI)
210
+ elementAtI = elementAtBeforeI
211
+ elementAtBeforeI = self [ beforeI]
150
212
}
151
- visited [ i] = true
152
- perm [ index] = i
153
- _forAllPermutationsImpl ( index + 1 , size, & perm, & visited, body)
154
- visited [ i] = false
155
213
}
156
214
}
157
215
158
216
/// Generate all permutations.
159
217
public func forAllPermutations( _ size: Int , body: ( [ Int ] ) -> Void ) {
160
- if size == 0 {
161
- return
162
- }
163
-
164
- var permutation = [ Int] ( repeating: 0 , count: size)
165
- var visited = [ Bool] ( repeating: false , count: size)
166
- _forAllPermutationsImpl ( 0 , size, & permutation, & visited, body)
218
+ var data = Array ( 0 ..< size)
219
+ repeat {
220
+ body ( data)
221
+ } while data. formNextPermutation ( ) != . formedFirstPermutation
167
222
}
168
223
169
224
/// Generate all permutations.
0 commit comments