Created
August 22, 2020 10:33
-
-
Save mayuroks/06a52555568ae8b1e3d66405a3a96f0a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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