Created
February 7, 2018 15:29
-
-
Save icedraco/9b6da9c4aa8af3a9b5174dfb7c573e72 to your computer and use it in GitHub Desktop.
Kotlin permutation generator function: creates sequences
This file contains hidden or 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
/* 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