Skip to content

Instantly share code, notes, and snippets.

View elizarov's full-sized avatar

Roman Elizarov elizarov

View GitHub Profile
@elizarov
elizarov / dump-cycles.patch
Created November 18, 2020 13:21
Dump cycles for kotinx-coroutines 1.4.1 running on Kotlin 1.4.20
Index: kotlinx-coroutines-core/concurrent/src/internal/LockFreeLinkedList.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- kotlinx-coroutines-core/concurrent/src/internal/LockFreeLinkedList.kt (revision 4dd4e59f6676a45499cd193aa8fd9521013f8a3f)
+++ kotlinx-coroutines-core/concurrent/src/internal/LockFreeLinkedList.kt (date 1605704376180)
@@ -62,12 +62,19 @@
*/
@Suppress("LeakingThis")
@elizarov
elizarov / bisect_leaks.sh
Created November 18, 2020 09:59
Bisect leaks in K/N code
#!/bin/bash
kexe="$1"
if [ "$1" == "" ]; then
echo "Usage bisect_leaks.sh <path-to-test.kexe>"
exit
fi
echo "Bisecting leaks for $kexe"
log="$kexe.log"
@elizarov
elizarov / Main.kt
Created July 3, 2020 09:00
Flow.asPublisher stress-test with concurrent request/onNext
import kotlin.coroutines.*
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.reactive.*
import org.reactivestreams.*
import java.util.concurrent.*
import java.util.concurrent.atomic.*
import kotlin.random.*
@elizarov
elizarov / BlockingInputFlow.kt
Created May 17, 2020 09:02
Blocking input flow
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking<Unit> {
// working in the main thread
val stdinFlow = System.`in`.bufferedReader().lineSequence().asFlow()
// lets launch a coroutine that collects this flow and prints lines:
stdinFlow.onEach { println(it) }.launchIn(this)
// is the main thread active or blocked?
println("I'm not blocked yet")
@elizarov
elizarov / BlindfoldedBullseye.kt
Last active April 20, 2020 07:34
GCJ 2020: Blindfolded Bullseye
fun main() {
val t = readLine()!!.split(" ")[0].toInt()
val s = 1_000_000_000
val n = 9
val d = (2 * s) / (n + 1)
fun hit(i: Int): Int = -s + i * d
fun ask(x: Int, y: Int, swap: Boolean = false): Boolean? {
println(if (swap) "$y $x" else "$x $y")
return when (readLine()!!) {
"CENTER" -> null
@elizarov
elizarov / TimedBuffer.kt
Last active June 22, 2021 19:53
timedBuffer
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
private class Buffer<T> {
private val list = arrayListOf<T>()
@Synchronized
fun add(value: T) { list.add(value) }
@Synchronized
@elizarov
elizarov / KH3I.kt
Created February 28, 2020 07:11
Kotlin Heroes: Episode 3 - Solution for Problem I. Falling Blocks
// https://codeforces.com/contest/1297/problem/I
import java.util.*
private class Block(val l: Int, val r: Int) : Comparable<Block> {
fun cover(c: Block) = l <= c.l && r >= c.r
override fun compareTo(other: Block): Int = l.compareTo(other.l)
}
fun main() {
val (n, d) = readLine()!!.split(" ").map { it.toInt() }
@elizarov
elizarov / StrategyFinder.kt
Last active January 30, 2020 09:45
Math puzzle strategy finder
import kotlin.math.*
/*
Player A gets N random coin flips.
Player B gets M random coin flips.
They don't see each other coins, but has agreed on strategy in advance:
- A names the # of B's coin
- B names the # of A's coin
If both their named rolls agree they win, otherwise they loose.
Question: What is their best strategy and chances for winning?
@elizarov
elizarov / BufferStrategy.md
Created January 24, 2020 09:45
RFC: Flow: Optional backpressure-handling strategy in buffer operator

Flow has buffer(capacity: Int) operator to adapt fast consumers to slow producers. It does offer some flexibility and supports buffer(Channel.CONFLATED), but it does not cover one important use-case that happens in practice. Consider a flow of UI events (like keyboard/mouse clicks). If they go too fast and the application is not keeping up with their processing it would be better to skip the events altogether at some point than to buffer them indefinitely and process later. When to drop/skip? There might be multiple strategies based on time-limit or buffer-size. It seems pretty natural to support at least some of those strategies directly in buffer operator.

sealed class Expression<A> {
abstract val value: A
}
data class Num(override val value: Int) : Expression<Int>()
data class Bool(override val value: Boolean) : Expression<Boolean>()
data class Add(val a: Expression<Int>, val b: Expression<Int>) : Expression<Int>() {
override val value: Int get() = a.value + b.value
}
data class Equals<A>(val first: Expression<A>, val second: Expression<A>) : Expression<Boolean>() {
override val value: Boolean get() = first.value == second.value