「JavaScript: 配列の直積を返すジェネレータを作ってみた」に倣い、
順列組み合わせの次には直積をやってみる。
こちらは元記事とは異なるアルゴリズム。
/** 直積(可変長引数版) */
fun <T> product(vararg optionsArray: List<T>): Sequence<List<T>> {
if (optionsArray.isEmpty()) {
return emptySequence()
}
return productInternal(optionsArray.asList())
}
/** 直積(リスト版) */
fun <T> List<List<T>>.product(): Sequence<List<T>> {
if (isEmpty()) {
return emptySequence()
}
return productInternal(this)
}
private fun <T> productInternal(optionsList: List<List<T>>): Sequence<List<T>> {
if (optionsList.isEmpty()) {
return sequenceOf(emptyList())
}
return sequence {
optionsList.first().forEach { first ->
productInternal(optionsList.drop(1)).forEach {
yield(listOf(first) + it)
}
}
}
}
使用例:
fun main() {
product(listOf(0, 1), listOf(2, 3), listOf(4, 5))
.also { println(it.toList()) }
// > [[0, 2, 4], [0, 2, 5], [0, 3, 4], [0, 3, 5], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5]]
}
/以上