Last active
June 7, 2022 01:33
-
-
Save dotNetTree/9035dda235cb171025bdbbcc7c9e114f to your computer and use it in GitHub Desktop.
Code Spitz 90 - 코틀린 언어편 (1) 과제
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
val trim = """[^.\d-+*/()]""".toRegex() | |
fun trim(v: String): String = v.replace(trim, "") | |
fun repMMtoP(v: String) = v.replace("--", "+") | |
fun repMtoPM(v: String) = v.replace("-", "+-") | |
val groupMD = """((?:\+|\+-)?[.\d]+)([*/])((?:\+|\+-)?[.\d]+)""".toRegex() | |
tailrec fun removeMultiDiv(v: String): String = groupMD.find(v).let { | |
if (it != null) { | |
val (target, left, op, right) = it.groupValues | |
val leftValue = left.replace("+", "").toDouble() | |
val rightValue = right.replace("+", "").toDouble() | |
val result = when (op) { | |
"*" -> leftValue * rightValue | |
"/" -> leftValue / rightValue | |
else -> throw Throwable("invalid operator $op") | |
} | |
removeMultiDiv(v.replace(target, "+$result")) | |
} else v | |
} | |
fun calcWithBracket(v: String): Double { | |
return v | |
.let { v.drop(1).dropLast(1) } | |
.let { trim(it) } | |
.let { repMMtoP(it) } | |
.let { repMtoPM(it) } | |
.let { removeMultiDiv(it) } | |
.split("""(\++)""".toRegex()) | |
.fold(0.0) { accu, curr -> | |
if (curr.isBlank()) { accu } else accu + curr.toDouble() | |
} | |
} | |
tailrec fun removeBracket(v: String): String { | |
return """\([.\d+\-*/]+\)""".toRegex().findAll(v).let { | |
if (it.count() == 0) v | |
else removeBracket( | |
it.fold(v) { acc, cur -> | |
val target = cur.value | |
val ret = calcWithBracket(target) | |
acc.replace(target, "$ret") | |
} | |
) | |
} | |
} | |
fun calc(v: String): Double = removeBracket("(${trim(v)})").toDouble() | |
fun main(args: Array<String>) { | |
val exps: Array<String> = arrayOf( | |
"16 / 2 / 2 / 2", | |
"-2 -3 + 0.4", | |
"-2 * (-3 + 0.4) / -0.2", | |
"-2 * (-3 + 0.4) / -0.2 + .55", | |
"-2 - (-3 + -8 * (7 + 3)) + (0.4 / -0.2)", | |
) | |
for (exp in exps) { | |
println("$exp = ${calc(exp)}") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
가능한 가까우면 좋은데, 무조건 그런 것은 아닙니다! 클래스가 등장하면 변수를 위에 놓고 메서드를 쓰니 꼭 그렇게 되지는 않겠죠 ㅎㅎ 변수를 사용할 때도 때로는 변수를 모아놓는 것이 좋을 때가 있는 것 같아요.
count 메서드가 있었군요 감사합니다!