diff --git a/README.md b/README.md index 13420b29..9780bf48 100644 --- a/README.md +++ b/README.md @@ -1 +1,50 @@ -# javascript-calculator-precourse \ No newline at end of file +# 문자열 덧셈 계산기 + +## 구현할 기능 목록 + +1. 입력받은 문자열에서 숫자를 추출하여 합계를 계산한다. +2. 쉼표(`,`) 또는 콜론(`:`)을 구분자로 사용한다. +3. 커스텀 구분자를 지원한다. (`//`와 `\n` 사이의 문자) +4. 잘못된 입력 시 `[ERROR]` 메시지를 출력하고 프로그램을 종료한다. + +## 구현된 기능 + +### 입력 처리 + +- `Console.readLineAsync`로 사용자 입력 받기 +- 빈 문자열 입력 시 `0` 반환 +- `\\n`을 실제 개행 문자로 변환 + +### 구분자 처리 + +- 기본 구분자 (`,`, `:`)로 문자열 분리 +- 커스텀 구분자 `//;<구분자>\n<숫자>` 형식 파싱 +- 여러 문자로 된 구분자 지원 (`|` 연산자 사용) + +### 계산 및 검증 + +- 분리된 토큰이 숫자인지 검증 +- 양의 정수만 허용 (음수 예외 처리) +- 합계 계산 후 반환 + +### 출력 및 예외 처리 + +- `Console.print`로 결과 출력 (`결과 : <합계>`) +- 잘못된 입력 시 `[ERROR]` 메시지 출력 +- `Error` throw 후 프로그램 종료 + +## 예외 상황 + +- 음수 입력: `[ERROR] 음수는 입력할 수 없습니다.` +- 숫자 아닌 값: `[ERROR] 잘못된 숫자 입력: {값}` +- 잘못된 구분자 형식: `[ERROR] 커스텀 구분자 형식 오류.` + +## 실행 예시 + +``` +입력: 1,2,3 +출력: 결과 : 6 + +입력: //;\n1;2;3 +출력: 결과 : 6 +``` diff --git a/src/App.js b/src/App.js index 091aa0a5..84566c5a 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,19 @@ +import { Console } from "@woowacourse/mission-utils"; +import { calculate } from "./Calculator.js"; + class App { - async run() {} + async run() { + const input = await Console.readLineAsync( + "덧셈할 문자열을 입력해 주세요.\n" + ); + + try { + const result = calculate(input); + Console.print(`결과 : ${result}`); + } catch (error) { + throw error; + } + } } export default App; diff --git a/src/Calculator.js b/src/Calculator.js new file mode 100644 index 00000000..1da77b0e --- /dev/null +++ b/src/Calculator.js @@ -0,0 +1,45 @@ +export function StringSplitor(input) { + const str = String(input ?? "").trim(); + + if (str === "") return []; + + let customSeparator = ""; + let numbersPart = str; + + if (str.startsWith("//")) { + const normalized = str.replace(/\\n/g, "\n"); + const match = normalized.match(/^\/\/(.+)\r?\n(.*)$/); + + customSeparator = match[1]; + numbersPart = match[2]; + } + + const separators = [",", ":", customSeparator].filter(Boolean); + const pattern = new RegExp(separators.map(escapeRegExp).join("|")); + const tokens = numbersPart.split(pattern); + return tokens.filter((t) => t !== ""); +} +export function calculate(input) { + const numbers = StringSplitor(input); + + if (numbers.length === 0) return 0; + + let sum = 0; + for (const n of numbers) { + if (!/^\d+$/.test(n)) { + throw new Error(`[ERROR] 잘못된 숫자 입력: ${n}`); + } + + const value = parseInt(n, 10); + if (value < 0) { + throw new Error("[ERROR] 음수는 입력할 수 없습니다."); + } + + sum += value; + } + return sum; +} + +function escapeRegExp(str) { + return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +}