Skip to content

Instantly share code, notes, and snippets.

@ElianFabian
Last active July 17, 2024 17:58
Show Gist options
  • Save ElianFabian/466994e9f76e93b783f33493ac8133f5 to your computer and use it in GitHub Desktop.
Save ElianFabian/466994e9f76e93b783f33493ac8133f5 to your computer and use it in GitHub Desktop.
Math utils
fun getAllDivisiblePairsInRangeCount(
start: Int,
end: Int,
ignoreSelfDivision: Boolean = false,
): Int {
require(start != 0) {
"start parameter can't be $start"
}
require(start <= end) {
"start '$start' must be less or equal to end '$end'"
}
var ratio = end / start
var denominator = start
var count = 0
while (ratio >= 1) {
for (multiple in 1..ratio) {
val numerator = denominator * multiple
if (ignoreSelfDivision && denominator == numerator) {
continue
}
count++
}
ratio = end / ++denominator
}
return count
}
// https://stackoverflow.com/questions/75062834/how-to-get-all-the-divisible-pairs-in-a-range-faster/
fun getAllDivisiblePairsInRangeAsIntPairArray(
start: Int,
end: Int,
ignoreSelfDivision: Boolean = false,
): IntPairArray {
val divisiblePairsCount = getAllDivisiblePairsInRangeCount(start, end, ignoreSelfDivision)
val divisiblePairs = IntPairArray(divisiblePairsCount)
var ratio = end / start
var denominator = start
var pairIndex = 0
while (ratio >= 1) {
for (multiple in 1..ratio) {
val numerator = denominator * multiple
if (ignoreSelfDivision && denominator == numerator) {
continue
}
divisiblePairs[pairIndex] = IntPair(numerator, denominator)
pairIndex++
}
ratio = end / ++denominator
}
return divisiblePairs
}
@JvmInline
value class IntPair private constructor(
val packedValue: Long,
) {
constructor(first: Int, second: Int) : this(
(first.toLong() shl 32) or (second.toLong() and 0xFFFFFFFF)
)
val first get() = (packedValue shr 32).toInt()
val second get() = (packedValue and 0xFFFFFFFF).toInt()
override fun toString(): String {
return "IntPair(first=$first, second=$second)"
}
companion object {
fun getRawValueFrom(pair: IntPair): Long = pair.packedValue
fun fromRawValue(rawValue: Long): IntPair = IntPair(rawValue)
}
}
@JvmInline
value class IntPairArray constructor(
private val array: LongArray,
) {
operator fun get(index: Int) = IntPair.fromRawValue(array[index])
operator fun set(index: Int, value: IntPair) {
array[index] = IntPair.getRawValueFrom(value)
}
val size: Int get() = array.size
operator fun iterator() = array.iterator()
override fun toString(): String {
return buildString {
var separator = ""
append('[')
for (index in array.indices) {
append(separator)
val long = array[index]
val intPair = IntPair.fromRawValue(long)
append("[${intPair.first}, ${intPair.second}]")
separator = ", "
}
append(']')
}
}
}
inline fun IntPairArray(size: Int, init: (Int) -> IntPair): IntPairArray {
return IntPairArray(LongArray(size) { index ->
IntPair.getRawValueFrom(init(index))
})
}
inline fun IntPairArray(size: Int): IntPairArray {
return IntPairArray(LongArray(size))
}
fun Byte.digitCount(): Int {
var x = this
if (x >= 0) {
x = (-x).toByte()
}
var powerOfTen = -10
for (digitCount in 1..2) {
if (x > powerOfTen) {
return digitCount
}
powerOfTen *= 10
}
return 3
}
fun Short.digitCount(): Int {
var x = this
if (x >= 0) {
x = (-x).toShort()
}
var powerOfTen = -10
for (digitCount in 1..4) {
if (x > powerOfTen) {
return digitCount
}
powerOfTen *= 10
}
return 5
}
fun Int.digitCount(): Int {
var x = this
if (x >= 0) {
x = -x
}
var powerOfTen = -10
for (digitCount in 1..9) {
if (x > powerOfTen) {
return digitCount
}
powerOfTen *= 10
}
return 10
}
fun Long.digitCount(): Int {
var x = this
if (x >= 0) {
x = -x
}
var powerOfTen = -10L
for (digitCount in 1..18) {
if (x > powerOfTen) {
return digitCount
}
powerOfTen *= 10
}
return 19
}
fun UByte.digitCount(): Int {
val x = this
var powerOfTen = 10u
for (digitCount in 1..3) {
if (x < powerOfTen) {
return digitCount
}
powerOfTen *= 10u
}
return 3
}
fun UShort.digitCount(): Int {
val x = this.toUInt()
var powerOfTen = 10u
for (digitCount in 1..5) {
if (x < powerOfTen) {
return digitCount
}
powerOfTen *= 10u
}
return 5
}
fun UInt.digitCount(): Int {
val x = this
var powerOfTen = 10u
for (digitCount in 1..10) {
if (x < powerOfTen) {
return digitCount
}
powerOfTen *= 10u
}
return 10
}
fun ULong.digitCount(): Int {
val x = this
var powerOfTen = 10uL
for (digitCount in 1..20) {
if (x < powerOfTen) {
return digitCount
}
powerOfTen *= 10uL
}
return 20
}
fun lerp(start: Float, stop: Float, t: Float): Float {
require(t in 0.0F..1.0F) {
"t ($t) must be between 0.0 and 1.0"
}
require(start < stop) {
"start ($start) must be less than stop ($stop)"
}
return start + (stop - start) * t
}
fun lerp(start: Double, stop: Double, t: Double): Double {
require(t in 0.0..1.0) {
"t ($t) must be between 0.0 and 1.0"
}
require(start < stop) {
"start ($start) must be less than stop ($stop)"
}
return start + (stop - start) * t
}
fun inverseLerp(start: Float, stop: Float, value: Float): Float {
require(start < stop) {
"start ($start) must be less than stop ($stop)"
}
return (value - start) / (stop - start)
}
fun inverseLerp(start: Double, stop: Double, value: Double): Double {
require(start < stop) {
"start ($start) must be less than stop ($stop)"
}
return value / (stop - start)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment