Return the indices of the two numbers such that they add up to a specific target (...as I learn Kotlin) I want to get the indices of the two numbers such that they add up to a specific target from a given array of integers.

Solution:

fun sum(values: Array&lt;Int&gt;, result: Int): Array&lt;Int&gt; {
  for ((i, e1) in values.withIndex()) {
    for ((j, e2) in values.drop(i + 1).withIndex()) { // ...or: values.drop(i + 1).forEachIndexed { j, e2 -&gt;
      //println("$i : $e1 &gt;&gt; $j : $e2")
      if (e1 + e2 == result) {
        return arrayOf(i, i + j + 1)
      }
    }
  }
  return emptyArray()
}


Test cases:

class SumTest {
  @Test
  fun testSum() {
    Assert.assertArrayEquals(sum(arrayOf(4, 7, 9, 10, 6, 34), 10), arrayOf(0, 4))
    Assert.assertArrayEquals(sum(arrayOf(5, 7, 9, 10, 21, 34), 43), arrayOf(2, 5))
    Assert.assertArrayEquals(sum(arrayOf(2, 7, 11, 15), 9), arrayOf(0, 1))
    Assert.assertArrayEquals(sum(arrayOf(2, 7, 8, 6, 20), 11), emptyArray())
  }
}


I know this is a pretty simple algorithm, but I would like to avoid the return arrayOf(i, i + j + 1) and modifying the values array in the second loop (values.drop(i + 1).withIndex()) if possible. A functional-towards approach would be great!
sum

The word sum sounds like your taking an iterable of some sort and summing all the values in it. sumsTo would be a better name. Even then, I would expect to return all possible pairings, which the code doesn't currently do.

result

I wouldn't call it result. I'm not that familiar with Kotlin, but sometimes APIs will write to the value you pass in and so the function doesn't return anything but it modifies the result variable. Maybe target is a better choice?

Pair datatype

I would change your datatype from Array to Pair. You are returning a pair of integers satisfying the equation so why choose an array when there is a Pair data type object? I also suggest that if no solution is found that you, yes, return null.

null is often a bad design choice, but I strongly believe this is the exception. If there are no solutions we say that the solution set is null (or the empty set). So if there are no pairs the solution set is null. Reads just like math.

Generalizing to Iterable

You could just iterate over an array of values, but more generally you probably want to iterate over an Iterable collection of integers.

The one cost of this is you have to say arrayOf(...).asIterable().

The code

fun sumsTo(values: Iterable&lt;Int&gt;, target: Int): Pair&lt;Int, Int&gt;? {
  for ((i, e1) in values.withIndex()) {
    for ((j, e2) in values.drop(i + 1).withIndex()) {
      if (e1 + e2 == target) {
        return Pair(i, i + j + 1)
      }
    }
  }
  return null
}