Skip to content

Instantly share code, notes, and snippets.

@hannut91
Last active June 3, 2022 00:40
Show Gist options
  • Save hannut91/643d8f84c1510c5248b739c2346aeee1 to your computer and use it in GitHub Desktop.
Save hannut91/643d8f84c1510c5248b739c2346aeee1 to your computer and use it in GitHub Desktop.
코드스피츠 90강 코틀린 과제 1
package org.example.assignment1
val trimRegex = """[^().\d-+*/]""".toRegex()
val parenthesesRegex = """\((-?[.\d]+)([/*+-])(-?[.\d]+)\)""".toRegex()
val expressionRegex = """(-?[.\d]+)([/*+-])(-?[.\d]+)"""
.toRegex()
val multiplyAndDivideRegex = """([.\d]+)([*/])([.\d]+)"""
.toRegex()
fun trim(v: String): String {
return v.replace(trimRegex, "")
}
fun calculate(left: String, op: String, right: String): Double {
val leftValue = left.toDouble()
val rightValue = right.toDouble()
val calculatedValue = when (op) {
"+" -> leftValue + rightValue
"-" -> leftValue - rightValue
"*" -> leftValue * rightValue
"/" -> leftValue / rightValue
else -> throw Throwable("invalid operator $op")
}
return calculatedValue
}
fun sum(v: String): Double {
val parenthesesRegexResult = parenthesesRegex.find(v)
if (parenthesesRegexResult != null) {
val (value) = parenthesesRegexResult.groupValues
val range = parenthesesRegexResult.range
val l = v.slice(0 until range.first)
val middle = sum(value.drop(1).dropLast(1))
val r = v.substring(range.last +1)
return sum(l + middle + r)
}
val multiplyRegexResult = multiplyAndDivideRegex.find(v)
if (multiplyRegexResult != null) {
val (_, left, op, right) = multiplyRegexResult.groupValues
val calculatedValue = calculate(left, op, right)
val range = multiplyRegexResult.range
val l = v.slice(0 until range.first)
val r = v.substring(range.last +1)
return sum(l + calculatedValue + r)
}
val matchedResult = expressionRegex.find(v)
if (matchedResult == null) {
return v.toDouble()
}
val (r, left, op, right) = matchedResult.groupValues
val calculatedValue = calculate(left, op, right)
return sum("${calculatedValue}${v.drop(r.length)}")
}
fun calc(v:String) = sum(trim(v) )
package org.example.assignment1
import io.kotest.core.spec.style.DescribeSpec
import io.kotest.matchers.shouldBe
class Assignment1KtTest : DescribeSpec({
describe("assignment1") {
it("returns calculated value") {
calc("-2 -3 + 0.4") shouldBe -4.6
}
}
describe("assignment2") {
it("returns calculated value") {
calc("-2 * (-3 + 0.4) / - 0.2") shouldBe -26
}
}
describe("calc") {
context("only plus and minus") {
it("returns calculated value") {
calc("1 + 1") shouldBe 2
calc("1 + 1") shouldBe 2
calc("1 + 1 + 1") shouldBe 3
calc("1 + 1 - 3") shouldBe -1
calc("5 - 1") shouldBe 4
}
}
context("with multiply") {
it("returns calculated value") {
calc("1 * 2") shouldBe 2
calc("2 * 2 * 2 * 2") shouldBe 16
}
}
context("with divide") {
it("returns calculated value") {
calc("16 / 2") shouldBe 8
calc("16 / 2 / 2") shouldBe 4
calc("16 / 2 / 2 / 2") shouldBe 2
calc("16 / 2 / 2 / 2 / 2") shouldBe 1
calc("16 / 2 / 2 / 2 / 2 / 2") shouldBe 0.5
}
}
context("with multiply and plus") {
it("returns calculated value") {
calc("2 + 2 * 2") shouldBe 6
calc("2 * 2 + 2 * 2") shouldBe 8
}
}
context("with divide and plus") {
it("returns calculated value") {
calc("2 + 2 / 2") shouldBe 3
calc("2 / 2 + 2 / 2 + 2 * 2") shouldBe 6
}
}
context("with negative number") {
it("returns calculated value") {
calc("-2 + 3") shouldBe 1
calc("-2 + -3") shouldBe -5
calc("-2 - -3") shouldBe 1
}
}
context("with negative number and multiply") {
it("returns calculated value") {
calc("3 * -2") shouldBe -6
calc("-3 * -2") shouldBe 6
}
}
context("with ()") {
it("returns calculated value") {
calc("(2 + 2) * 2") shouldBe 8
calc("2 + (2 * 2)") shouldBe 6
calc("2 + (2 + 2) * 2") shouldBe 10
calc("2 + 2") shouldBe 4
}
}
context("with (())") {
it("returns calculated value") {
calc("((2 + 2) * 2) * 2 + (2 + 2)") shouldBe 20
}
}
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment