sorted* moved to Iterable
in-place List sort v0.8.15-SNAPSHOT
This commit is contained in:
1 parent
a5e51a3f90
commit
0ec0ed96ee
10 files changed
+277
-67
No files matched your search
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
|
||||
group = "net.sergeych"
|
||||
version = "0.8.14-SNAPSHOT"
|
||||
version = "0.8.15-SNAPSHOT"
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
/**
|
||||
* Collection is an iterator with `size`]
|
||||
* Collection is an iterator with `size`
|
||||
*/
|
||||
val ObjCollection = ObjClass("Collection", ObjIterable).apply {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -119,12 +119,6 @@ val ObjIterable by lazy {
|
||||
ObjList(result)
|
||||
}
|
||||
|
||||
// addFn("drop" ) {
|
||||
// var n = requireOnlyArg<ObjInt>().value.toInt()
|
||||
// if( n < 0 ) raiseIllegalArgument("drop($n): should be positive")
|
||||
// val it = callMethod<>()
|
||||
// }
|
||||
|
||||
addFn("isEmpty") {
|
||||
ObjBool(
|
||||
thisObj.invokeInstanceMethod(this, "iterator")
|
||||
@@ -132,5 +126,21 @@ val ObjIterable by lazy {
|
||||
.not()
|
||||
)
|
||||
}
|
||||
|
||||
addFn("sortedWith") {
|
||||
val list = thisObj.callMethod<ObjList>(this, "toList")
|
||||
val comparator = requireOnlyArg<Statement>()
|
||||
list.quicksort { a, b ->
|
||||
comparator.call(this, a, b).toInt()
|
||||
}
|
||||
list
|
||||
}
|
||||
|
||||
addFn("reversed") {
|
||||
val list = thisObj.callMethod<ObjList>(this, "toList")
|
||||
list.list.reverse()
|
||||
list
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
import net.sergeych.lyng.Statement
|
||||
import net.sergeych.lyng.statement
|
||||
import net.sergeych.lynon.LynonDecoder
|
||||
import net.sergeych.lynon.LynonEncoder
|
||||
@@ -127,6 +128,33 @@ class ObjList(val list: MutableList<Obj> = mutableListOf()) : Obj() {
|
||||
return list.map { it.toKotlin(scope) }
|
||||
}
|
||||
|
||||
suspend fun quicksort(compare: suspend (Obj, Obj) -> Int) = quicksort(compare, 0, list.size - 1)
|
||||
|
||||
suspend fun quicksort(compare: suspend (Obj, Obj) -> Int, left: Int, right: Int) {
|
||||
if (left >= right) return
|
||||
var i = left
|
||||
var j = right
|
||||
val pivot = list[left]
|
||||
while (i < j) {
|
||||
// Сдвигаем j влево, пока элемент меньше pivot
|
||||
while (i < j && compare(list[j], pivot) >= 0) {
|
||||
j--
|
||||
}
|
||||
// Сдвигаем i вправо, пока элемент больше pivot
|
||||
while (i < j && compare(list[i], pivot) <= 0) {
|
||||
i++
|
||||
}
|
||||
if (i < j) {
|
||||
list.swap(i, j)
|
||||
}
|
||||
}
|
||||
// После завершения i == j, ставим pivot на своё место
|
||||
list.swap(left, i)
|
||||
// Рекурсивно сортируем левую и правую части
|
||||
quicksort(compare, left, i - 1)
|
||||
quicksort(compare, i + 1, right)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
// check?
|
||||
return list.hashCode()
|
||||
@@ -235,8 +263,23 @@ class ObjList(val list: MutableList<Obj> = mutableListOf()) : Obj() {
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
addFn("sortWith") {
|
||||
val comparator = requireOnlyArg<Statement>()
|
||||
thisAs<ObjList>().quicksort { a, b -> comparator.call(this, a, b).toInt() }
|
||||
ObjVoid
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Расширение MutableList для удобного обмена элементами
|
||||
fun <T>MutableList<T>.swap(i: Int, j: Int) {
|
||||
if (i in indices && j in indices) {
|
||||
val temp = this[i]
|
||||
this[i] = this[j]
|
||||
this[j] = temp
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,10 +103,46 @@ fun Iterable.all(predicate): Bool {
|
||||
!any { !predicate(it) }
|
||||
}
|
||||
|
||||
fun Iterable.sum() {
|
||||
val i = iterator()
|
||||
if( i.hasNext() ) {
|
||||
var result = i.next()
|
||||
while( i.hasNext() ) result += i.next()
|
||||
result
|
||||
}
|
||||
else null
|
||||
}
|
||||
|
||||
fun Iterable.sumOf(f) {
|
||||
val i = iterator()
|
||||
if( i.hasNext() ) {
|
||||
var result = f(i.next())
|
||||
while( i.hasNext() ) result += f(i.next())
|
||||
result
|
||||
}
|
||||
else null
|
||||
}
|
||||
|
||||
fun Iterable.sorted() {
|
||||
sortedWith { a, b -> a <=> b }
|
||||
}
|
||||
|
||||
fun Iterable.sortedBy(predicate) {
|
||||
sortedWith { a, b -> predicate(a) <=> predicate(b) }
|
||||
}
|
||||
|
||||
fun List.toString() {
|
||||
"[" + joinToString(",") + "]"
|
||||
}
|
||||
|
||||
fun List.sortBy(predicate) {
|
||||
sortWith { a, b -> predicate(a) <=> predicate(b) }
|
||||
}
|
||||
|
||||
fun List.sort() {
|
||||
sortWith { a, b -> a <=> b }
|
||||
}
|
||||
|
||||
class StackTraceEntry(
|
||||
val sourceName: String,
|
||||
val line: Int,
|
||||
@@ -124,6 +160,7 @@ fun Exception.printStackTrace() {
|
||||
println("\tat "+entry)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
""".trimIndent()
|
||||
|
||||
@@ -3095,10 +3095,12 @@ class ScriptTest {
|
||||
|
||||
@Test
|
||||
fun testOverridenListToString() = runTest {
|
||||
eval("""
|
||||
eval(
|
||||
"""
|
||||
val x = [1,2,3]
|
||||
assertEquals( "[1,2,3]", x.toString() )
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -3131,7 +3133,8 @@ class ScriptTest {
|
||||
|
||||
@Test
|
||||
fun testThisInClosure() = runTest {
|
||||
eval("""
|
||||
eval(
|
||||
"""
|
||||
fun Iterable.sum2by(f) {
|
||||
var acc = null
|
||||
for( x in this ) {
|
||||
@@ -3147,12 +3150,14 @@ class ScriptTest {
|
||||
}
|
||||
}
|
||||
assertEquals(60, T([1,2,3], 10).sum())
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testThisInFlowClosure() = runTest {
|
||||
eval("""
|
||||
eval(
|
||||
"""
|
||||
class T(val coll, val factor) {
|
||||
fun seq() {
|
||||
flow {
|
||||
@@ -3163,7 +3168,50 @@ class ScriptTest {
|
||||
}
|
||||
}
|
||||
assertEquals([10,20,30], T([1,2,3], 10).seq().toList())
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSum() = runTest {
|
||||
eval(
|
||||
"""
|
||||
assertEquals(1, [1].sum())
|
||||
assertEquals(null, [].sum())
|
||||
assertEquals(6, [1,2,3].sum())
|
||||
assertEquals(30, [3].sumOf { it * 10 })
|
||||
assertEquals(null, [].sumOf { it * 10 })
|
||||
assertEquals(60, [1,2,3].sumOf { it * 10 })
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSort() = runTest {
|
||||
eval("""
|
||||
val coll = [5,4,1,7]
|
||||
assertEquals( [1,4,5,7], coll.sortedWith { a,b -> a <=> b })
|
||||
assertEquals( [1,4,5,7], coll.sorted())
|
||||
assertEquals( [7,5,4,1], coll.sortedBy { -it })
|
||||
assertEquals( [1,4,5,7], coll.sortedBy { -it }.reversed())
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testListSortInPlace() = runTest {
|
||||
eval("""
|
||||
val l1 = [6,3,1,9]
|
||||
l1.sort()
|
||||
assertEquals( [1,3,6,9], l1)
|
||||
l1.sortBy { -it }
|
||||
assertEquals( [1,3,6,9].reversed(), l1)
|
||||
l1.sort()
|
||||
l1.sortBy { it % 4 }
|
||||
// 1,3,6,9
|
||||
// 1 3 2 1
|
||||
// we hope we got it also stable:
|
||||
assertEquals( [1,9,6,3], l1)
|
||||
""")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user