Erect the Fence using Kotlin
class Solution {
    
    class Trees(val type: Type) {
        enum class Type(val value: Int) {
            CONVEX(1), CONCAVE(-1)
        }

        private val _trees = mutableListOf<IntArray>()
        val trees: List<IntArray> = _trees

        fun add(tree: IntArray) {
            val needRemoveLast: () -> Boolean = {
                trees.size > 1 && run {
                    val prev = trees[trees.lastIndex]
                    val prevPrev = trees[trees.lastIndex - 1]
                    return@run ((tree[1] - prev[1]) * (prev[0] - prevPrev[0]) -
                            (prev[1] - prevPrev[1]) * (tree[0] - prev[0])) * type.value > 0
                }
            }
            while (needRemoveLast()) {
                _trees.removeAt(trees.lastIndex)
            }
            _trees.add(tree)
        }
    }

    fun outerTrees(trees: Array<IntArray>): Array<IntArray> {
        trees.sortWith(compareBy({ it[0] }, { it[1] }))
        val structuredTrees = trees.groupByTo(TreeMap<Int, MutableList<IntArray>>(), { it[0] }).values

        val upperTrees = Trees(Trees.Type.CONVEX)
        val lowerTrees = Trees(Trees.Type.CONCAVE)

        structuredTrees.forEach {
            upperTrees.add(it.last())
            lowerTrees.add(it.first())
        }

        return mutableSetOf<IntArray>().apply {
            addAll(structuredTrees.first())
            addAll(structuredTrees.last())
            addAll(upperTrees.trees)
            addAll(lowerTrees.trees)
        }.toTypedArray()
    }
}
Comments (1)