serializable and hashable BitArray. Comparable BitList. Small improvements
This commit is contained in:
parent
2696f1546d
commit
3481a718b1
@ -21,10 +21,10 @@ import lyng.time
|
|||||||
//
|
//
|
||||||
// After all optimizations it takes ~120ms.
|
// After all optimizations it takes ~120ms.
|
||||||
//
|
//
|
||||||
//for( r in 1..100 ) {
|
for( r in 1..100 ) {
|
||||||
// val start = Instant.now()
|
val start = Instant.now()
|
||||||
val found = naiveCountHappyNumbers()
|
val found = naiveCountHappyNumbers()
|
||||||
// println("Found happy numbers: %d time %s"(found, Instant.now() - start))
|
println("Found happy numbers: %d time %s"(found, Instant.now() - start))
|
||||||
assert( found == 55252 )
|
assert( found == 55252 )
|
||||||
// delay(0.01)
|
delay(0.1)
|
||||||
//}
|
}
|
@ -21,7 +21,7 @@ import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
|
|
||||||
group = "net.sergeych"
|
group = "net.sergeych"
|
||||||
version = "0.9.1-SNAPSHOT"
|
version = "0.9.2-SNAPSHOT"
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
@ -66,6 +66,7 @@ kotlin {
|
|||||||
// iosArm64()
|
// iosArm64()
|
||||||
// iosSimulatorArm64()
|
// iosSimulatorArm64()
|
||||||
linuxX64()
|
linuxX64()
|
||||||
|
linuxArm64()
|
||||||
js {
|
js {
|
||||||
browser()
|
browser()
|
||||||
nodejs()
|
nodejs()
|
||||||
@ -79,9 +80,9 @@ kotlin {
|
|||||||
sourceSets {
|
sourceSets {
|
||||||
all {
|
all {
|
||||||
languageSettings.optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
|
languageSettings.optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
|
||||||
languageSettings.optIn("kotlin.contracts.ExperimentalContracts")
|
|
||||||
languageSettings.optIn("kotlin.ExperimentalUnsignedTypes")
|
languageSettings.optIn("kotlin.ExperimentalUnsignedTypes")
|
||||||
languageSettings.optIn("kotlin.coroutines.DelicateCoroutinesApi")
|
languageSettings.optIn("kotlin.coroutines.DelicateCoroutinesApi")
|
||||||
|
languageSettings.optIn("kotlin.contracts.ExperimentalContracts")
|
||||||
languageSettings.optIn("kotlinx.coroutines.flow.DelicateCoroutinesApi")
|
languageSettings.optIn("kotlinx.coroutines.flow.DelicateCoroutinesApi")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,6 +164,7 @@ class CompilerContext(val tokens: List<Token>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun addBreak() {
|
inline fun addBreak() {
|
||||||
breakFound = true
|
breakFound = true
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import net.sergeych.lynon.ObjLynonClass
|
|||||||
import net.sergeych.mp_tools.globalDefer
|
import net.sergeych.mp_tools.globalDefer
|
||||||
import kotlin.math.*
|
import kotlin.math.*
|
||||||
|
|
||||||
|
@Suppress("TYPE_INTERSECTION_AS_REIFIED_WARNING")
|
||||||
class Script(
|
class Script(
|
||||||
override val pos: Pos,
|
override val pos: Pos,
|
||||||
private val statements: List<Statement> = emptyList(),
|
private val statements: List<Statement> = emptyList(),
|
||||||
|
@ -367,6 +367,7 @@ open class Obj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun from(obj: Any?): Obj {
|
inline fun from(obj: Any?): Obj {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return when (obj) {
|
return when (obj) {
|
||||||
|
@ -35,12 +35,12 @@ class ObjBitBuffer(val bitArray: BitArray) : Obj() {
|
|||||||
}.apply {
|
}.apply {
|
||||||
addFn("toBuffer") {
|
addFn("toBuffer") {
|
||||||
requireNoArgs()
|
requireNoArgs()
|
||||||
ObjBuffer(thisAs<ObjBitBuffer>().bitArray.asUbyteArray())
|
ObjBuffer(thisAs<ObjBitBuffer>().bitArray.asUByteArray())
|
||||||
}
|
}
|
||||||
addFn("toDump") {
|
addFn("toDump") {
|
||||||
requireNoArgs()
|
requireNoArgs()
|
||||||
ObjString(
|
ObjString(
|
||||||
thisAs<ObjBitBuffer>().bitArray.asUbyteArray().toDump()
|
thisAs<ObjBitBuffer>().bitArray.asUByteArray().toDump()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
addFn("size") {
|
addFn("size") {
|
||||||
|
@ -17,8 +17,10 @@
|
|||||||
|
|
||||||
package net.sergeych.lynon
|
package net.sergeych.lynon
|
||||||
|
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
interface BitList {
|
interface BitList: Comparable<BitList> {
|
||||||
operator fun get(bitIndex: Long): Int
|
operator fun get(bitIndex: Long): Int
|
||||||
operator fun set(bitIndex: Long,value: Int)
|
operator fun set(bitIndex: Long,value: Int)
|
||||||
val size: Long
|
val size: Long
|
||||||
@ -31,6 +33,22 @@ interface BitList {
|
|||||||
if( index < size) this@BitList[index++]
|
if( index < size) this@BitList[index++]
|
||||||
else null
|
else null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun compareTo(other: BitList): Int {
|
||||||
|
val m = min(size, other.size)
|
||||||
|
for( i in 0 ..< m) {
|
||||||
|
val a = this[i]
|
||||||
|
val b = other[i]
|
||||||
|
when {
|
||||||
|
a < b -> return -1
|
||||||
|
a > b -> return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( size > other.size) return 1
|
||||||
|
if( size < other.size) return -1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bitListOf(vararg bits: Int): BitList {
|
fun bitListOf(vararg bits: Int): BitList {
|
||||||
|
@ -17,13 +17,18 @@
|
|||||||
|
|
||||||
package net.sergeych.lynon
|
package net.sergeych.lynon
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BitList implementation as fixed suze array of bits; indexing works exactly same as if
|
* BitList implementation as fixed suze array of bits; indexing works exactly same as if
|
||||||
* [MemoryBitInput] is used with [MemoryBitInput.getBit]. See [MemoryBitOutput] for
|
* [MemoryBitInput] is used with [MemoryBitInput.getBit]. See [MemoryBitOutput] for
|
||||||
* bits order and more information.
|
* bits order and more information.
|
||||||
|
*
|
||||||
|
* It is [BitList] - comparable, and provides valid [hashCode] and [equals], so it could
|
||||||
|
* also be used as a key in maps.
|
||||||
*/
|
*/
|
||||||
|
@Serializable
|
||||||
class BitArray(val bytes: UByteArray, val lastByteBits: Int) : BitList {
|
class BitArray(val bytes: UByteArray, val lastByteBits: Int) : BitList {
|
||||||
|
|
||||||
val bytesSize: Int get() = bytes.size
|
val bytesSize: Int get() = bytes.size
|
||||||
@ -73,7 +78,15 @@ class BitArray(val bytes: UByteArray, val lastByteBits: Int) : BitList {
|
|||||||
fun asByteArray(): ByteArray = bytes.asByteArray()
|
fun asByteArray(): ByteArray = bytes.asByteArray()
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun asUbyteArray(): UByteArray = bytes
|
fun asUByteArray(): UByteArray = bytes
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
return other is BitList && this.compareTo(other) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return bytes.contentHashCode()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
package net.sergeych.lynon
|
package net.sergeych.lynon
|
||||||
|
|
||||||
import net.sergeych.collections.SortedList
|
import net.sergeych.collections.SortedList
|
||||||
import net.sergeych.lynon.Huffman.Alphabet
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -285,7 +284,7 @@ object Huffman {
|
|||||||
|
|
||||||
fun <T>decompress(bin: BitInput,alphabet: Alphabet<T>): UByteArray {
|
fun <T>decompress(bin: BitInput,alphabet: Alphabet<T>): UByteArray {
|
||||||
val codes = deserializeCanonicCodes(bin, alphabet)
|
val codes = deserializeCanonicCodes(bin, alphabet)
|
||||||
return decompressUsingCodes(bin, codes, alphabet).asUbyteArray()
|
return decompressUsingCodes(bin, codes, alphabet).asUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -56,7 +56,7 @@ object ObjLynonClass : ObjClass("Lynon") {
|
|||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
suspend fun lynonEncodeAny(scope: Scope, value: Obj): UByteArray =
|
suspend fun lynonEncodeAny(scope: Scope, value: Obj): UByteArray =
|
||||||
(ObjLynonClass.encodeAny(scope, value))
|
(ObjLynonClass.encodeAny(scope, value))
|
||||||
.bitArray.asUbyteArray()
|
.bitArray.asUByteArray()
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
suspend fun lynonDecodeAny(scope: Scope, encoded: UByteArray): Obj =
|
suspend fun lynonDecodeAny(scope: Scope, encoded: UByteArray): Obj =
|
||||||
|
@ -22,7 +22,10 @@ import net.sergeych.lyng.Source
|
|||||||
import net.sergeych.lyng.eval
|
import net.sergeych.lyng.eval
|
||||||
import net.sergeych.lyng.pacman.InlineSourcesImportProvider
|
import net.sergeych.lyng.pacman.InlineSourcesImportProvider
|
||||||
import net.sergeych.lyng.toSource
|
import net.sergeych.lyng.toSource
|
||||||
|
import net.sergeych.lynon.BitArray
|
||||||
|
import net.sergeych.lynon.BitList
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertNotEquals
|
||||||
|
|
||||||
class OtherTests {
|
class OtherTests {
|
||||||
@Test
|
@Test
|
||||||
@ -67,4 +70,33 @@ class OtherTests {
|
|||||||
Unit
|
Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testBitArrayEqAndHash() {
|
||||||
|
|
||||||
|
val b1 = BitArray.ofBits(1, 0, 1, 1)
|
||||||
|
val b11 = BitArray.ofBits(1, 0, 1, 1)
|
||||||
|
val b2 = BitArray.ofBits(1, 1, 1, 1)
|
||||||
|
val b3 = BitArray.ofBits(1, 0, 1, 1, 0)
|
||||||
|
|
||||||
|
assert( b3 > b1 )
|
||||||
|
assert( b2 > b1)
|
||||||
|
assert( b11.compareTo(b1) == 0)
|
||||||
|
|
||||||
|
assertEquals(b1, b11)
|
||||||
|
assertNotEquals(b1, b2)
|
||||||
|
assertNotEquals(b1, b3)
|
||||||
|
|
||||||
|
assert( b1.hashCode() == b11.hashCode() )
|
||||||
|
|
||||||
|
val x = mutableMapOf<BitList,String>()
|
||||||
|
x[b1] = "wrong"
|
||||||
|
x[b11] = "OK"
|
||||||
|
x[b2] = "other"
|
||||||
|
|
||||||
|
assertEquals("OK", x[b11])
|
||||||
|
assertEquals("OK", x[b1])
|
||||||
|
assertEquals("other", x[b2])
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user