Skip to content

Instantly share code, notes, and snippets.

@stripe-q
Last active February 18, 2016 03:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stripe-q/20d4a8cbc1ec9f32b486 to your computer and use it in GitHub Desktop.
Save stripe-q/20d4a8cbc1ec9f32b486 to your computer and use it in GitHub Desktop.
private func perms <T>(pos: Int, _ arr:[T]) -> [T] {
let divmod: (Int, Int) -> (Int, Int)? = { a, b in
guard b != 0 else { return nil }
return (a / b, a % b)
}
let factorial: (Int) -> Int = { x in
if x < 2 { return nil }
return Array(2...x).reduce(1, combine: *)
}
let l = arr.count
let n = pos % factorial(l)
if n > 0,
let (q, r) = divmod(n, factorial(l - 1))
{
let head = [arr[q]]
let tail = perms(r, Array(arr[0..<q]) + Array(arr[q+1..<l]))
return head + tail
}
return arr
}
extension String {
struct StringGenerator: GeneratorType {
typealias Element = String
var idx = 0
let data: [Character]
let limit: Int
init(string: String){
self.data = Array(string.characters)
limit = factorial(string.characters.count)
}
mutating func next() -> Element? {
guard idx < limit else { return nil }
let result = perms(idx, data)
idx += 1
return String(result)
}
}
struct StringPermutation: SequenceType {
typealias Element = String
var data: String?
init(string: String) {
self.data = string
}
func generate() -> StringGenerator {
var g = StringGenerator(string:data!)
return g
}
}
func permutations() -> StringPermutation {
return StringPermutation(string: self)
}
}
let a = "abcd"
for i in a.permutations() {
print(i)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment