Skip to content

Instantly share code, notes, and snippets.

@icedraco
Created February 7, 2018 15:29
Show Gist options
  • Save icedraco/9b6da9c4aa8af3a9b5174dfb7c573e72 to your computer and use it in GitHub Desktop.
Save icedraco/9b6da9c4aa8af3a9b5174dfb7c573e72 to your computer and use it in GitHub Desktop.
Kotlin permutation generator function: creates sequences
/* Created by IceDragon on 07-Feb-2018 */
import kotlin.coroutines.experimental.buildSequence
fun permutations(items: List<Any?>, qty: Int): Sequence<List<Any?>> = buildSequence {
if (items.size < qty || qty == 0)
return@buildSequence
val availableIndices = Array<Int?>(items.size, { it })
val iterators = Array<Iterator<Int>>(qty, { (0 until availableIndices.size).iterator() })
val accumulator = Array<Int?>(qty, { null })
var index = 0
while (index >= 0) {
if (index >= qty) {
yield(accumulator.map { i -> items[i!!] }.toList()) // <-- return a permutation
index--
} else {
if (iterators[index].hasNext()) {
// return the value we took (if any)
if (accumulator[index] != null) {
availableIndices[accumulator[index]!!] = accumulator[index]
accumulator[index] = null
}
// take the value from available indices and store it
val selectedIndex = iterators[index].next()
accumulator[index] = availableIndices[selectedIndex]
availableIndices[selectedIndex] = null
if (accumulator[index] != null) {
index++
}
} else {
// return the value we took
if (accumulator[index] != null) {
availableIndices[accumulator[index]!!] = accumulator[index]
accumulator[index] = null
}
// reset iterator
iterators[index] = (0 until availableIndices.size).iterator()
index--
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment