From 44c1727ae608cdb5a50e9a53fea6ca5d6b9376d5 Mon Sep 17 00:00:00 2001 From: whitecity01 Date: Sat, 18 Oct 2025 14:32:07 +0900 Subject: [PATCH 1/6] =?UTF-8?q?docs:=20=EA=B5=AC=ED=98=84=ED=95=A0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 13420b29..9dfc089a 100644 --- a/README.md +++ b/README.md @@ -1 +1,13 @@ -# javascript-calculator-precourse \ No newline at end of file +# javascript-calculator-precourse + +# 기능 목록 + +1. **입력 및 출력** 기능 + +2. **커스텀 구분자 파싱** 기능 + +3. 구분자(+커스텀)로 문자열의 **숫자 분리** 기능 + +4. 3번의 유효성 검증 실패 시 **에러 핸들링** 기능 + +5. 3번의 유효성 검증 성공 시 구분자로 분리한 **각 숫자의 합**을 구하는 기능 From 44f3ea71deedc6bc2ae2dff2d8c58de767454011 Mon Sep 17 00:00:00 2001 From: whitecity01 Date: Sun, 19 Oct 2025 01:02:16 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20=EC=9E=85=EB=A0=A5=20=EB=B0=8F=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 11 ++++++++++- src/calculator.js | 30 ++++++++++++++++++++++++++++++ src/constants.js | 4 ++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/calculator.js create mode 100644 src/constants.js diff --git a/src/App.js b/src/App.js index 091aa0a5..6c1cdd17 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,14 @@ +import Calculator from './calculator.js'; + class App { - async run() {} + async run() { + const calculator = new Calculator(); + + await calculator.input(); // 입력 + const result = 0; // TODO: 실제 계산 결과로 대체 + + calculator.output(result); // 출력 + } } export default App; diff --git a/src/calculator.js b/src/calculator.js new file mode 100644 index 00000000..b64db3ac --- /dev/null +++ b/src/calculator.js @@ -0,0 +1,30 @@ +import { Console } from '@woowacourse/mission-utils'; +import { + ERROR_INVALID_FORMAT, + INPUT_MESSAGE, + OUTPUT_PREFIX, +} from './constants.js'; + +class Calculator { + constructor() { + this.inputText = ''; // 입력 문자열 + } + + // 문자열 입력 + async input() { + try { + const input = await Console.readLineAsync(INPUT_MESSAGE); + + this.inputText = input; + } catch { + throw new Error(ERROR_INVALID_FORMAT); + } + } + + // 결과 출력 + output(result) { + Console.print(`${OUTPUT_PREFIX}${result}`); + } +} + +export default Calculator; diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 00000000..e0282015 --- /dev/null +++ b/src/constants.js @@ -0,0 +1,4 @@ +export const INPUT_MESSAGE = '덧셈할 문자열을 입력해 주세요.\n'; +export const OUTPUT_PREFIX = '결과 : '; + +export const ERROR_INVALID_FORMAT = '[ERROR] 입력 형식이 올바르지 않습니다.'; From c5d814cf7fbc166a1d07cfec4ceb28dcde99a59e Mon Sep 17 00:00:00 2001 From: whitecity01 Date: Sun, 19 Oct 2025 01:14:25 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EA=B5=AC=EB=B6=84=EC=9E=90=20=ED=8C=8C=EC=8B=B1=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/calculator.js | 21 +++++++++++++++++++++ src/constants.js | 2 ++ 2 files changed, 23 insertions(+) diff --git a/src/calculator.js b/src/calculator.js index b64db3ac..f8ff7afe 100644 --- a/src/calculator.js +++ b/src/calculator.js @@ -1,5 +1,6 @@ import { Console } from '@woowacourse/mission-utils'; import { + DEFAULT_DELIMITERS, ERROR_INVALID_FORMAT, INPUT_MESSAGE, OUTPUT_PREFIX, @@ -7,9 +8,29 @@ import { class Calculator { constructor() { + this.delimiterList = [...DEFAULT_DELIMITERS]; // 구분자 this.inputText = ''; // 입력 문자열 } + // 문자열 길이 반환 + size() { + return this.inputText.length; + } + + // 커스텀 구분자 파싱 + parseCustomDelimiter() { + if (this.size() < 5) return; + + // 구분자가 없거나 틀린 형식일 시 return + if (this.inputText[0] !== '/') return; + if (this.inputText[1] !== '/') return; + if (this.inputText[3] !== '\\') return; + if (this.inputText[4] !== 'n') return; + + this.delimiterList.push(this.inputText[2]); // 커스텀 구분자 추가 + this.inputText = this.inputText.substring(5); // 커스텀 구분자 문자열 삭제 + } + // 문자열 입력 async input() { try { diff --git a/src/constants.js b/src/constants.js index e0282015..8471dd66 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,3 +1,5 @@ +export const DEFAULT_DELIMITERS = [',', ':']; // 기본 구분자 + export const INPUT_MESSAGE = '덧셈할 문자열을 입력해 주세요.\n'; export const OUTPUT_PREFIX = '결과 : '; From 3d7c80784612d01849bfc2bd623e6ac36478bc9d Mon Sep 17 00:00:00 2001 From: whitecity01 Date: Sun, 19 Oct 2025 01:44:27 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20=EA=B5=AC=EB=B6=84=EC=9E=90=20?= =?UTF-8?q?=EB=B0=8F=20=EC=BB=A4=EC=8A=A4=ED=85=80=20=EA=B5=AC=EB=B6=84?= =?UTF-8?q?=EC=9E=90=EB=A1=9C=20=EB=AC=B8=EC=9E=90=EC=97=B4=EC=9D=98=20?= =?UTF-8?q?=EC=88=AB=EC=9E=90=20=EB=B6=84=EB=A6=AC=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/calculator.js | 34 ++++++++++++++++++++++++++++++++++ src/utils.js | 3 +++ 2 files changed, 37 insertions(+) create mode 100644 src/utils.js diff --git a/src/calculator.js b/src/calculator.js index f8ff7afe..918a26f4 100644 --- a/src/calculator.js +++ b/src/calculator.js @@ -5,6 +5,7 @@ import { INPUT_MESSAGE, OUTPUT_PREFIX, } from './constants.js'; +import { isNumberChar } from './utils.js'; class Calculator { constructor() { @@ -31,6 +32,39 @@ class Calculator { this.inputText = this.inputText.substring(5); // 커스텀 구분자 문자열 삭제 } + // delimiterList(구분자)로 문자열의 숫자를 파싱해서 배열로 반환 + // TODO: 예외 발생 시 애플리케이션 종료 + parseNumber() { + const numbers = [0]; // 기본값 : 0 + let chunk = ''; + + for (let i = 0; i < this.size(); i++) { + const c = this.inputText[i]; + + // chunk에 숫자 추가 + if (isNumberChar(c)) { + chunk += c; + + if (i + 1 < this.size()) continue; + } + + // 문자열의 마지막이나 구분자를 만날 경우 + if (i + 1 === this.size() || this.delimiterList.includes(c)) { + const number = Number(chunk); // 형변환 + + // TODO: 잘못된 형식 에러 처리 예정 + + numbers.push(number); + chunk = ''; + continue; + } + + // TODO: 숫자, 구분자 모두 아닐 경우 에러 처리 필요 + } + + return numbers; // 성공 시 분리된 숫자 배열을 반환 + } + // 문자열 입력 async input() { try { diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 00000000..0e88e1de --- /dev/null +++ b/src/utils.js @@ -0,0 +1,3 @@ +export const isNumberChar = (c) => { + return '0' <= c && c <= '9'; +}; From 01b25b7ce793556de1c110c02b43aed59cc3380b Mon Sep 17 00:00:00 2001 From: whitecity01 Date: Sun, 19 Oct 2025 01:47:47 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20=EA=B5=AC=EB=B6=84=EC=9E=90=20?= =?UTF-8?q?=ED=8C=8C=EC=8B=B1=20=EC=A4=91=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EC=8B=A4=ED=8C=A8=20=EC=8B=9C=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=ED=95=B8=EB=93=A4=EB=A7=81=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/calculator.js | 12 +++++++++--- src/constants.js | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/calculator.js b/src/calculator.js index 918a26f4..c5f680bc 100644 --- a/src/calculator.js +++ b/src/calculator.js @@ -2,6 +2,7 @@ import { Console } from '@woowacourse/mission-utils'; import { DEFAULT_DELIMITERS, ERROR_INVALID_FORMAT, + ERROR_NON_POSITIVE, INPUT_MESSAGE, OUTPUT_PREFIX, } from './constants.js'; @@ -33,7 +34,7 @@ class Calculator { } // delimiterList(구분자)로 문자열의 숫자를 파싱해서 배열로 반환 - // TODO: 예외 발생 시 애플리케이션 종료 + // 예외 발생 시 애플리케이션이 종료된다. parseNumber() { const numbers = [0]; // 기본값 : 0 let chunk = ''; @@ -52,14 +53,19 @@ class Calculator { if (i + 1 === this.size() || this.delimiterList.includes(c)) { const number = Number(chunk); // 형변환 - // TODO: 잘못된 형식 에러 처리 예정 + // 숫자가 아닐 경우 + if (Number.isNaN(number)) throw new Error(ERROR_INVALID_FORMAT); + + // 양수가 아닐 경우 + if (number <= 0) throw new Error(ERROR_NON_POSITIVE); numbers.push(number); chunk = ''; continue; } - // TODO: 숫자, 구분자 모두 아닐 경우 에러 처리 필요 + // 숫자, 구분자 모두 아닐 경우 + throw new Error(ERROR_INVALID_FORMAT); } return numbers; // 성공 시 분리된 숫자 배열을 반환 diff --git a/src/constants.js b/src/constants.js index 8471dd66..55dea8ad 100644 --- a/src/constants.js +++ b/src/constants.js @@ -4,3 +4,4 @@ export const INPUT_MESSAGE = '덧셈할 문자열을 입력해 주세요.\n'; export const OUTPUT_PREFIX = '결과 : '; export const ERROR_INVALID_FORMAT = '[ERROR] 입력 형식이 올바르지 않습니다.'; +export const ERROR_NON_POSITIVE = '[ERROR] 양수를 입력해주세요.'; From f8d550d8ded5989172e9c6455a52085973fa4a27 Mon Sep 17 00:00:00 2001 From: whitecity01 Date: Sun, 19 Oct 2025 01:53:06 +0900 Subject: [PATCH 6/6] =?UTF-8?q?feat:=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EC=84=B1=EA=B3=B5=20=EC=8B=9C=20=EA=B0=81?= =?UTF-8?q?=20=EC=88=AB=EC=9E=90=EC=9D=98=20=ED=95=A9=EC=9D=84=20=EA=B5=AC?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 2 +- src/calculator.js | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index 6c1cdd17..416e2a2b 100644 --- a/src/App.js +++ b/src/App.js @@ -5,7 +5,7 @@ class App { const calculator = new Calculator(); await calculator.input(); // 입력 - const result = 0; // TODO: 실제 계산 결과로 대체 + const result = calculator.calculate(); calculator.output(result); // 출력 } diff --git a/src/calculator.js b/src/calculator.js index c5f680bc..78cba66e 100644 --- a/src/calculator.js +++ b/src/calculator.js @@ -14,6 +14,19 @@ class Calculator { this.inputText = ''; // 입력 문자열 } + // 문자열 연산 + calculate() { + this.parseCustomDelimiter(); + + const numbers = this.parseNumber(); + return this.sum(numbers); + } + + // 배열의 숫자들을 더한 후 반환 + sum(numbers) { + return numbers.reduce((acc, cur) => acc + cur, 0); + } + // 문자열 길이 반환 size() { return this.inputText.length;