matrix stuff

This commit is contained in:
alex-s168
2024-04-02 20:25:45 +02:00
parent 54dde5f1f7
commit 9a571a072d
4 changed files with 114 additions and 7 deletions

View File

@@ -48,4 +48,16 @@ val <T> Sequence<T>.contents get() =
Contents(this.asIterable())
val <T> Array<T>.contents get() =
Contents(this.asIterable())
val IntArray.contents get() =
Contents(this.asIterable())
val ByteArray.contents get() =
Contents(this.asIterable())
val DoubleArray.contents get() =
Contents(this.asIterable())
val FloatArray.contents get() =
Contents(this.asIterable())

View File

@@ -20,6 +20,21 @@ class Matrix<T>(
rows[y][x] = value
}
fun column(col: Int): IndexableSequence<T> =
generateSequenceWithIndex(height) { row -> this[col, row] }
fun fill(fn: (x: Int, y: Int) -> T) {
repeat(height) { row ->
repeat(width) { col ->
this[col, row] = fn(col, row)
}
}
}
fun transpose(dest: Matrix<T>) {
dest.fill { x, y -> this[y, x] }
}
fun transposeCopy(): Matrix<T> =
Matrix(width, height) { x, y -> this[y, x] }
@@ -28,6 +43,10 @@ class Matrix<T>(
Matrix(wh, wh) { x, y -> this[x, y] }
}
fun copyTo(dest: Matrix<T>) {
dest.fill { x, y -> this[x, y] }
}
fun copy(): Matrix<T> =
Matrix(width, height) { x, y -> this[x, y] }
@@ -52,10 +71,50 @@ class Matrix<T>(
return to
}
// TODO: make better
fun stringMat(): Matrix<String> =
Matrix(width, height) { x, y -> this[x, y].toString() }
fun stringMatTo(dest: Matrix<String>) {
dest.fill { x, y -> this[x, y].toString() }
}
fun window(w: Int, h: Int): Matrix<Matrix<T>> =
Matrix(width / w, height / h) { x, y ->
Matrix(w, h) { sx, sy -> this[x * w + sx, y * w + sy] }
}
fun toString(alignRight: Boolean): String {
val str = stringMat()
val widths = str.columnWidths()
val out = StringBuilder()
val padfn = if (alignRight) String::padStart else String::padEnd
str.rows.forEachIndexed { row, elems ->
if (row > 0)
out.append('\n')
elems.forEachIndexed { col, x ->
if (col > 0)
out.append(' ')
out.append(padfn(x, widths[col], ' '))
}
}
return out.toString()
}
override fun toString(): String =
"--\n" +
rows.joinToString(separator = "\n") {
it.joinToString(separator = ", ", prefix = "| ", postfix = " |")
} + "\n--"
}
toString(true)
override fun equals(other: Any?): Boolean =
rows == other
override fun hashCode(): Int =
rows.hashCode()
}
fun Matrix<String>.columnWidths(): IntArray =
IntArray(width) { col -> column(col).maxOf { it.length } }
fun Matrix<String>.lengths(): Matrix<Int> =
Matrix(width, height) { x, y -> this[x, y].length }

View File

@@ -74,4 +74,25 @@ fun <T> selfInitializingSequence(block: Provider<Sequence<T>>): Sequence<T> =
override fun iterator(): Iterator<T> =
Iter()
}
fun <T> generateSequenceWithIndex(len: Int, fn: (index: Int) -> T): IndexableSequence<T> =
object : IndexableSequence<T> {
override fun get(index: Int): T {
if (index >= len) error("Index $index out of bounds!")
return fn(index)
}
override fun iterator(): Iterator<T> =
object : Iterator<T> {
private var index = 0
override fun hasNext(): Boolean =
index < len
override fun next(): T {
if (index >= len) error("No next")
return fn(index ++)
}
}
}

View File

@@ -4,15 +4,18 @@ import blitz.parse.comb.*
object JSON {
lateinit var jsonElement: Parser<Element>
val jsonNum = parser {
it.map(NumParse.float)?.mapSecond { n ->
Number(n)
}
}
val jsonString = parser {
it.require("\"")
?.untilRequire("\"") { str -> Str(str) }
}
val jsonArray = parser {
it.require("[")
?.array(",") { elem ->
@@ -23,6 +26,10 @@ object JSON {
?.require("]")
?.mapSecond { x -> Array(x) }
}
val jsonBool = parser { it.require("true")?.to(Bool(true)) } or
parser { it.require("false")?.to(Bool(false)) }
val jsonObj = parser {
it.require("{")
?.array(",") { elem ->
@@ -40,7 +47,7 @@ object JSON {
}
init {
jsonElement = (jsonArray or jsonNum or jsonString or jsonObj).trim()
jsonElement = (jsonArray or jsonNum or jsonString or jsonObj or jsonBool).trim()
}
interface Element {
@@ -48,11 +55,13 @@ object JSON {
val num get() = (this as Number).value
val str get() = (this as Str).value
val obj get() = (this as Obj).value
val bool get() = (this as Bool).value
fun isArr() = this is Array
fun isNum() = this is Number
fun isStr() = this is Str
fun isObj() = this is Obj
fun isBool() = this is Bool
}
data class Array(val value: List<Element>): Element {
@@ -75,6 +84,12 @@ object JSON {
value.map { (k, v) -> "\"$k\": $v" }.joinToString(separator = ", ", prefix = "{", postfix = "}")
}
data class Bool(val value: Boolean): Element {
override fun toString(): String =
value.toString()
}
fun parse(string: String): Element? =
jsonElement(Parsable(string))?.second
}