Cartesian product, and there's no real solution in...
# random
k
Cartesian product, and there's no real solution in Kotlin except for nested loops I think.
r
Is there a general algorithm for an N dimensional Cartesian product? I was hoping to avoid all the intermediate lists created by many 2D Cartesian products.
k
I've been looking for a while but now I've got an idea, give me a couple of minutes.
r
Sweet, thanks
k
Copy code
fun <T> List<List<T>>.cartesian(): List<List<T>> {
    val resultSize = this.fold(1) { a, l -> a * l.size }
    return List(resultSize) { i ->
        var left = resultSize - i
        this.map { list ->
            val j = left % list.size
            left /= list.size
            list[j]
        }
    }
}
Not that happy mutating things from within a
map
but oh well.
Also this should probably be lazy, a sequence or something like that.
r
@alex Thanks, I'll definitely read through that.
@karelpeeters That works pretty well, though the order is all wrong, but that shouldn't be too hard to fix. Thanks!
k
Ah I thought
resultSize - i
fixed it but I didn't actually check simple smile
Looks like Guava does the same thing:
(index / axesSizeProduct[axis + 1]) % axes.get(axis).size()
r
It looks like that just moved the last iteration to the beginning, but left the rest in the same order.
k
this.asReversed().map { ... }.asReversed()
and just
var left = i
does fix it.
But that's not great either.
r
Indeed
141 Views