Skip to content

Instantly share code, notes, and snippets.

@fgoinai
Created May 19, 2017 19:11
Show Gist options
  • Save fgoinai/e0410b6b5d207161873526ef66cb8098 to your computer and use it in GitHub Desktop.
Save fgoinai/e0410b6b5d207161873526ef66cb8098 to your computer and use it in GitHub Desktop.
class CheckCal {
private val MAX = 128
private val valStack = Stack<Int>(MAX)
private val opStack = Stack<Char>(MAX)
private var buf = CharArray(MAX)
fun startCheck(inStream: InputStream) {
val reader = inStream.bufferedReader()
var prev: Int? = null
loop@ while(reader.read(buf) != -1) {
t@ for (t in buf) {
try {
when (t) {
' ' -> continue@t
'(' -> {
opStack.push(t)
prev = null
}
')' -> {
closeBracket()
prev = null
}
in nums -> {
if(prev!=null) valStack.pop()
val intOfT = Character.getNumericValue(t)
prev = prev?.times(10)?.plus(intOfT) ?: intOfT
valStack.push(prev)
}
in operators -> {
if(!opStack.isEmpty)
if(highPriority(t) && opStack.top != '(')
operate(opStack.pop())
opStack.push(t)
prev = null
}
'\n' -> {
finalCheck()
break@loop
}
else -> close("Only numbers and \"+-*/()\" are accepted!")
}
} catch (e: Exception) {
e.printStackTrace()
close("Exceed close brackets!")
}
}
}
println("Result is ${valStack.top}")
}
private fun highPriority(t: Char) = findPriority(opStack.top as Char) < findPriority(t)
private fun finalCheck() {
while (!opStack.isEmpty && !valStack.isEmpty) {
if (valStack.size == 1) throw Exception("Statement Error!")
operate(opStack.pop())
}
}
private fun closeBracket() {
for (op in opStack) {
if (op == '(') break
if (valStack.size < 2) throw Exception("Statement Error!")
operate(op)
}
}
private fun operate(tmp: Char) {
val cal = calculate(valStack.pop(), valStack.pop())
val ret = when (tmp) {
'+' -> cal(Int::plus)
'-' -> cal(Int::minus)
'*' -> cal(Int::times)
'/' -> cal(Int::div)
else -> throw Exception("Fuck")
}
valStack.push(ret)
}
private fun calculate(arg1: Int, arg2: Int) : ((Int, Int) -> Int) -> Int {
return fun (op: (Int, Int) -> Int) : Int {
return op(arg2, arg1)
}
}
private fun close(txt: String) {
println(txt)
System.exit(1)
}
private val nums = "1234567890".toCharArray()
private val operators = "+-*/".toCharArray()
val priority = arrayOf(
arrayOf('(', ')'),
arrayOf('*', '/'),
arrayOf('+', '-')
)
fun findPriority(t: Char) = priority.indexOf(priority.first{it.contains(t)})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment