class Solution {
    private data class Accumulator(val firstIndex: Int, var count: Int = 0) {
        fun add() {
            count++
        }
    }

    fun firstUniqChar(s: String): Int = s
        .foldIndexed(mutableMapOf<Char, Accumulator>()) { i, acc, c ->
            acc.getOrPut(c) { Accumulator(i) }.add()
            acc
        }
        .filterValues { it.count == 1 }
        .minByOrNull { (_, acc) -> acc.firstIndex }
        ?.value
        ?.firstIndex
        ?: -1
}

fun main() {
    val s = Solution()

    check(s.firstUniqChar("leetcode") == 0)
    check(s.firstUniqChar("loveleetcode") == 2)
    check(s.firstUniqChar("aabb") == -1)
}