Basic Matrix and Matrix Storage implementation
This commit is contained in:
+1
-1
@@ -35,7 +35,7 @@ kotlin {
|
||||
|
||||
kotlin {
|
||||
jvmToolchain {
|
||||
languageVersion = JavaLanguageVersion.of(25)
|
||||
languageVersion = JavaLanguageVersion.of(21)
|
||||
vendor = JvmVendorSpec.ADOPTIUM
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.duckdns.davygora.matrix
|
||||
|
||||
import org.duckdns.davygora.matrix.storage.MatrixStorage
|
||||
|
||||
abstract class AbstractMatrix<T>(
|
||||
override val xSize: Int,
|
||||
override val ySize: Int,
|
||||
protected val matrix: MatrixStorage<T>,
|
||||
) : Matrix<T> {
|
||||
override fun toString(): String =
|
||||
(0..<ySize)
|
||||
.map { y ->
|
||||
"[\t${(0..<xSize).joinToString("\t") { x -> this[x, y].toString() }}\t]"
|
||||
}.joinToString { "\n" }
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as AbstractMatrix<T>
|
||||
|
||||
if (xSize != other.xSize) return false
|
||||
if (ySize != other.ySize) return false
|
||||
if (matrix != other.matrix) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = xSize
|
||||
result = 31 * result + ySize
|
||||
result = 31 * result + matrix.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.duckdns.davygora.matrix
|
||||
|
||||
import org.duckdns.davygora.matrix.storage.MatrixStorage
|
||||
|
||||
abstract class AbstractMutableMatrix<T>(
|
||||
xSize: Int,
|
||||
ySize: Int,
|
||||
matrix: MatrixStorage<T>,
|
||||
) : AbstractMatrix<T>(xSize, ySize, matrix),
|
||||
MutableMatrix<T>
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.duckdns.davygora.matrix
|
||||
|
||||
interface Matrix<T> {
|
||||
val xSize: Int
|
||||
val ySize: Int
|
||||
|
||||
operator fun get(
|
||||
x: Int,
|
||||
y: Int,
|
||||
): T
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.duckdns.davygora.matrix
|
||||
|
||||
interface MutableMatrix<T> : Matrix<T> {
|
||||
operator fun set(
|
||||
x: Int,
|
||||
y: Int,
|
||||
value: T,
|
||||
)
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package org.duckdns.davygora.matrix.exception
|
||||
|
||||
class MatrixCoordinateOutOfRangeException(
|
||||
coordName: Char,
|
||||
coord: Int,
|
||||
maxCoord: Int,
|
||||
) : MatrixException("${coordName.uppercaseChar()} coordinate $coord is out of range, allowed is 0..$maxCoord")
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.duckdns.davygora.matrix.exception
|
||||
|
||||
sealed class MatrixException(
|
||||
message: String,
|
||||
cause: Throwable? = null,
|
||||
) : RuntimeException(message, cause)
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.duckdns.davygora.matrix.exception
|
||||
|
||||
class MatrixInvalidSizeException(
|
||||
coordinate: Char,
|
||||
size: Int,
|
||||
) : MatrixException("${coordinate.uppercaseChar()} size is invalid: $size (should be > 0)")
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.duckdns.davygora.matrix.exception
|
||||
|
||||
class MatrixSizeMismatchException(
|
||||
expectedSize: Int,
|
||||
actualSize: Int,
|
||||
) : MatrixException("Matrix size mismatch: expected $expectedSize, actual $actualSize")
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.duckdns.davygora.matrix.impl
|
||||
|
||||
import org.duckdns.davygora.matrix.AbstractMutableMatrix
|
||||
import org.duckdns.davygora.matrix.Matrix
|
||||
import org.duckdns.davygora.matrix.exception.MatrixCoordinateOutOfRangeException
|
||||
import org.duckdns.davygora.matrix.exception.MatrixInvalidSizeException
|
||||
import org.duckdns.davygora.matrix.exception.MatrixNotRectangularException
|
||||
import org.duckdns.davygora.matrix.exception.MatrixSizeMismatchException
|
||||
import org.duckdns.davygora.matrix.storage.MatrixStorage
|
||||
import org.duckdns.davygora.memoize.memoize
|
||||
|
||||
class ArrayMatrix<T>(
|
||||
xSize: Int,
|
||||
ySize: Int,
|
||||
matrix: MatrixStorage<T>,
|
||||
) : AbstractMutableMatrix<T>(xSize, ySize, matrix) {
|
||||
private val size = xSize * ySize
|
||||
|
||||
private val maxX = xSize - 1
|
||||
private val maxY = ySize - 1
|
||||
|
||||
init {
|
||||
if (ySize < 1) throw MatrixInvalidSizeException('y', ySize)
|
||||
if (xSize < 1) throw MatrixInvalidSizeException('x', xSize)
|
||||
if (size != matrix.size) throw MatrixSizeMismatchException(size, matrix.size)
|
||||
}
|
||||
|
||||
override operator fun get(
|
||||
x: Int,
|
||||
y: Int,
|
||||
): T = matrix[index(x, y)]
|
||||
|
||||
override operator fun set(
|
||||
x: Int,
|
||||
y: Int,
|
||||
value: T,
|
||||
) {
|
||||
matrix[index(x, y)] = value
|
||||
}
|
||||
|
||||
private val index = { x: Int, y: Int -> validateY(y) * xSize + validateX(x) }.memoize()
|
||||
|
||||
private val validateX = { x: Int -> validateCoord('x', x, maxX) }.memoize()
|
||||
private val validateY = { y: Int -> validateCoord('y', y, maxY) }.memoize()
|
||||
|
||||
private fun validateCoord(
|
||||
coordName: Char,
|
||||
coord: Int,
|
||||
maxCoord: Int,
|
||||
) = if (coord in
|
||||
0..maxCoord
|
||||
) {
|
||||
coord
|
||||
} else {
|
||||
throw MatrixCoordinateOutOfRangeException(coordName, coord, maxCoord)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.duckdns.davygora.matrix.storage
|
||||
|
||||
@JvmInline
|
||||
value class BooleanStorage(
|
||||
val data: BooleanArray,
|
||||
) : MatrixStorage<Boolean> {
|
||||
override val size get() = data.size
|
||||
|
||||
override operator fun get(index: Int) = data[index]
|
||||
|
||||
override fun set(
|
||||
index: Int,
|
||||
value: Boolean,
|
||||
) {
|
||||
data[index] = value
|
||||
}
|
||||
|
||||
override fun toString(): String = data.contentToString()
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.duckdns.davygora.matrix.storage
|
||||
|
||||
@JvmInline
|
||||
value class ByteStorage(
|
||||
val data: ByteArray,
|
||||
) : MatrixStorage<Byte> {
|
||||
override val size get() = data.size
|
||||
|
||||
override operator fun get(index: Int) = data[index]
|
||||
|
||||
override fun set(
|
||||
index: Int,
|
||||
value: Byte,
|
||||
) {
|
||||
data[index] = value
|
||||
}
|
||||
|
||||
override fun toString(): String = data.contentToString()
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.duckdns.davygora.matrix.storage
|
||||
|
||||
@JvmInline
|
||||
value class CharStorage(
|
||||
val data: CharArray,
|
||||
) : MatrixStorage<Char> {
|
||||
override val size get() = data.size
|
||||
|
||||
override operator fun get(index: Int) = data[index]
|
||||
|
||||
override fun set(
|
||||
index: Int,
|
||||
value: Char,
|
||||
) {
|
||||
data[index] = value
|
||||
}
|
||||
|
||||
override fun toString(): String = data.contentToString()
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.duckdns.davygora.matrix.storage
|
||||
|
||||
@JvmInline
|
||||
value class DoubleStorage(
|
||||
val data: DoubleArray,
|
||||
) : MatrixStorage<Double> {
|
||||
override val size get() = data.size
|
||||
|
||||
override operator fun get(index: Int) = data[index]
|
||||
|
||||
override fun set(
|
||||
index: Int,
|
||||
value: Double,
|
||||
) {
|
||||
data[index] = value
|
||||
}
|
||||
|
||||
override fun toString(): String = data.contentToString()
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.duckdns.davygora.matrix.storage
|
||||
|
||||
@JvmInline
|
||||
value class FloatStorage(
|
||||
val data: FloatArray,
|
||||
) : MatrixStorage<Float> {
|
||||
override val size get() = data.size
|
||||
|
||||
override operator fun get(index: Int) = data[index]
|
||||
|
||||
override fun set(
|
||||
index: Int,
|
||||
value: Float,
|
||||
) {
|
||||
data[index] = value
|
||||
}
|
||||
|
||||
override fun toString(): String = data.contentToString()
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.duckdns.davygora.matrix.storage
|
||||
|
||||
@JvmInline
|
||||
value class IntStorage(
|
||||
val data: IntArray,
|
||||
) : MatrixStorage<Int> {
|
||||
override val size get() = data.size
|
||||
|
||||
override operator fun get(index: Int) = data[index]
|
||||
|
||||
override fun set(
|
||||
index: Int,
|
||||
value: Int,
|
||||
) {
|
||||
data[index] = value
|
||||
}
|
||||
|
||||
override fun toString(): String = data.contentToString()
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.duckdns.davygora.matrix.storage
|
||||
|
||||
@JvmInline
|
||||
value class LongStorage(
|
||||
val data: LongArray,
|
||||
) : MatrixStorage<Long> {
|
||||
override val size get() = data.size
|
||||
|
||||
override operator fun get(index: Int) = data[index]
|
||||
|
||||
override fun set(
|
||||
index: Int,
|
||||
value: Long,
|
||||
) {
|
||||
data[index] = value
|
||||
}
|
||||
|
||||
override fun toString(): String = data.contentToString()
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.duckdns.davygora.matrix.storage
|
||||
|
||||
sealed interface MatrixStorage<T> {
|
||||
val size: Int
|
||||
|
||||
operator fun get(index: Int): T
|
||||
|
||||
operator fun set(
|
||||
index: Int,
|
||||
value: T,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.duckdns.davygora.matrix.storage
|
||||
|
||||
@JvmInline
|
||||
value class ObjectStorage<T>(
|
||||
val data: Array<T>,
|
||||
) : MatrixStorage<T> {
|
||||
override val size get() = data.size
|
||||
|
||||
override operator fun get(index: Int) = data[index]
|
||||
|
||||
override fun set(
|
||||
index: Int,
|
||||
value: T,
|
||||
) {
|
||||
data[index] = value
|
||||
}
|
||||
|
||||
override fun toString(): String = data.contentToString()
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.duckdns.davygora.matrix.storage
|
||||
|
||||
@JvmInline
|
||||
value class ShortStorage(
|
||||
val data: ShortArray,
|
||||
) : MatrixStorage<Short> {
|
||||
override val size get() = data.size
|
||||
|
||||
override operator fun get(index: Int) = data[index]
|
||||
|
||||
override fun set(
|
||||
index: Int,
|
||||
value: Short,
|
||||
) {
|
||||
data[index] = value
|
||||
}
|
||||
|
||||
override fun toString(): String = data.contentToString()
|
||||
}
|
||||
Reference in New Issue
Block a user