diff --git a/README.md b/README.md index bd90ef0247..9bc3d31c21 100644 --- a/README.md +++ b/README.md @@ -1 +1,11 @@ -# java-calculator-precourse \ No newline at end of file +# java-calculator-precourse + +## 구현 기능 목록 +- [✓] 빈 문자열 또는 null 입력이면 0을 반환한다. +- [✓] 기본 구분자(쉼표 `,`, 콜론 `:`)로 분리한 숫자의 합을 반환한다. +- [✓] 커스텀 구분자 형식 `//<구분자>\n<숫자들>` 을 지원한다. +- [✓] 음수 입력 시 `IllegalArgumentException`을 발생시킨다. +- [✓] 숫자가 아닌 토큰 입력 시 `IllegalArgumentException`을 발생시킨다. +- [✓] 출력 형식: `결과 : <합>` 을 엄수한다. +- [✓] `Application.main()`에서 `Console.readLine()`으로 입력을 받는다. +- [✓] JDK 21, 외부 라이브러리 추가 금지(build.gradle 수정 금지). diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index 573580fb40..6b3a3d0906 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -1,7 +1,22 @@ package calculator; +import camp.nextstep.edu.missionutils.Console; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + System.out.println("덧셈할 문자열을 입력해 주세요."); + + // 1) 한 줄만 읽는다 + String input = Console.readLine(); + + // 2) 만약 문자 그대로의 "\n"이 들어왔다면 실제 개행으로 치환 + // 예: "//;\\n1;2;3" -> "//;\n1;2;3" + if (input != null && input.contains("\\n")) { + input = input.replace("\\n", "\n"); + } + + // 3) 계산 후 정확한 포맷으로 출력 + int result = StringCalculator.add(input); + System.out.println("결과 : " + result); } } diff --git a/src/main/java/calculator/StringCalculator.java b/src/main/java/calculator/StringCalculator.java new file mode 100644 index 0000000000..5643e154f8 --- /dev/null +++ b/src/main/java/calculator/StringCalculator.java @@ -0,0 +1,49 @@ +package calculator; + +import java.util.regex.Pattern; + +public class StringCalculator { + + private static final String DEFAULT_DELIMS = "[,:]"; + + public static int add(String input) { + if (input == null || input.isBlank()) { + return 0; + } + + String numbers = input; + String delimiterRegex = DEFAULT_DELIMS; + + // //<구분자>\n<숫자들> + if (input.startsWith("//")) { + int nl = input.indexOf('\n'); + if (nl < 0) { + throw new IllegalArgumentException("잘못된 커스텀 구분자 형식"); + } + String custom = input.substring(2, nl); + delimiterRegex = DEFAULT_DELIMS + "|" + Pattern.quote(custom); + numbers = input.substring(nl + 1); + } + + String[] tokens = numbers.split(delimiterRegex, -1); + + int sum = 0; + for (String raw : tokens) { + String s = raw.trim(); + if (s.isEmpty()) { + throw new IllegalArgumentException("빈 토큰"); + } + final int value; + try { + value = Integer.parseInt(s); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("숫자가 아님: " + s); + } + if (value < 0) { + throw new IllegalArgumentException("음수 허용 안됨: " + value); + } + sum += value; + } + return sum; + } +} diff --git a/src/test/java/calculator/StringCalculatorTest.java b/src/test/java/calculator/StringCalculatorTest.java new file mode 100644 index 0000000000..6de62c09ef --- /dev/null +++ b/src/test/java/calculator/StringCalculatorTest.java @@ -0,0 +1,27 @@ +package calculator; + +// 테스트 어노테이션 +import org.junit.jupiter.api.Test; +// 검증(assertThat) +import static org.assertj.core.api.Assertions.assertThat; + +class StringCalculatorTest { + + // "" (빈 문자열)이면 0을 돌려야 한다 + @Test + void emptyString_returns0() { + assertThat(StringCalculator.add("")).isEqualTo(0); + } + + // "1,2:3" 같이 쉼표/콜론을 구분자로 합산해야 한다 + @Test + void sum_with_comma_and_colon() { + assertThat(StringCalculator.add("1,2:3")).isEqualTo(6); + } + + // 커스텀 구분자: "//;\n1;2;3" -> 6 + @Test + void custom_delimiter_semicolon() { + assertThat(StringCalculator.add("//;\n1;2;3")).isEqualTo(6); + } +}