Skip to content

Instantly share code, notes, and snippets.

@cherrydev
Created March 18, 2022 04:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cherrydev/cff792b6208424189ed4be0c21f2ab7b to your computer and use it in GitHub Desktop.
Save cherrydev/cff792b6208424189ed4be0c21f2ab7b to your computer and use it in GitHub Desktop.
Fast functions for intersecting sorted lists in Kotlin, returning Lists or Sequences
import kotlin.math.*
object ListIntersection {
fun <T : Comparable<T>> safeIntersection(l1: List<T>, l2: List<T>) : List<T> {
return l1.intersect(l2).sorted()
}
// https://stackoverflow.com/a/33963306/480176
fun <T : Comparable<T>> fastIntersection(a1: List<T>, a2: List<T>) : List<T> {
return fastIntersectionSequence(a1, a2).toList()
}
fun <T : Comparable<T>> fastIntersectionSequence(a1: List<T>, a2: List<T>) : Sequence<T> {
val s1 = a1.size
val s2 = a2.size
return if (s1 > 0 && s1 + s2 > min(s1, s2) * ln(max(s1, s2).toDouble()) * 1.4426950408889634)
bSearchIntersectionSequence(a1, a2)
else
linearIntersectionSequence(a1, a2)
}
fun <T : Comparable<T>> linearIntersectionSequence(a1: List<T>, a2: List<T>) : Sequence<T> {
return sequence {
val s1 = a1.size
val s2 = a2.size
var i1 = 0
var i2 = 0
while (i1 < s1 && i2 < s2) {
val v1 = a1[i1]
val v2 = a2[i2]
if (v1 == v2) {
yield(v1)
i1 += 1
i2 += 1
}
else if (v1 < v2) i1 += 1
else i2 += 1
}
}
}
fun <T : Comparable<T>> bSearchIntersectionSequence(a1: List<T>, a2: List<T>) : Sequence<T> {
return sequence {
val s1 = a1.size
val s2 = a2.size
var i1 = 0
var i2 = 0
var temp : Int
while (i1 < s1 && i2 < s2) {
val v1 = a1[i1]
val v2 = a2[i2]
if (v1 == v2) {
yield(v1)
i1 += 1
i2 += 1
}
else if (v1 < v2) {
temp = a1.binarySearch(v2, i1)
i1 = if (temp < 0) -(temp + 1) else temp
}
else {
temp = a2.binarySearch(v1, i2)
i2 = if (temp < 0) -(temp + 1) else temp
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment