Skip to content

Instantly share code, notes, and snippets.

@turtton
Last active September 11, 2023 16:48
Show Gist options
  • Save turtton/9fec208b71aaf2c4139370ca7b1e2a17 to your computer and use it in GitHub Desktop.
Save turtton/9fec208b71aaf2c4139370ca7b1e2a17 to your computer and use it in GitHub Desktop.
ネストしたリストを総当たりするやつ(round robin forEach for elements of nested list
inline fun <T> List<List<T>>.roundRobinnedForEach(action: (List<T>) -> Unit) {
NestedElementCollector(this).collect().forEach(action)
}
inline fun <T> List<T>.timesOf(action: (T) -> Int): Int {
var result = 1
for (element in this) {
result *= action(element)
}
return result
}
class NestedElementCollector<T>(private val list: List<List<T>>) {
private val currentIndexMap = mutableMapOf<Int, Int>()
fun collect(): List<List<T>> =
(0 until list.timesOf { it.size }).map { next() }
fun next(): List<T> {
val result = list.mapIndexed { index, list ->
val currentIndex = currentIndexMap.getOrDefault(index, 0)
list[currentIndex]
}
plusIndex()
return result
}
private fun plusIndex(current: Int = 0) {
val nextIndex = currentIndexMap.getOrDefault(current, 0).plus(1) % list[current].size
currentIndexMap[current] = nextIndex
if (nextIndex == 0 && current < list.lastIndex) {
plusIndex(current + 1)
}
}
}
// using kotest
import io.kotest.core.spec.style.FunSpec
import io.kotest.datatest.withData
import io.kotest.matchers.collections.shouldContain
import io.kotest.matchers.shouldBe
import NestedElementCollector
class TestCollection : FunSpec({
val internal = (0..4).toList()
val combined = listOf(internal, internal, internal)
val roundRobin = NestedElementCollector(combined).collect()
context("RoundRobin") {
var calculated = 0
withData(internal) { first ->
withData(internal) { second ->
withData(internal) { third ->
calculated++
roundRobin shouldContain listOf(first, second, third)
}
}
}
test("calculated should be same as roundRobin.size") {
calculated shouldBe roundRobin.size
}
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment