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()) Contents(this.asIterable())
val <T> Array<T>.contents get() = 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()) Contents(this.asIterable())

View File

@@ -20,6 +20,21 @@ class Matrix<T>(
rows[y][x] = value 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> = fun transposeCopy(): Matrix<T> =
Matrix(width, height) { x, y -> this[y, x] } Matrix(width, height) { x, y -> this[y, x] }
@@ -28,6 +43,10 @@ class Matrix<T>(
Matrix(wh, wh) { x, y -> this[x, y] } Matrix(wh, wh) { x, y -> this[x, y] }
} }
fun copyTo(dest: Matrix<T>) {
dest.fill { x, y -> this[x, y] }
}
fun copy(): Matrix<T> = fun copy(): Matrix<T> =
Matrix(width, height) { x, y -> this[x, y] } Matrix(width, height) { x, y -> this[x, y] }
@@ -52,10 +71,50 @@ class Matrix<T>(
return to 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 = override fun toString(): String =
"--\n" + toString(true)
rows.joinToString(separator = "\n") {
it.joinToString(separator = ", ", prefix = "| ", postfix = " |") override fun equals(other: Any?): Boolean =
} + "\n--" 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> = override fun iterator(): Iterator<T> =
Iter() 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 { object JSON {
lateinit var jsonElement: Parser<Element> lateinit var jsonElement: Parser<Element>
val jsonNum = parser { val jsonNum = parser {
it.map(NumParse.float)?.mapSecond { n -> it.map(NumParse.float)?.mapSecond { n ->
Number(n) Number(n)
} }
} }
val jsonString = parser { val jsonString = parser {
it.require("\"") it.require("\"")
?.untilRequire("\"") { str -> Str(str) } ?.untilRequire("\"") { str -> Str(str) }
} }
val jsonArray = parser { val jsonArray = parser {
it.require("[") it.require("[")
?.array(",") { elem -> ?.array(",") { elem ->
@@ -23,6 +26,10 @@ object JSON {
?.require("]") ?.require("]")
?.mapSecond { x -> Array(x) } ?.mapSecond { x -> Array(x) }
} }
val jsonBool = parser { it.require("true")?.to(Bool(true)) } or
parser { it.require("false")?.to(Bool(false)) }
val jsonObj = parser { val jsonObj = parser {
it.require("{") it.require("{")
?.array(",") { elem -> ?.array(",") { elem ->
@@ -40,7 +47,7 @@ object JSON {
} }
init { init {
jsonElement = (jsonArray or jsonNum or jsonString or jsonObj).trim() jsonElement = (jsonArray or jsonNum or jsonString or jsonObj or jsonBool).trim()
} }
interface Element { interface Element {
@@ -48,11 +55,13 @@ object JSON {
val num get() = (this as Number).value val num get() = (this as Number).value
val str get() = (this as Str).value val str get() = (this as Str).value
val obj get() = (this as Obj).value val obj get() = (this as Obj).value
val bool get() = (this as Bool).value
fun isArr() = this is Array fun isArr() = this is Array
fun isNum() = this is Number fun isNum() = this is Number
fun isStr() = this is Str fun isStr() = this is Str
fun isObj() = this is Obj fun isObj() = this is Obj
fun isBool() = this is Bool
} }
data class Array(val value: List<Element>): Element { data class Array(val value: List<Element>): Element {
@@ -75,6 +84,12 @@ object JSON {
value.map { (k, v) -> "\"$k\": $v" }.joinToString(separator = ", ", prefix = "{", postfix = "}") 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? = fun parse(string: String): Element? =
jsonElement(Parsable(string))?.second jsonElement(Parsable(string))?.second
} }