4

In a 3x3 matrix representation, i can find the sum of both diagonals with one liners in Swift as below,

let array = [
   [1, 2, 3],
   [4, 5, 6],
   [-7, 8, 9]
]
let d1 = array.enumerated().map({ $1[$0] }).reduce(0, +)
let d2 = array.reversed().enumerated().map({ $1[$0] }).reduce(0, +)
print(d1) // prints 15
print(d2) // prints 1

I am able to find map and reduce equivalents in Kotlin as flatMap and fold but couldn't find for enumerated.

How can we achieve similar with higher order functions in Kotlin?

Kamran
  • 14,987
  • 4
  • 33
  • 51

2 Answers2

6

Starting with this input:

val input: Array<Array<Int>> = arrayOf(
        arrayOf(1, 2, 3),
        arrayOf(4, 5, 6),
        arrayOf(-7, 8, 9)
)

this is how I'd phrase the diagonal sums:

val mainDiagonalSum = input.indices
        .map { input[it][it] }
        .reduce(Int::plus)
val counterDiagonalSum = input.indices
        .map { input[input.size - 1 - it][it] }
        .reduce(Int::plus)

Note that this is an improvement over your solution because it doesn't have to create the reversed array. It improves the time complexity from O(n2) to O(n).

If you're dealing with large matrices, it would pay to reduce the space complexity from O(n) to O(1) as well, by using fold instead of reduce:

val mainDiagonalSum = input.indices
        .fold(0) { sum, i -> sum + input[i][i] }
val counterDiagonalSum = input.indices
        .fold(0) { sum, i -> sum + input[input.size - 1 - i][i] }
Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • `fold` is also important if you have empty arrays. I often find myself using `fold` instead of `reduce` in 99% of the cases. – Adam Arold Oct 10 '18 at 13:58
3

It looks like you're looking for withIndex

Nikolay Ivanov
  • 8,897
  • 3
  • 31
  • 34