diff --git a/README.md b/README.md index 13420b29..190ce38f 100644 --- a/README.md +++ b/README.md @@ -1 +1,28 @@ -# javascript-calculator-precourse \ No newline at end of file +# javascript-calculator-precourse + +SNAKE_CASE로 작성할것. + +1주차 미션 - 문자열 덧셈 계산기 + +기능 요구 사항 +1. 쉼표, 콜론을 구분자로가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환한다. +2. 앞에 기본 구분자 외에 커스텀 구분자를 지정할 수 있다. 커스텀 구분자는 문자열 앞부분의 //와 \n 사이 위치하는 문자를 커스템 구분자로 사용 +3. 사용자가 잘못된 값을 입력할 경우 "[Error]"로 시작하는 메시지와 함께 error 발생 -> 앱 종료 + +입출력 요구 사항 +입력 +- 구분자와 양수로 구성된 문자열 +출력 +- 덧셈 결과 +결과 : 6 + +- 실행 결과 예시 +덧셈할 문자열을 입력해 주세요. +1,2:3 +결과 : 6 + +프로그래밍 요구 사항 +네이밍 컨벤션 +- 소스의 변수명, 클래스명 등에는 이외의 언어 사용 x +- 클래스, 메서드 등의 이름에는 특수 문자 사용 x +- 상수명은 SNAKE_CASE로 작성할것 diff --git a/src/App.js b/src/App.js index 091aa0a5..1d78e933 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,26 @@ +import { calculator } from "./calculator.js"; +import { Console } from "@woowacourse/mission-utils"; + class App { - async run() {} + async run() { + try { + Console.print("덧셈할 문자열을 입력해 주세요."); + const input = await Console.readLineAsync(); + const result = calculator(input); + Console.print(`결과 : ${result}`); + + } catch (error) { + const msg = error instanceof Error ? error.message : String(error); + const out = msg.startsWith("[ERROR]") ? msg : "[ERROR]"; + Console.print(out); + throw new Error(out); + + } finally { + if (typeof Console.close === "function") { + Console.close(); + } + } + } } export default App; diff --git a/src/calculator.js b/src/calculator.js new file mode 100644 index 00000000..481893f0 --- /dev/null +++ b/src/calculator.js @@ -0,0 +1,37 @@ +export function calculator(input) { + if (input === "") return 0; + + const NORMALIZED_INPUT = String(input).replace(/\\n/g, "\n"); + + // 기본 구분자 + let numbersPart = NORMALIZED_INPUT; + let DELIMITER = /[,:]/; + + // 커스텀 구분자 파싱 + const MATCH_RESULT = NORMALIZED_INPUT.match(/^\/\/(.)\r?\n(.*)$/); + if (MATCH_RESULT) { + const CUSTOM_DELIMITER = MATCH_RESULT[1]; + numbersPart = MATCH_RESULT[2]; + + const ESCAPED_DELIMITER = CUSTOM_DELIMITER.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); + DELIMITER = new RegExp(`[,:${ESCAPED_DELIMITER}]`); + + } else if (NORMALIZED_INPUT.startsWith("//")) { + throw new Error("[ERROR] 잘못된 형식입니다."); + } + + const tokens = numbersPart.split(DELIMITER); + let sum = 0; + + for (const token of tokens) { + if (token === "") throw new Error("[ERROR] 잘못된 숫자입니다."); + const number = Number(token); + if (Number.isNaN(number) || number < 0) { + throw new Error("[ERROR] 잘못된 숫자입니다."); + } + sum += number; + } + + return sum; + } + \ No newline at end of file