Skip to content

Instantly share code, notes, and snippets.

@mayuroks
Created August 22, 2020 10:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mayuroks/06a52555568ae8b1e3d66405a3a96f0a to your computer and use it in GitHub Desktop.
Save mayuroks/06a52555568ae8b1e3d66405a3a96f0a to your computer and use it in GitHub Desktop.
package com.example.sigsegvapp
/*
* Notes:
*
* OpWeight function to get weight of an op
* Max function to return highest of two ops
*
* Evaluate entire string for all operators
* Save highest and leftmost operator
* Iterative evaluate reduced strings
*
* Iterative Reduction
* 10 * 2 - 4 + 1
* 20 - 4 + 1
* 20 - 5
* 15
*
* Test input
* eval("50+20/10")
* eval("50/20+5")
* eval("25-2*10")
* eval("10/2-20")
* eval("10-2-3")
* eval("10/2/5")
* eval("10/2/4+1")
* eval("10/0/4+1")
*
* Usage
*
* try {
* val output = eval(expression)
* }
* catch (ex: Exception) {
* // Can throw arithmetic exception
* }
* */
fun eval(expr: String): Int {
println("logeval called")
var input: ArrayList<String> = parseInput(expr) as ArrayList<String>
while (input.size > 1) {
println("logeval res.size ${input.size}")
/*
* Find highest leftmost operator using 2 points
* Reduce the numbers around highest
* Update the input array
* */
var highestOpIndex = 0
for (i in input.size - 2 downTo 1 step 2) {
highestOpIndex = maxOpIndex(highestOpIndex, i, input)
}
println("logeval highest at $highestOpIndex ${input[highestOpIndex]}")
input[highestOpIndex - 1] = compute(
input[highestOpIndex - 1].toInt(),
input[highestOpIndex + 1].toInt(),
input[highestOpIndex]
).toString()
input.removeAt(highestOpIndex)
input.removeAt(highestOpIndex)
}
println("logeval final $input")
return input[0].toInt()
}
fun compute(a: Int, b: Int, operator: String): Int {
var res = 0
res = when (operator) {
"+" -> a + b
"-" -> a - b
"/" -> a / b
"*" -> a * b
else -> throw IllegalArgumentException("Bad params")
}
return res
}
fun maxOpIndex(r: Int, l: Int, res: List<String>): Int {
val diff = getOpWeight(res[l]) - getOpWeight(res[r])
return when {
diff > 0 -> return l
diff < 0 -> return r
diff == 0 -> return l
else -> 0
}
}
fun getOpWeight(op: String): Int {
return when (op) {
"+" -> 3
"-" -> 1
"/" -> 2
"*" -> 4
else -> 0
}
}
fun parseInput(expr: String): List<String> {
val reg = Regex("(?<=[+-/*])|(?=[+-/*])")
val list = expr.split(reg).filter { it.isNotEmpty() }
println("logeval parse $list")
return list
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment