Skip to content
Permalink
Browse files

Reworked to improve map efficiency

  • Loading branch information
jrtapsell committed Mar 1, 2018
1 parent 8e5eb68 commit 4193215742726222d5cc67a1df4b278c14ef7e6f
@@ -1,3 +1,4 @@
local
*.iml

# Created by https://www.gitignore.io/api/gradle,kotlin,intellij+all
@@ -23,6 +23,9 @@ To run code in a file called `test.jt`:
cat test.jt | docker run --rm -i jrtapsell/jotlin


## Documentation

A list of builtins is available [here](https://docs.google.com/spreadsheets/d/1QeGMf1UGDnVn-SpvPvOHDOxRXj-RipUKSovctsaU-CM/edit?usp=sharing).
## Raw data

Based on data dumps the following are the most used methods
@@ -0,0 +1,11 @@
package jotlin.lang

fun main(args: Array<String>) {
var x:(Int)->Char =
{v->'F'-l(13,170,180,294,300).f{i->i<v}.l()}

println(x(12))
println(x(15))
println(x(301))
println(x(181))
}
@@ -1,4 +1,8 @@
package jotlin.lang

import jotlin.lang.utils.ScopedMonoBlock
import jotlin.lang.utils.consume

/**
* Converts to an Integer.
*
@@ -25,6 +29,7 @@ fun Any?.s() = toString()
* < 2
*/
fun Int.s(radix: Int=10) = toString(radix)

/**
* Allows for the radix of s() to be set.
*
@@ -33,4 +38,6 @@ fun Int.s(radix: Int=10) = toString(radix)
* > 10L.s(2)
* < 2
*/
fun Long.s(radix: Int=10) = toString(radix)
fun Long.s(radix: Int=10) = toString(radix)

fun <T,U> T.l(block:ScopedMonoBlock<T, U>) = let(consume(block))
@@ -1,46 +1,51 @@
package jotlin.lang

import jotlin.lang.utils.ScopedDualBlock
import jotlin.lang.utils.ScopedMonoBlock
import jotlin.lang.utils.ScopedTripleBlock
import jotlin.lang.utils.consume

/** Acts as a shortened map. */
infix fun <T,R> Iterable<T>.m(transform: (T)->R) = map(transform)
infix fun <T,R> Iterable<T>.m(transform: ScopedMonoBlock<T, R>) = map(consume(transform))
/** Acts as a shortened map. */
infix fun <T,R> Sequence<T>.m(transform: (T)->R) = map(transform)
infix fun <T,R> Sequence<T>.m(transform: ScopedMonoBlock<T, R>) = map(consume(transform))
/** Acts as a shortened map. */
infix fun <T,R> Array<T>.m(transform: (T)->R) = map(transform)
infix fun <T,R> Array<T>.m(transform: ScopedMonoBlock<T, R>) = map(consume(transform))

/** Acts as a shortened indexed map. */
infix fun <T,R> Iterable<T>.m(transform: (Int, T)->R) = mapIndexed(transform)
infix fun <T,R> Iterable<T>.n(transform: ScopedDualBlock<Int, T, R>) = mapIndexed(consume(transform))
/** Acts as a shortened indexed map. */
infix fun <T,R> Sequence<T>.m(transform: (Int, T)->R) = mapIndexed(transform)
infix fun <T,R> Sequence<T>.n(transform: ScopedDualBlock<Int, T, R>) = mapIndexed(consume(transform))
/** Acts as a shortened indexed map. */
infix fun <T,R> Array<T>.m(transform: (Int, T)->R) = mapIndexed(transform)
infix fun <T,R> Array<T>.n(transform: ScopedDualBlock<Int, T, R>) = mapIndexed(consume(transform))

/** Acts as a shortened filter. */
infix fun <T> Iterable<T>.f(transform: (T)->Boolean) = filter(transform)
infix fun <T> Iterable<T>.f(transform: ScopedMonoBlock<T, Boolean>) = filter(consume(transform))
/** Acts as a shortened filter. */
infix fun <T> Sequence<T>.f(transform: (T)->Boolean) = filter(transform)
infix fun <T> Sequence<T>.f(transform: ScopedMonoBlock<T, Boolean>) = filter(consume(transform))
/** Acts as a shortened filter. */
infix fun <T> Array<T>.f(transform: (T)->Boolean) = filter(transform)
infix fun <T> Array<T>.f(transform: ScopedMonoBlock<T, Boolean>) = filter(consume(transform))

/** Acts as a shortened indexed filter. */
infix fun <T> Iterable<T>.f(transform: (Int, T)->Boolean) = filterIndexed(transform)
infix fun <T> Iterable<T>.g(transform: ScopedDualBlock<Int, T, Boolean>) = filterIndexed(consume(transform))
/** Acts as a shortened indexed filter. */
infix fun <T> Sequence<T>.f(transform: (Int, T)->Boolean) = filterIndexed(transform)
infix fun <T> Sequence<T>.g(transform: ScopedDualBlock<Int, T, Boolean>) = filterIndexed(consume(transform))
/** Acts as a shortened indexed filter. */
infix fun <T> Array<T>.f(transform: (Int, T)->Boolean) = filterIndexed(transform)
infix fun <T> Array<T>.g(transform: ScopedDualBlock<Int, T, Boolean>) = filterIndexed(consume(transform))

/** Acts as a shortened fold. */
fun <T,U> Iterable<T>.F(seed: U, transform: (U, T)->U) = fold(seed, transform)
fun <T,U> Iterable<T>.F(seed: U, transform: ScopedDualBlock<U, T, U>) = fold(seed, consume(transform))
/** Acts as a shortened fold. */
fun <T,U> Sequence<T>.F(seed: U, transform: (U, T)->U) = fold(seed, transform)
fun <T,U> Sequence<T>.F(seed: U, transform: ScopedDualBlock<U, T, U>) = fold(seed, consume(transform))
/** Acts as a shortened fold. */
fun <T,U> Array<T>.F(seed: U, transform: (U, T)->U) = fold(seed, transform)
fun <T,U> Array<T>.F(seed: U, transform: ScopedDualBlock<U, T, U>) = fold(seed, consume(transform))

/** Acts as a shortened indexed fold. */
fun <T,U> Iterable<T>.F(seed: U, transform: (Int, U, T)->U) = foldIndexed(seed, transform)
fun <T,U> Iterable<T>.G(seed: U, transform: ScopedTripleBlock<Int, U, T, U>) = foldIndexed(seed, consume(transform))
/** Acts as a shortened indexed fold. */
fun <T,U> Sequence<T>.F(seed: U, transform: (Int, U, T)->U) = foldIndexed(seed, transform)
fun <T,U> Sequence<T>.G(seed: U, transform: ScopedTripleBlock<Int, U, T, U>) = foldIndexed(seed, consume(transform))
/** Acts as a shortened indexed fold. */
fun <T,U> Array<T>.F(seed: U, transform: (Int, U, T)->U) = foldIndexed(seed, transform)
fun <T,U> Array<T>.G(seed: U, transform: ScopedTripleBlock<Int, U, T, U>) = foldIndexed(seed, consume(transform))

/** Counts each of the distinct items. */
fun <T> Iterable<T>.c() = groupingBy { it }.eachCount()
@@ -50,11 +55,11 @@ fun <T> Sequence<T>.c() = groupingBy { it }.eachCount()
fun <T> Array<T>.c() = groupingBy { it }.eachCount()

/** Joins to a string.*/
fun <T> Iterable<T>.j(sep:String=",", block:T.()->Any?={this}) = joinToString(sep) { it.block().toString() }
fun <T> Iterable<T>.j(sep:String=",", block:ScopedMonoBlock<T, Any?> ={this}) = joinToString(sep) { consume(block)(it).toString() }
/** Joins to a string. */
fun <T> Sequence<T>.j(sep:String=",", block:T.()->Any?={this}) = joinToString(sep) { it.block().toString() }
fun <T> Sequence<T>.j(sep:String=",", block:ScopedMonoBlock<T, Any?> ={this}) = joinToString(sep) { consume(block)(it).toString() }
/** Joins to a string. */
fun <T> Array<T>.j(sep:String=",", block:T.()->Any?={this}) = joinToString(sep) { it.block().toString() }
fun <T> Array<T>.j(sep:String=",", block:ScopedMonoBlock<T, Any?> ={this}) = joinToString(sep) { consume(block)(it).toString() }

/** Converts to a sequence. */
fun <T> Iterable<T>._s() = asSequence()
@@ -81,4 +86,35 @@ inline fun <reified T> Array<T>._l() = toMutableList()
/** Generates a sequence. */
fun <T: Any> g(nextFun: () -> T) = generateSequence(nextFun)
/** Generates a sequence. */
fun <T: Any> g(seed: T, nextFun: (T) -> T) = generateSequence(seed, nextFun)
fun <T: Any> g(seed: T, nextFun: ScopedMonoBlock<T, T>) = generateSequence(seed, consume(nextFun))

operator fun <T> List<T>.invoke(l: Int=0, r:Int=-1, s: Int=1): List<T> {
fun fix(index: Int): Int {
if (index < 0) {
return count() + index
}
return index
}

val start = fix(l)
val end = fix(r)
val range = when {
s <= -1 -> end downTo start step -s
s >= 1 -> start..end step s
else -> throw AssertionError("Bad range ($s)")
}
return range.map { get(it) }
}

operator fun <T> Iterable<T>.invoke(l: Int=0, r:Int=-1, s: Int=1) = toList()(l,r,s).asIterable()
operator fun <T> Sequence<T>.invoke(l: Int=0, r:Int=-1, s: Int=1) = toList()(l,r,s).asSequence()
inline operator fun <reified T> Array<T>.invoke(l: Int=0, r:Int=-1, s: Int=1) = toList()(l,r,s).toTypedArray()

fun <T> Iterable<T>.l() = count()
fun <T> Sequence<T>.l() = count()
fun <T> Array<T>.l() = count()


fun CharRange.s(size:Int) = step(size)
fun IntRange.s(size:Int) = step(size)
fun LongRange.s(size:Long) = step(size)
@@ -0,0 +1,32 @@
package jotlin.lang.utils

/**
* @author James Tapsell
*/

typealias ScopedMonoBlock<T, Z> =ScopedMonoContext<T>.(T)->Z
class ScopedMonoContext<T>(val a: T)
fun <T,U> consume(block: ScopedMonoBlock<T,U>): (T)->U {
return {input ->
val context = ScopedMonoContext(input)
context.block(input)
}
}

typealias ScopedDualBlock<T, U, Z> =ScopedDualContext<T, U>.()->Z
class ScopedDualContext<T,U>(val a: T, val b: U)
fun <T,U,Z> consume(block: ScopedDualBlock<T,U, Z>): (T, U)->Z {
return {a,b ->
val context = ScopedDualContext(a,b)
context.block()
}
}

typealias ScopedTripleBlock<T, U, V, Z> =ScopedTripleContext<T, U, V>.()->Z
class ScopedTripleContext<T,U, V>(val a: T, val b: U, val c: V)
fun <T,U, V,Z> consume(block: ScopedTripleBlock<T,U, V, Z>): (T, U, V)->Z {
return {a,b,c ->
val context = ScopedTripleContext(a,b,c)
context.block()
}
}
@@ -0,0 +1,38 @@
package jotlin.lang

data class Test(val r: Int, val g: Int, val b: Int, val out: Int)

val test = listOf(
Test(0, 0, 0, 16),
Test(95, 135, 0, 64),
Test(255, 255, 255, 231),
Test(238, 238, 238, 255),

Test(90, 133, 140, 66),
Test(218, 215, 216, 188),
Test(175, 177, 178, 249),

Test(175, 0, 155, 127),
Test(75, 75, 75, 239),
Test(23, 23, 23, 234),
Test(115, 155, 235, 111)
)

fun z(it: List<Int>): Int =
(16..255).associate{it to if (it<232)(it-16).let { i ->
l(0, 95, 135, 175, 215, 255).let { l ->
l(l[i / 36], l[(i / 6) % 6],
l[i % 6])
}
} else (8..238 step 10)._l()[it - 232].let { l(it, it, it) }
}.minBy { (k, v) ->
(it.zip(v).m { (a, b) -> kotlin.math.abs(a - b) }.sum() * 256) + (256 - k)
}!!.key

fun main(args: Array<String>) {

for (i in test) {
val r = z(listOf(i.r, i.g, i.b))
println("$i ${i.out} ==> $r")
}
}
@@ -0,0 +1,25 @@
package jotlin.lang

import org.testng.annotations.Test
import utils.assert

/**
* @author James Tapsell
*/
class IterUtilsTest {
@Test
fun testSlices() {
val original = listOf("a", "b", "c", "d")
assert(original(s=-1))
.equalsValue(listOf("d", "c", "b", "a"))
.assert("Trying backwards")

assert(original(l=1))
.equalsValue(listOf("b", "c", "d"))
.assert("Skipping the first")

assert(original(r=-2))
.equalsValue(listOf("a", "b", "c"))
.assert("Skipping the last")
}
}

This file was deleted.

0 comments on commit 4193215

Please sign in to comment.
You can’t perform that action at this time.