fun main(args: Array<String>) {
println("""${decompress("a2b3c4(dfgh)5(3w6(Qwe))")}""")
}
fun decompress(s: String): String {
val result = StringBuilder()
var cursor = 0
while(cursor < s.length) {
when (val c = s[cursor]) {
in '0'..'9' -> {
++cursor
if (s[cursor] == '(') {
val length = findSubstrLength(s, cursor)
val decompressedSubStr = decompress(s.substring(cursor + 1, cursor + length))
cursor += length + 1
('1'..c).forEach {
result.append(decompressedSubStr)
}
} else {
('1'..c).forEach {
result.append(s[cursor])
}
++cursor
}
}
else -> {
++cursor
result.append(c)
}
}
}
return result.toString()
}
private fun findSubstrLength(s: String, position: Int): Int {
var count = 1
var cursor = position + 1
while(count != 0 && cursor < s.length) {
when(s[cursor]) {
'(' -> ++count
')' -> --count
}
++cursor
}
if (cursor == s.length && count != 0) throw IllegalStateException()
return cursor - position - 1
}
fun main(args: Array<String>) {
println("""${solve("2+2*2")} == 6?""")
println("""${solve("3+2*5")} == 13""")
println("""${solve("1+2+3+4+5+6")} == ${1+2+3+4+5+6}""")
println("""${solve("1*2*3*4*5*6")} == ${1*2*3*4*5*6}""")
println("""${solve("(2+2)*2")} == 8""")
println("""${solve("(2*2)+2")} == 6""")
println("""${solve("(1+2)*(3+4+5)*(6+7)+(7*8+9)")} == ${(1+2)*(3+4+5)*(6+7)+(7*8+9)}""")
println("""${solve("(1+2*(2+3*4)+5*(6+(7+8*(9+1))))")} == ${(1+2*(2+3*4)+5*(6+(7+8*(9+1))))}""")
}
fun solve(expr: String) = Solver(expr).solve()
class Solver(private val expr: String) {
private var cursor = 0
private lateinit var token: Token
fun solve(): Int {
cursor = 0
next()
return addExpr()
}
private fun addExpr(): Int {
var result = mulExpr()
while (token == Plus) {
next()
result += mulExpr()
}
return result
}
private fun mulExpr(): Int {
var result = unaryExpr()
while (token == Asterisk) {
next()
result *= unaryExpr()
}
return result
}
private fun unaryExpr(): Int {
if (token == OpenBrace) {
next()
val result = addExpr()
if (token != CloseBrace) throw IllegalStateException("wrong expression at symbol $cursor")
next()
return result
}
if (token is Num) {
val result = (token as Num).v
next()
return result
}
throw IllegalStateException("wrong expression at symbol $cursor")
}
private fun next() {
if (cursor >= expr.length) {
token = Eof
return
}
token = when (val c = expr[cursor]) {
in '0'..'9' -> Num(c.toInt() - '0'.toInt())
'+' -> Plus
'*' -> Asterisk
'(' -> OpenBrace
')' -> CloseBrace
else -> throw IllegalStateException("unknown symbol $c")
}.also { cursor++ }
}
}
private sealed class Token
private class Num(val v: Int): Token()
private object Plus: Token()
private object Asterisk: Token()
private object OpenBrace: Token()
private object CloseBrace: Token()
private object Eof: Token()