LeetCode in Kotlin

1106. Parsing A Boolean Expression

Hard

Return the result of evaluating a given boolean expression, represented as a string.

An expression can either be:

Example 1:

Input: expression = “!(f)”

Output: true

Example 2:

Input: expression = “|(f,t)”

Output: true

Example 3:

Input: expression = “&(t,f)”

Output: false

Constraints:

Solution

class Solution {
    private var source: String? = null
    private var index = 0

    fun parseBoolExpr(expression: String?): Boolean {
        source = expression
        index = 0
        return expr()
    }

    private fun expr(): Boolean {
        val res: Boolean
        res = if (match('!')) {
            not()
        } else if (match('&')) {
            and()
        } else if (match('|')) {
            or()
        } else {
            bool()
        }
        return res
    }

    private fun not(): Boolean {
        consume('!')
        return !group()[0]
    }

    private fun or(): Boolean {
        consume('|')
        var res = false
        for (e in group()) {
            res = res or e
        }
        return res
    }

    private fun and(): Boolean {
        consume('&')
        var res = true
        for (e in group()) {
            res = res and e
        }
        return res
    }

    private fun group(): List<Boolean> {
        consume('(')
        val res: MutableList<Boolean> = ArrayList()
        while (!match(')')) {
            res.add(expr())
            if (match(',')) {
                advance()
            }
        }
        consume(')')
        return res
    }

    private fun bool(): Boolean {
        val isTrue = match('t')
        advance()
        return isTrue
    }

    private val isAtEnd: Boolean
        get() = index >= source!!.length

    private fun advance() {
        if (isAtEnd) {
            return
        }
        index++
    }

    private fun peek(): Char {
        return source!![index]
    }

    private fun match(ch: Char): Boolean {
        return if (isAtEnd) {
            false
        } else {
            peek() == ch
        }
    }

    private fun consume(ch: Char) {
        if (!match(ch)) {
            return
        }
        advance()
    }
}