diff --git a/README.md b/README.md index 13420b29..3477ace4 100644 --- a/README.md +++ b/README.md @@ -1 +1,64 @@ -# javascript-calculator-precourse \ No newline at end of file +# 문자열 덧셈 계산기 + +## 기능 요구 사항 + +입력한 문자열에서 숫자를 추출하여 더하는 계산기를 구현한다. + +- 쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환한다. + - 예: "" => 0, "1,2" => 3, "1,2,3" => 6, "1,2:3" => 6 +- 앞의 기본 구분자(쉼표, 콜론) 외에 커스텀 구분자를 지정할 수 있다. 커스텀 구분자는 문자열 앞부분의 "//"와 "\n" 사이에 위치하는 문자를 커스텀 구분자로 사용한다. + - 예를 들어 "//;\n1;2;3"과 같이 값을 입력할 경우 커스텀 구분자는 세미콜론(;)이며, 결과 값은 6이 반환되어야 한다. +- 사용자가 잘못된 값을 입력할 경우 "[ERROR]"로 시작하는 메시지와 함께 Error를 발생시킨 후 애플리케이션은 종료되어야 한다. + +## 입출력 요구 사항 + +#### 입력 + +- 구분자와 양수로 구성된 문자열 + +#### 출력 + +- 덧셈 결과 + +``` +결과 : 6 +``` + +#### 실행 결과 예시 + +``` +덧셈할 문자열을 입력해 주세요. +1,2:3 +결과 : 6 +``` + +## 프로그래밍 요구 사항 + +- Node.js 22.19.0 버전에서 실행 가능해야 한다. +- 프로그램 실행의 시작점은 `App.js`의 `run()`이다. +- `package.json` 파일은 변경할 수 없으며, 제공된 라이브러리와 스타일 라이브러리 이외의 외부 라이브러리는 사용하지 않는다. +- 프로그램 종료 시 `process.exit()`를 호출하지 않는다. +- 프로그래밍 요구 사항에서 달리 명시하지 않는 한 파일, 패키지 등의 이름을 바꾸거나 이동하지 않는다. +- 자바스크립트 코드 컨벤션을 지키면서 프로그래밍한다. + - 기본적으로 [JavaScript Style Guide](https://github.com/woowacourse/woowacourse-docs/tree/main/styleguide/javascript)를 원칙으로 한다. + +### 라이브러리 + +- `@woowacourse/mission-utils`에서 제공하는 `Console` API를 사용하여 구현해야 한다. +- 사용자의 값을 입력 및 출력하려면 `Console.readLineAsync()`와 `Console.print()`를 활용한다. + +## 구현한 기능 + +#### 1. 문자열 입력 +#### 2. 쉼표(,), 콜론(:) 구분자를 기준으로 숫자 분리 +#### 3. 계산 및 결과 반환 +#### 4. 커스텀 구분자 추가 +#### 5. 예외 처리 + +- 빈 문자열을 입력한 경우 +- 지정된 구분자 외에 다른 문자가 포함된 경우 +- 커스텀 구분자 지정이 잘못된 경우 + - 맨 앞에 작성되지 않은 경우 + - 구분자가 없거나 두 개 이상 작성된 경우 + - 구분자에 (,)나 (:)가 작성된 경우 +- 숫자에 0을 입력한 경우 diff --git a/src/App.js b/src/App.js index 091aa0a5..97f5d6f7 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,64 @@ +import { Console } from "@woowacourse/mission-utils"; + class App { - async run() {} + async run() { + /* 문자열 입력 */ + let input = await Console.readLineAsync( + "덧셈할 문자열을 입력해 주세요.\n" + ); + + // 예외처리 - 빈 문자열을 입력한 경우 + if (input === "") { + return Console.print("결과 : 0"); + } + + /* 커스텀 구분자 추가 */ + let custom = ""; + let customForm = input.match(/\/\/.*\\n/); + + if (customForm) { + // 예외처리 - 커스텀 구분자 지정이 잘못된 경우 + if (customForm.index !== 0) { + throw new Error( + "[ERROR] 커스텀 구분자 지정 형식은 맨 앞에 작성해야 합니다." + ); + } + if (customForm[0].length !== 5) { + throw new Error( + "[ERROR] 커스텀 구분자는 한 개 작성해야 합니다." + ); + } + if (customForm[0][2] === "," || customForm[0][2] === ":") { + throw new Error( + "[ERROR] 기본 구분자는 커스텀 지정자에 작성할 수 없습니다." + ); + } + + custom = `|${input[2]}`; + input = input.slice(5); + } + + // 예외처리 - 지정된 구분자 외에 다른 문자가 포함된 경우 + let pattern = new RegExp(`^[0-9,|:${custom}]+$`); + if (!pattern.test(input)) { + throw new Error( + "[ERROR] 지정된 구분자 외에 다른 문자가 포함되어 있습니다." + ); + } + + /* 숫자 분리 */ + let delimiter = new RegExp(`,|:${custom}`); + let number = input.split(delimiter); + + // 예외처리 - 숫자에 0을 입력한 경우 + if (number.includes("0")) { + throw new Error("[ERROR] 양수만 입력할 수 있습니다."); + } + + /* 계산 및 결과 반환 */ + let answer = number.reduce((sum, num) => (sum += +num), 0); + Console.print(`결과 : ${answer}`); + } } export default App;