URL: https://leetcode.com/problems/closest-prime-numbers-in-range/ Signed-off-by: Matej Focko <me@mfocko.xyz>
44 lines
1.3 KiB
Kotlin
44 lines
1.3 KiB
Kotlin
class Solution {
|
|
private fun isPrime(n: Int): Boolean =
|
|
when {
|
|
n < 2 -> false
|
|
n % 2 == 0 -> n == 2
|
|
else ->
|
|
(3..n).step(2)
|
|
.asSequence()
|
|
.takeWhile { it * it <= n }
|
|
.all { div -> n % div != 0 }
|
|
}
|
|
|
|
private data class Acc(val lastPrime: Int, val p: Int, val q: Int, val diff: Int) {
|
|
constructor() : this(-1, -1, -1, 1_000_000) {}
|
|
|
|
val result: IntArray =
|
|
when {
|
|
p == -1 -> intArrayOf(-1, -1)
|
|
else -> intArrayOf(p, q)
|
|
}
|
|
|
|
private fun check(r: Int): Triple<Int, Int, Int>? =
|
|
when {
|
|
lastPrime == -1 -> null
|
|
r - lastPrime >= diff -> null
|
|
else -> Triple(lastPrime, r, r - lastPrime)
|
|
}
|
|
|
|
fun update(r: Int): Acc =
|
|
(check(r) ?: Triple(p, q, diff)).let { (p, q, diff) ->
|
|
copy(lastPrime = r, p = p, q = q, diff = diff)
|
|
}
|
|
}
|
|
|
|
fun closestPrimes(
|
|
left: Int,
|
|
right: Int,
|
|
): IntArray =
|
|
(left..right)
|
|
.asSequence()
|
|
.filter { p -> isPrime(p) }
|
|
.fold(Acc()) { acc, p -> acc.update(p) }
|
|
.result
|
|
}
|