diff --git a/src/main/kotlin/calculator/Main.kt b/src/main/kotlin/calculator/Main.kt new file mode 100644 index 0000000000..3016ae64da --- /dev/null +++ b/src/main/kotlin/calculator/Main.kt @@ -0,0 +1,10 @@ +package calculator + +import java.util.* + +fun main() { + println("계산식을 입력해주세요.") + val sc = Scanner(System.`in`) + val result = StringCalculator.calculate(sc.nextLine()) + println(result); +} diff --git a/src/main/kotlin/calculator/StringCalculator.kt b/src/main/kotlin/calculator/StringCalculator.kt new file mode 100644 index 0000000000..ce1afe4d6b --- /dev/null +++ b/src/main/kotlin/calculator/StringCalculator.kt @@ -0,0 +1,46 @@ +package calculator + +data class StringCalculator(val totalNumber: Int) { + + companion object { + fun calculate(input: String?): Int { + if (input.isNullOrBlank()) { + return 0 + } + + if (input.length == 1 && input.all { it.isDigit() }) { + return input.toInt() + } + + val (delimiter, text) = parseDelimiterAndText(input) + validate(text, delimiter) + return splitString(text, delimiter) + } + + private fun parseDelimiterAndText(input: String?): Pair { + var delimiter = "[,:]" + var text = input + val result = text?.let { Regex("//(.)\n(.*)").find(it) } + result?.let { + delimiter = it.groupValues[1] + text = it.groupValues[2] + } + return Pair(delimiter, text) + } + + private fun validate(input: String?, delimiter: String) { + if ( + Regex("[^\\d\n$delimiter//]").containsMatchIn(input.toString())) { + throw RuntimeException() + } + } + + private fun splitString( + inputString: String?, + delimiter: String, + ): Int { + return inputString?.split(Regex(delimiter))?.map(String::toInt) + ?.sum() ?: 0 + } + } +} diff --git a/src/test/kotlin/StringCalculatorTest.kt b/src/test/kotlin/StringCalculatorTest.kt new file mode 100644 index 0000000000..07198e145e --- /dev/null +++ b/src/test/kotlin/StringCalculatorTest.kt @@ -0,0 +1,57 @@ +import calculator.StringCalculator +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatRuntimeException +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.CsvSource +import org.junit.jupiter.params.provider.NullAndEmptySource +import org.junit.jupiter.params.provider.ValueSource + +class StringCalculatorTest { + @ParameterizedTest + @DisplayName(value = "쉼표, 콜론을 구분자로 분리한다.") + @CsvSource(value = ["'1,2',3", "'1:3',4"]) + fun stringSplitTest( + inputString: String, + expacted: Int, + ) { + assertThat(StringCalculator.calculate(inputString)).isEqualTo(expacted) + } + + @ParameterizedTest + @DisplayName(value = "커스텀 구분자가 있으면 그 구분자로 분리한다.") + @CsvSource(value = ["'//;\n1;2',3", "'//_\n1_3',4"]) + fun customSplitTest( + inputString: String, + expacted: Int, + ) { + assertThat(StringCalculator.calculate(inputString)).isEqualTo(expacted) + } + + @ParameterizedTest + @DisplayName(value = "음수 및 숫자 아닌값은 에러처리한다.") + @CsvSource(value = ["'-1:2',3", "'//_\n1@3',4"]) + fun SplitfailTest( + inputString: String, + expacted: Int, + ) { + assertThatRuntimeException().isThrownBy { + StringCalculator.calculate(inputString) + } + } + + @DisplayName(value = "숫자 하나를 문자열로 입력할 경우 해당 숫자를 반환한다.") + @ParameterizedTest + @ValueSource(strings = ["1"]) + fun oneNumber(text: String) { + assertThat(StringCalculator.calculate(text)).isSameAs(Integer.parseInt(text)); + } + + + @DisplayName(value = "빈 문자열 또는 null 값을 입력할 경우 0을 반환해야 한다.") + @ParameterizedTest + @NullAndEmptySource + fun emptyOrNull(text: String?) { + assertThat(StringCalculator.calculate(text)).isZero(); + } +} diff --git a/step1README.md b/step1README.md new file mode 100644 index 0000000000..6ca6680b34 --- /dev/null +++ b/step1README.md @@ -0,0 +1,13 @@ +# 문자열 덧셈 계산기 + +기능 요구사항 +1. 쉼표, 콜론을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환한다.(""=>0, "1,2=>3, "1,2,3"=>6, "1,2:3"=>6) + 2. - [x] 쉼표, 콜론를 기본 구분자로 판단하여 분리하여 리스트에 저장.or 바로 더하기 +2. 앞의 기본 구분자외 커스텀 구분자 지정 가능. //와 \n 사이 위치문자를 커스텀 구분자로 사용한다. + 3. - [x] //와 \n이 둘다 있을 경우 \\다음 문자를 구분자로 간주하고 분리 +3. 문자열 계산기에 숫자이외 값 or 음수 전달시 RuntimeException throw + 4. - [x] 구분자로 분리하고 순회하면서 숫자 이외값 있을시 throw. 이때 구분자랑 커스텀구분자는 제외 필요 + + +구조 +문자열 계산기 클래스