class Solution {
    private fun buildTable(words: Sequence<String>): Map<String, Int> {
        val table = mutableMapOf<String, Int>()

        words.forEach {
            table.put(it, 1 + table.getOrElse(it) { 0 })
        }

        return table
    }

    private fun buildTable(
        s: String,
        length: Int,
    ): Map<String, Int> = buildTable(s.chunked(length).asSequence())

    fun findSubstring(
        s: String,
        words: Array<String>,
    ): List<Int> {
        val expectedFrequencies = buildTable(words.asSequence())
        val wordLen = words.first().length
        val windowSize = wordLen * words.size

        return s
            .windowed(windowSize)
            .zip(s.indices)
            .filter { (window, _) ->
                val frequencies = buildTable(window, wordLen)
                frequencies == expectedFrequencies
            }
            .map { (_, idx) -> idx }
            .toList()
    }
}