Last active
July 17, 2024 17:58
-
-
Save ElianFabian/466994e9f76e93b783f33493ac8133f5 to your computer and use it in GitHub Desktop.
Math utils
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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