https://kotlinlang.org logo
#getting-started
Title
# getting-started
v

Valentin Metz

08/29/2020, 7:08 PM
I'd like to have an array of ~1000 Functions (not all are implemented yet) to choose one from at runtime and pass all input arguments (after the first, which is used to choose the function) to. How can I create the array and call from it?
m

Mark Spindler

08/29/2020, 8:17 PM
I'm also new to Kotlin, but it's making me think about possibilities. Are they `fun`s or lambda expressions (like `val`s of function types?). Does it have to be an
Array
or could it be a
MutableList
? Are you sure you want to do things this way? It sounds weird to me to have an array of 1000 functions rather than a function that calls the other functions more directly or a function that combines them.
v

Valentin Metz

08/30/2020, 1:32 AM
It could also be a mutable List. I take Problems from ProjectEuler and I solve them. There are 700+ Problems available. I could have the array initialised with a default print of "Not implemented yet". And I could overwrite positions in the array with pointers to my new function, as soon as I've solved a Problem. Kotlin seems to support high order functions, so it should be possible. I'll let you know once I got something.
m

Michael de Kaste

08/31/2020, 7:29 AM
Let me jump right in. Trying to solve all project euler problems by merely using functions doesn't seem like a good idea to me. You're probably better of using an object per problem and solving them respectively in there. For instance, here is a picture of how I implemented an advent of code problem.
Can you provide an example of what you roughly want to do @Valentin Metz?
v

Valentin Metz

08/31/2020, 7:56 AM
Oh, I'm writing one file per problem. And I'm just handing the main Array<String> args without the first argument over to the function, as if it were a main itself, so I'm flexible. For now I'm using a switch statement to call the according function with the problem being selectable cia a command line argument.
m

Michael de Kaste

08/31/2020, 9:28 AM
Mhh you can solve the problem by creating all problems in a single file with a sealed subclass and then, using reflection, you can access them like so:
Copy code
sealed class EulerExample1{
    abstract fun solve(params: Array<String>)
    
    companion object{
        val classMap = EulerExample1::class
            .sealedSubclasses
            .associateBy({it.simpleName},{it.objectInstance})
    }
}

object Problem1Example1 : EulerExample1() {
    override fun solve(params: Array<String>) {
        println("solving problem 1")
    }
}

object Problem2Example1 : EulerExample1() {
    override fun solve(params: Array<String>) {
        println("solving problem 2")
    }
}
with fun main:
Copy code
fun main(params: Array<String>){
    EulerExample1.classMap["Problem1Example1"]?.solve(params)
    EulerExample1.classMap["Problem2Example1"]?.solve(params)
}
however, I can understand how this can become cumbersome as all the solutions per object now need to be in the same file, so what you could do is use delegation to delegate by seperate files like so:
Copy code
fun main(params: Array<String>){
    EulerExample2.classMap["Problem1"]?.solve(params)
    EulerExample2.classMap["Problem2"]?.solve(params)
}

sealed class EulerExample2 : IEulerExample2{
    companion object{
        val classMap = EulerExample2::class
            .sealedSubclasses
            .associateBy({it.simpleName},{it.objectInstance})
    }
    
    object Problem1 : EulerExample2(), IEulerExample2 by P1
    object Problem2 : EulerExample2(), IEulerExample2 by P2
}

interface IEulerExample2{
    fun solve(params: Array<String>)
}

object P1 : IEulerExample2 {
    override fun solve(params: Array<String>) {
        println("solving problem 1")
    }
}

object P2 : IEulerExample2 {
    override fun solve(params: Array<String>) {
        println("solving problem 2")
    }
}
P1 and P2 can be in seperate files so you can work on them individually
if you work on a new problem, you simply add the problem to the sealed class with the object name being the string you will provide by the params, and then implement the interface as an object in a seperate file.
Is this what you need? @Valentin Metz
v

Valentin Metz

08/31/2020, 11:09 AM
That looks very interesting. For now I think I'll go with a simple function selection via a switch case. The whole high order functions / array of functions was more about learning how to do it in kotlin than using it productively for this case.
m

Michael de Kaste

09/01/2020, 12:08 PM
I usually just create a fun main per problem though 🙂