diff --git a/README.md b/README.md index 2648188..467ecab 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ repositories { } dependencies { - implementation("me.alex_s168:blitz:0.22h2") + implementation("me.alex_s168:blitz:0.23") } ``` diff --git a/build.gradle.kts b/build.gradle.kts index 4129277..64e6740 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } group = "me.alex_s168" -version = "0.22h2" +version = "0.23" repositories { mavenCentral() diff --git a/src/main/kotlin/blitz/collections/ByteVec.kt b/src/main/kotlin/blitz/collections/ByteVec.kt index 8faee02..ad6f169 100644 --- a/src/main/kotlin/blitz/collections/ByteVec.kt +++ b/src/main/kotlin/blitz/collections/ByteVec.kt @@ -135,6 +135,9 @@ class ByteVec(private val initCap: Int = 0): Vec, ByteBatchSequence { array[index] = value } + override fun idx(value: Byte): Int = + array.indexOf(value) + companion object { fun from(bytes: ByteArray) = ByteVec(bytes.size).also { diff --git a/src/main/kotlin/blitz/collections/CharVec.kt b/src/main/kotlin/blitz/collections/CharVec.kt index 2e44a8d..2b98969 100644 --- a/src/main/kotlin/blitz/collections/CharVec.kt +++ b/src/main/kotlin/blitz/collections/CharVec.kt @@ -135,6 +135,9 @@ class CharVec(private val initCap: Int = 0): Vec, BatchSequence { array[index] = value } + override fun idx(value: Char): Int = + array.indexOf(value) + companion object { fun from(data: String) = CharVec(data.length).also { diff --git a/src/main/kotlin/blitz/collections/IntVec.kt b/src/main/kotlin/blitz/collections/IntVec.kt index 7cb2c45..c59c029 100644 --- a/src/main/kotlin/blitz/collections/IntVec.kt +++ b/src/main/kotlin/blitz/collections/IntVec.kt @@ -132,6 +132,9 @@ class IntVec(private val initCap: Int = 0): Vec, BatchSequence { array[index] = value } + override fun idx(value: Int): Int = + array.indexOf(value) + companion object { fun from(bytes: IntArray) = IntVec(bytes.size).also { diff --git a/src/main/kotlin/blitz/collections/LightCache.kt b/src/main/kotlin/blitz/collections/LightCache.kt new file mode 100644 index 0000000..dfdbdb2 --- /dev/null +++ b/src/main/kotlin/blitz/collections/LightCache.kt @@ -0,0 +1,51 @@ +package blitz.collections + +class LightCache( + private val keys: Vec, + private val vals: Vec, +) { + private var lastKey: K? = null + private var lastVal: V? = null + + @Suppress("UNCHECKED_CAST") + fun getOrPut(key: K, compute: (K) -> V): V { + if (key == lastKey) + return (lastVal as V) + val idx = keys.indexOf(key) + val v = if (idx >= 0) { + vals[idx] + } else { + val x = compute(key) + keys.pushBack(key) + vals.pushBack(x) + x + } + lastKey = key + lastVal = v + return v + } + + internal fun getOrNullInternal(key: K): V? { + if (key == lastKey) + return lastVal + val idx = keys.indexOf(key) + return if (idx >= 0) { + lastKey = key + lastVal = vals[idx] + lastVal + } else { + null + } + } + + companion object { + inline fun new(initCap: Int = 0): LightCache = + LightCache( + SmartVec(initCap), + SmartVec(initCap), + ) + } +} + +fun LightCache.getOrNull(key: K): V? = + getOrNullInternal(key) \ No newline at end of file diff --git a/src/main/kotlin/blitz/collections/LongVec.kt b/src/main/kotlin/blitz/collections/LongVec.kt index 3c6f15a..d8a51c4 100644 --- a/src/main/kotlin/blitz/collections/LongVec.kt +++ b/src/main/kotlin/blitz/collections/LongVec.kt @@ -132,6 +132,9 @@ class LongVec(private val initCap: Int = 0): Vec, BatchSequence { array[index] = value } + override fun idx(value: Long): Int = + array.indexOf(value) + companion object { fun from(bytes: LongArray) = LongVec(bytes.size).also { diff --git a/src/main/kotlin/blitz/collections/RefVec.kt b/src/main/kotlin/blitz/collections/RefVec.kt index dd33fbc..00064ae 100644 --- a/src/main/kotlin/blitz/collections/RefVec.kt +++ b/src/main/kotlin/blitz/collections/RefVec.kt @@ -101,6 +101,9 @@ class RefVec(private val initCap: Int = 0): Vec { inline fun map(fn: (T) -> R): MutableList = MutableList(size) { fn(this[it]) } + override fun idx(value: T): Int = + _array?.indexOf(value) ?: -1 + companion object { fun from(data: Array) = RefVec(data.size).also { diff --git a/src/main/kotlin/blitz/collections/SequenceOps.kt b/src/main/kotlin/blitz/collections/SequenceOps.kt index 7cabe6c..105e0ab 100644 --- a/src/main/kotlin/blitz/collections/SequenceOps.kt +++ b/src/main/kotlin/blitz/collections/SequenceOps.kt @@ -41,4 +41,39 @@ fun Sequence.limit(len: Int): Sequence = } fun IndexableSequence.limitBy(other: Sequence): IndexableSequence = - modifier { it.limitBy(other) } \ No newline at end of file + modifier { it.limitBy(other) } + +fun Sequence.hasLeast(n: Int): Boolean { + val i = iterator() + repeat(n) { + if (!i.hasNext()) + return false + i.next() + } + return true +} + +/** cache already computed values across iterations */ +fun Sequence.caching(): Sequence = + object : Sequence { + val cache = RefVec() + val iter = this@caching.iterator() + + override fun iterator() = object : Iterator { + var idx = 0 + + override fun hasNext(): Boolean = + idx < cache.size || iter.hasNext() + + override fun next(): T { + val v = if (idx < cache.size) { + cache[idx] + } else { + iter.next() + .also(cache::pushBack) + } + idx ++ + return v + } + } + } diff --git a/src/main/kotlin/blitz/collections/ShortVec.kt b/src/main/kotlin/blitz/collections/ShortVec.kt index 4534372..23914dd 100644 --- a/src/main/kotlin/blitz/collections/ShortVec.kt +++ b/src/main/kotlin/blitz/collections/ShortVec.kt @@ -132,6 +132,9 @@ class ShortVec(private val initCap: Int = 0): Vec, BatchSequence { array[index] = value } + override fun idx(value: Short): Int = + array.indexOf(value) + companion object { fun from(bytes: ShortArray) = ShortVec(bytes.size).also { diff --git a/src/main/kotlin/blitz/collections/Vec.kt b/src/main/kotlin/blitz/collections/Vec.kt index a091f26..99e8542 100644 --- a/src/main/kotlin/blitz/collections/Vec.kt +++ b/src/main/kotlin/blitz/collections/Vec.kt @@ -37,4 +37,12 @@ interface Vec: IndexableSequence { operator fun set(index: Int, value: T) fun clear() + + fun idx(value: T): Int { + for (i in 0 until size) { + if (this[i] == value) + return i + } + return -1 + } } \ No newline at end of file