Last active
February 18, 2016 03:08
-
-
Save stripe-q/20d4a8cbc1ec9f32b486 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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