All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.it.unibo.tuprolog.utils.IterUtils.kt Maven / Gradle / Ivy

There is a newer version: 0.17.4
Show newest version
@file:JvmName("IterUtils")

package it.unibo.tuprolog.utils

import kotlin.jvm.JvmName

fun  merge(comparator: Comparator, iterables: Iterable>): Sequence {
    return sequence {
        val pipeline = iterables.asSequence().map { it.cursor() }.filterNot { it.isOver }.toMutableList()
        while (pipeline.isNotEmpty()) {
            val (minIndex, minValue) = pipeline.asSequence().map { it.current!! }.indexed().minWith(
                Comparator> { a, b -> comparator.compare(a.value, b.value) }
            )!!
            yield(minValue)
            pipeline[minIndex].next.let {
                if (it.isOver) {
                    pipeline.removeAt(minIndex)
                } else {
                    pipeline[minIndex] = it
                }
            }
        }
    }
}

fun  merge(iterables: Iterable>, comparator: (T, T) -> Int): Sequence {
    return merge(Comparator(comparator), iterables)
}

fun  merge(vararg iterables: Iterable, comparator: (T, T) -> Int): Sequence {
    return merge(Comparator(comparator), *iterables)
}

fun  merge(comparator: Comparator, vararg iterables: Iterable): Sequence {
    return merge(comparator, listOf(*iterables))
}

fun  merge(iterables: Sequence>, comparator: (T, T) -> Int): Sequence {
    return merge(Comparator(comparator), iterables)
}

fun  merge(comparator: Comparator, iterables: Sequence>): Sequence {
    return merge(comparator, iterables.asIterable())
}

fun  mergeSequences(iterables: Iterable>, comparator: (T, T) -> Int): Sequence {
    return merge(Comparator(comparator), iterables.map { it.asIterable() })
}

fun  mergeSequences(comparator: Comparator, iterables: Iterable>): Sequence {
    return merge(comparator, iterables.map { it.asIterable() })
}

fun  mergeSequences(iterables: Sequence>, comparator: (T, T) -> Int): Sequence {
    return merge(Comparator(comparator), iterables.map { it.asIterable() }.asIterable())
}

fun  mergeSequences(comparator: Comparator, iterables: Sequence>): Sequence {
    return merge(comparator, iterables.map { it.asIterable() }.asIterable())
}

fun  mergeSequences(vararg iterables: Sequence, comparator: (T, T) -> Int): Sequence {
    return merge(Comparator(comparator), iterables.map { it.asIterable() })
}

fun  mergeSequences(comparator: Comparator, vararg iterables: Sequence): Sequence {
    return merge(comparator, iterables.map { it.asIterable() })
}

fun  Sequence.product(other: Sequence, combinator: (T, U) -> R): Sequence =
    flatMap { x ->
        other.map { y -> combinator(x, y) }
    }

fun  Sequence.product(other: Sequence): Sequence> =
    product(other, ::Pair)

fun  Sequence.squared(combinator: (T, T) -> R): Sequence =
    product(this, combinator)

fun  Sequence.squared(): Sequence> =
    product(this)

fun  Sequence.longIndexed(): Sequence> =
    zip(LongRange(0, Long.MAX_VALUE).asSequence()) { it, i ->
        LongIndexed.of(i, it)
    }

fun  Sequence.indexed(): Sequence> =
    zip(IntRange(0, Int.MAX_VALUE).asSequence()) { it, i ->
        IntIndexed.of(i, it)
    }

fun  interleave(iterables: Iterable>): Sequence =
    sequence {
        val pipeline = iterables.asSequence()
            .map { it.iterator() }
            .filter { it.hasNext() }
            .toList()
        var nNonEmpty = pipeline.size
        while (nNonEmpty > 0) {
            nNonEmpty = 0
            for (iter in pipeline) {
                if (iter.hasNext()) {
                    nNonEmpty++
                    yield(iter.next())
                }
            }
        }
    }

fun  interleave(vararg iterables: Iterable): Sequence =
    interleave(iterables.asIterable())

fun  interleave(iterables: Sequence>): Sequence =
    interleave(iterables.asIterable())

fun  interleaveSequences(vararg iterables: Sequence): Sequence =
    interleave(sequenceOf(*iterables).map { it.asIterable() }.asIterable())

fun  interleaveSequences(iterables: Sequence>): Sequence =
    interleave(iterables.map { it.asIterable() }.asIterable())

fun  interleaveSequences(iterables: Iterable>): Sequence =
    interleave(iterables.map { it.asIterable() })

fun  Sequence.subsequences(): Sequence> {
    return sequence {
        var maxSize = 1
        var actualSize = 0
        while (true) {
            val sublist = [email protected](maxSize).toList()
            yield(sublist.asSequence())
            if (actualSize >= sublist.size) {
                break
            }
            maxSize++
            actualSize = sublist.size
        }
    }
}

fun  itemWiseEquals(iterable1: Iterable, iterable2: Iterable, comparator: (T, T) -> Boolean): Boolean {
    val i = iterable1.iterator()
    val j = iterable2.iterator()
    while (i.hasNext() && j.hasNext()) {
        if (!comparator(i.next(), j.next())) {
            return false
        }
    }
    return i.hasNext() == j.hasNext()
}

fun  itemWiseEquals(iterable1: Iterable, iterable2: Iterable): Boolean =
    itemWiseEquals(iterable1, iterable2) { a, b -> a == b }

fun  itemWiseEquals(sequence1: Sequence, sequence2: Sequence, comparator: (T, T) -> Boolean): Boolean {
    return itemWiseEquals(sequence1.asIterable(), sequence2.asIterable(), comparator)
}

fun  itemWiseEquals(sequence1: Sequence, sequence2: Sequence): Boolean {
    return itemWiseEquals(sequence1.asIterable(), sequence2.asIterable())
}

fun  itemWiseHashCode(vararg items: T): Int {
    return itemWiseHashCode(items.asIterable())
}

fun  itemWiseHashCode(iterable: Iterable): Int {
    var hash = 13
    val i = iterable.iterator()
    while (i.hasNext()) {
        hash = 31 * hash + (i.next()?.hashCode() ?: 0)
    }
    return hash
}

fun  itemWiseHashCode(sequence: Sequence): Int {
    return itemWiseHashCode(sequence.asIterable())
}


fun  Iterable.subsequences(): Sequence> {
    return asSequence().subsequences()
}

fun  subsequences(vararg items: T): Sequence> {
    return sequenceOf(*items).subsequences()
}

fun  Sequence.buffered(): Sequence {
    return this.toList().asSequence()
}

fun  Sequence.skipIndex(index: Int): Sequence {
    require(index >= 0)
    return sequence {
        var i = 0
        val iter = iterator()
        while (i < index && iter.hasNext()) {
            yield(iter.next())
            i++
        }
        if (iter.hasNext()) iter.next()
        while (iter.hasNext()) {
            yield(iter.next())
        }
    }
}

fun  permutations(vararg items: T): Sequence> =
    items.toList().permutations()

fun  Iterable.permutations(): Sequence> =
    toList().permutations()

fun  Sequence.permutations(): Sequence> =
    toList().permutations()

fun  List.permutations(): Sequence> =
    when (size) {
        0, 1 -> sequenceOf(this)
        2 -> sequenceOf(this, asReversed())
        else -> {
            asSequence().indexed().flatMap { (i, head) ->
                [email protected]()
                    .skipIndex(i)
                    .toList()
                    .permutations()
                    .map { listOf(head) + it }
            }
        }
    }