From 6b112c31979215a7cb2619ea1c4f0f7917419d1e Mon Sep 17 00:00:00 2001 From: Minji Kim Date: Mon, 4 Nov 2024 14:26:07 +0900 Subject: [PATCH 01/15] docs: update README --- README.md | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/README.md b/README.md index 15bb106b5..3009f3bbb 100644 --- a/README.md +++ b/README.md @@ -1 +1,121 @@ # javascript-lotto-precourse + +## ๐Ÿ“‘ ๊ฐ„๋‹จํ•œ ๋กœ๋˜ ๋ฐœ๋งค๊ธฐ ๊ตฌํ˜„ํ•˜๊ธฐ + +### ๊ตฌํ˜„ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก + +- ๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ์ˆซ์ž ๋ฒ”์œ„๋Š” 1~45๊นŒ์ง€์ด๋‹ค. +- 1๊ฐœ์˜ ๋กœ๋˜๋ฅผ ๋ฐœํ–‰ํ•  ๋•Œ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” 6๊ฐœ์˜ ์ˆซ์ž๋ฅผ ๋ฝ‘๋Š”๋‹ค. +- ๋‹น์ฒจ ๋ฒˆํ˜ธ ์ถ”์ฒจ ์‹œ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์ˆซ์ž 6๊ฐœ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ 1๊ฐœ๋ฅผ ๋ฝ‘๋Š”๋‹ค. +- ๋‹น์ฒจ์€ 1๋“ฑ๋ถ€ํ„ฐ 5๋“ฑ๊นŒ์ง€ ์žˆ๋‹ค. ๋‹น์ฒจ ๊ธฐ์ค€๊ณผ ๊ธˆ์•ก์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค. + - 1๋“ฑ: 6๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 2,000,000,000์› + - 2๋“ฑ: 5๊ฐœ ๋ฒˆํ˜ธ + ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์ผ์น˜ / 30,000,000์› + - 3๋“ฑ: 5๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 1,500,000์› + - 4๋“ฑ: 4๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 50,000์› + - 5๋“ฑ: 3๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 5,000์› +- ๋กœ๋˜ ๊ตฌ์ž… ๊ธˆ์•ก์„ ์ž…๋ ฅํ•˜๋ฉด ๊ตฌ์ž… ๊ธˆ์•ก์— ํ•ด๋‹นํ•˜๋Š” ๋งŒํผ ๋กœ๋˜๋ฅผ ๋ฐœํ–‰ํ•ด์•ผ ํ•œ๋‹ค. +- ๋กœ๋˜ 1์žฅ์˜ ๊ฐ€๊ฒฉ์€ 1,000์›์ด๋‹ค. +- ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค. +- ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ๋งคํ•œ ๋กœ๋˜ ๋ฒˆํ˜ธ์™€ ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ๋น„๊ตํ•˜์—ฌ ๋‹น์ฒจ ๋‚ด์—ญ ๋ฐ ์ˆ˜์ต๋ฅ ์„ ์ถœ๋ ฅํ•˜๊ณ  ๋กœ๋˜ ๊ฒŒ์ž„์„ ์ข…๋ฃŒํ•œ๋‹ค. +- ์‚ฌ์šฉ์ž๊ฐ€ ์ž˜๋ชป๋œ ๊ฐ’์„ ์ž…๋ ฅํ•  ๊ฒฝ์šฐ "[ERROR]"๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ป˜ Error๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ  ํ•ด๋‹น ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•œ ๋‹ค์Œ ํ•ด๋‹น ์ง€์ ๋ถ€ํ„ฐ ๋‹ค์‹œ ์ž…๋ ฅ์„ ๋ฐ›๋Š”๋‹ค. + +## โœ๏ธ ์š”๊ตฌ ์‚ฌํ•ญ + +### 1) ์ž…๋ ฅ + +- ๋กœ๋˜ ๊ตฌ์ž… ๊ธˆ์•ก์„ ์ž…๋ ฅ ๋ฐ›๋Š”๋‹ค. ๊ตฌ์ž… ๊ธˆ์•ก์€ 1,000์› ๋‹จ์œ„๋กœ ์ž…๋ ฅ ๋ฐ›์œผ๋ฉฐ 1,000์›์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•œ๋‹ค. + + ``` + 14000 + + ``` + +- ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ ๋ฐ›๋Š”๋‹ค. + + ``` + 7 + + ``` + +### 2) ์ถœ๋ ฅ + +- ๋ฐœํ–‰ํ•œ ๋กœ๋˜ ์ˆ˜๋Ÿ‰ ๋ฐ ๋ฒˆํ˜ธ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ๋ณด์—ฌ์ค€๋‹ค. + + ``` + 8๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค. + [8, 21, 23, 41, 42, 43] + [3, 5, 11, 16, 32, 38] + [7, 11, 16, 35, 36, 44] + [1, 8, 11, 31, 41, 42] + [13, 14, 16, 38, 42, 45] + [7, 11, 30, 40, 42, 43] + [2, 13, 22, 32, 38, 45] + [1, 3, 5, 14, 22, 45] + + ``` + +- ๋‹น์ฒจ ๋‚ด์—ญ์„ ์ถœ๋ ฅํ•œ๋‹ค. + + ``` + 3๊ฐœ ์ผ์น˜ (5,000์›) - 1๊ฐœ + 4๊ฐœ ์ผ์น˜ (50,000์›) - 0๊ฐœ + 5๊ฐœ ์ผ์น˜ (1,500,000์›) - 0๊ฐœ + 5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - 0๊ฐœ + 6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - 0๊ฐœ + + ``` + +- ์ˆ˜์ต๋ฅ ์€ ์†Œ์ˆ˜์  ๋‘˜์งธ ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผํ•œ๋‹ค. (ex. 100.0%, 51.5%, 1,000,000.0%) + + ``` + ์ด ์ˆ˜์ต๋ฅ ์€ 62.5%์ž…๋‹ˆ๋‹ค. + + ``` + +### 3) ์—๋Ÿฌ ์ฒ˜๋ฆฌ + +- ์‚ฌ์šฉ์ž๊ฐ€ ์ž˜๋ชป๋œ ๊ฐ’์„ ์ž…๋ ฅํ•  ๊ฒฝ์šฐ "[ERROR]"๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ + +``` +[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. + +``` + +## โญ•์‹คํ–‰ ๊ฒฐ๊ณผ ์˜ˆ์‹œ + +``` +๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”. +8000 + +8๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค. +[8, 21, 23, 41, 42, 43] +[3, 5, 11, 16, 32, 38] +[7, 11, 16, 35, 36, 44] +[1, 8, 11, 31, 41, 42] +[13, 14, 16, 38, 42, 45] +[7, 11, 30, 40, 42, 43] +[2, 13, 22, 32, 38, 45] +[1, 3, 5, 14, 22, 45] + +๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”. +1,2,3,4,5,6 + +๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”. +7 + +๋‹น์ฒจ ํ†ต๊ณ„ +--- +3๊ฐœ ์ผ์น˜ (5,000์›) - 1๊ฐœ +4๊ฐœ ์ผ์น˜ (50,000์›) - 0๊ฐœ +5๊ฐœ ์ผ์น˜ (1,500,000์›) - 0๊ฐœ +5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - 0๊ฐœ +6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - 0๊ฐœ +์ด ์ˆ˜์ต๋ฅ ์€ 62.5%์ž…๋‹ˆ๋‹ค. + +``` + +## ๐Ÿ”ŽETC + +- @woowacourse/mission-utils์—์„œ ์ œ๊ณตํ•˜๋Š” Random ๋ฐ Console API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. + - Random ๊ฐ’ ์ถ”์ถœ์€ Random. pickUniqueNumbersInRange()๋ฅผ ํ™œ์šฉํ•œ๋‹ค. + - ์‚ฌ์šฉ์ž์˜ ๊ฐ’์„ ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅํ•˜๋ ค๋ฉด Console.readLineAsync()์™€ Console.print()๋ฅผ ํ™œ์šฉํ•œ๋‹ค. From a055232ef7e58289903690b8b2e2105e292eb8e5 Mon Sep 17 00:00:00 2001 From: Minji Kim Date: Mon, 4 Nov 2024 15:24:01 +0900 Subject: [PATCH 02/15] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EA=B5=AC?= =?UTF-8?q?=EB=A7=A4=20=EA=B8=88=EC=95=A1=20=EC=9E=85=EB=A0=A5=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index 091aa0a5d..548de0491 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,14 @@ +import { Console } from "@woowacourse/mission-utils"; + class App { - async run() {} + run() { + this.inputPurchaseAmount(); + } + + async inputPurchaseAmount() { + const amount = await Console.readLineAsync("๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n"); + Console.print(amount); + } } export default App; From 17b8317fdf0cafbd595c0383cb7533b39ecdecf0 Mon Sep 17 00:00:00 2001 From: Minji Kim Date: Mon, 4 Nov 2024 15:34:18 +0900 Subject: [PATCH 03/15] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EA=B5=AC?= =?UTF-8?q?=EB=A7=A4=20=EA=B8=88=EC=95=A1=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20?= =?UTF-8?q?=EA=B2=80=EC=82=AC=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index 548de0491..86764447d 100644 --- a/src/App.js +++ b/src/App.js @@ -7,7 +7,22 @@ class App { async inputPurchaseAmount() { const amount = await Console.readLineAsync("๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n"); - Console.print(amount); + this.validatePurchaseAmount(amount); + } + + validatePurchaseAmount(amount) { + const purchaseAmount = Number(amount); + + if (Number.isNaN(purchaseAmount) || purchaseAmount % 1000 !== 0) { + this.handleError("[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์€ 1,000์› ๋‹จ์œ„๋กœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } else { + this.purchaseAmount = purchaseAmount; + } + } + + handleError(message) { + Console.print(message); + this.inputPurchaseAmount(); // ์ž˜๋ชป๋œ ์ž…๋ ฅ์ผ ๊ฒฝ์šฐ ์žฌ์ž…๋ ฅ ์š”์ฒญ } } From 78cf5bc53c1dcc08f5e580f141ace88811e4fea3 Mon Sep 17 00:00:00 2001 From: Minji Kim Date: Mon, 4 Nov 2024 15:38:10 +0900 Subject: [PATCH 04/15] =?UTF-8?q?feat:=20=EA=B5=AC=EB=A7=A4=ED=95=9C=20?= =?UTF-8?q?=EB=A1=9C=EB=98=90=20=EC=88=98=EB=9F=89=20=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index 86764447d..350a40fca 100644 --- a/src/App.js +++ b/src/App.js @@ -13,13 +13,19 @@ class App { validatePurchaseAmount(amount) { const purchaseAmount = Number(amount); - if (Number.isNaN(purchaseAmount) || purchaseAmount % 1000 !== 0) { + if (isNaN(purchaseAmount) || purchaseAmount % 1000 !== 0) { this.handleError("[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์€ 1,000์› ๋‹จ์œ„๋กœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."); } else { this.purchaseAmount = purchaseAmount; + this.printPurchasedLotto(); } } + printPurchasedLotto() { + const lottoCount = this.purchaseAmount / 1000; + Console.print(`${lottoCount}๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.`); + } + handleError(message) { Console.print(message); this.inputPurchaseAmount(); // ์ž˜๋ชป๋œ ์ž…๋ ฅ์ผ ๊ฒฝ์šฐ ์žฌ์ž…๋ ฅ ์š”์ฒญ From 776f069817c9cfcb6eabd46f1ed6fd425b2088c2 Mon Sep 17 00:00:00 2001 From: Minji Kim Date: Mon, 4 Nov 2024 19:58:11 +0900 Subject: [PATCH 05/15] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=ED=8B=B0?= =?UTF-8?q?=EC=BC=93=20=EB=B0=9C=ED=96=89=20=EB=B0=8F=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=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 | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index 350a40fca..64aa2df6c 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,4 @@ -import { Console } from "@woowacourse/mission-utils"; +import { Console, Random } from "@woowacourse/mission-utils"; class App { run() { @@ -24,6 +24,19 @@ class App { printPurchasedLotto() { const lottoCount = this.purchaseAmount / 1000; Console.print(`${lottoCount}๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.`); + this.lottoTickets = Array.from({ length: lottoCount }); + this.generateLottoTickets(); + } + + generateLottoTickets() { + this.lottoTickets = this.lottoTickets.map(() => + Random.pickUniqueNumbersInRange(1, 45, 6).sort((a, b) => a - b), + ); + this.displayLottoTickets(); + } + + displayLottoTickets() { + this.lottoTickets.forEach((ticket) => Console.print(`[${ticket.join(", ")}]`)); } handleError(message) { From 1fa9df9539b6e59340787945f866de7558013f54 Mon Sep 17 00:00:00 2001 From: Minji Kim Date: Mon, 4 Nov 2024 22:08:14 +0900 Subject: [PATCH 06/15] =?UTF-8?q?style:=20=EA=B0=9C=ED=96=89=20=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index 64aa2df6c..a071ab565 100644 --- a/src/App.js +++ b/src/App.js @@ -23,7 +23,7 @@ class App { printPurchasedLotto() { const lottoCount = this.purchaseAmount / 1000; - Console.print(`${lottoCount}๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.`); + Console.print(`\n${lottoCount}๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.`); this.lottoTickets = Array.from({ length: lottoCount }); this.generateLottoTickets(); } From eeff69e398e6c9c2712dee455f54d0981dacd4f2 Mon Sep 17 00:00:00 2001 From: Minji Kim Date: Mon, 4 Nov 2024 22:09:01 +0900 Subject: [PATCH 07/15] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=9E=85=EB=A0=A5=20=EB=B0=8F=20=EC=9C=A0=ED=9A=A8?= =?UTF-8?q?=EC=84=B1=20=EA=B2=80=EC=82=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/App.js b/src/App.js index a071ab565..e49413f07 100644 --- a/src/App.js +++ b/src/App.js @@ -26,6 +26,7 @@ class App { Console.print(`\n${lottoCount}๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.`); this.lottoTickets = Array.from({ length: lottoCount }); this.generateLottoTickets(); + this.inputWinningNumbers(); } generateLottoTickets() { @@ -39,6 +40,26 @@ class App { this.lottoTickets.forEach((ticket) => Console.print(`[${ticket.join(", ")}]`)); } + async inputWinningNumbers() { + const winningNumbersInput = await Console.readLineAsync( + "\n๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”. (์˜ˆ: 1,2,3,4,5,6)\n", + ); + const winningNumbers = winningNumbersInput.split(",").map(Number); + this.validateWinningNumbers(winningNumbers); + } + + validateWinningNumbers(numbers) { + if (numbers.length !== 6 || new Set(numbers).size !== 6) { + this.handleError("[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ๋Š” ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” 6๊ฐœ์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + return; + } + if (numbers.some((number) => number < 1 || number > 45)) { + this.handleError("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + return; + } + this.winningNumbers = numbers; + } + handleError(message) { Console.print(message); this.inputPurchaseAmount(); // ์ž˜๋ชป๋œ ์ž…๋ ฅ์ผ ๊ฒฝ์šฐ ์žฌ์ž…๋ ฅ ์š”์ฒญ From 14bf080bd83bd2367f1bfaecbb50fa1a235c2747 Mon Sep 17 00:00:00 2001 From: Minji Kim Date: Mon, 4 Nov 2024 22:15:50 +0900 Subject: [PATCH 08/15] =?UTF-8?q?feat:=20=EB=B3=B4=EB=84=88=EC=8A=A4=20?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=EC=9E=85=EB=A0=A5=20=EB=B0=8F=20=EC=9C=A0?= =?UTF-8?q?=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=82=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index e49413f07..3c01b1b89 100644 --- a/src/App.js +++ b/src/App.js @@ -46,6 +46,7 @@ class App { ); const winningNumbers = winningNumbersInput.split(",").map(Number); this.validateWinningNumbers(winningNumbers); + this.inputBonusNumber(); } validateWinningNumbers(numbers) { @@ -60,9 +61,27 @@ class App { this.winningNumbers = numbers; } + async inputBonusNumber() { + const bonusNumberInput = await Console.readLineAsync("\n๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n"); + const bonusNumber = Number(bonusNumberInput); + this.validateBonusNumber(bonusNumber); + } + + validateBonusNumber(number) { + if (Number.isNaN(number) || number < 1 || number > 45) { + this.handleError("[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + return; + } + if (this.winningNumbers.includes(number)) { + this.handleError("[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + return; + } + this.bonusNumber = number; + } + handleError(message) { Console.print(message); - this.inputPurchaseAmount(); // ์ž˜๋ชป๋œ ์ž…๋ ฅ์ผ ๊ฒฝ์šฐ ์žฌ์ž…๋ ฅ ์š”์ฒญ + retryFunction(); // ์ž˜๋ชป๋œ ์ž…๋ ฅ์ผ ๊ฒฝ์šฐ ํ•ด๋‹น ์ง€์ ๋ถ€ํ„ฐ ๋‹ค์‹œ ์ž…๋ ฅ ์š”์ฒญ } } From 2c87fcbad45757459e5da7b9af73ad56bcf332aa Mon Sep 17 00:00:00 2001 From: Minji Kim Date: Mon, 4 Nov 2024 22:19:53 +0900 Subject: [PATCH 09/15] =?UTF-8?q?refactor:=20else=EB=AC=B8=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/App.js b/src/App.js index 3c01b1b89..57bd1fac6 100644 --- a/src/App.js +++ b/src/App.js @@ -15,10 +15,10 @@ class App { if (isNaN(purchaseAmount) || purchaseAmount % 1000 !== 0) { this.handleError("[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์€ 1,000์› ๋‹จ์œ„๋กœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."); - } else { - this.purchaseAmount = purchaseAmount; - this.printPurchasedLotto(); + return; } + this.purchaseAmount = purchaseAmount; + this.printPurchasedLotto(); } printPurchasedLotto() { @@ -79,7 +79,7 @@ class App { this.bonusNumber = number; } - handleError(message) { + handleError(message, retryFunction) { Console.print(message); retryFunction(); // ์ž˜๋ชป๋œ ์ž…๋ ฅ์ผ ๊ฒฝ์šฐ ํ•ด๋‹น ์ง€์ ๋ถ€ํ„ฐ ๋‹ค์‹œ ์ž…๋ ฅ ์š”์ฒญ } From 54d097ea39db305be37d03dbbf85f403be6b6608 Mon Sep 17 00:00:00 2001 From: Minji Kim Date: Mon, 4 Nov 2024 22:34:20 +0900 Subject: [PATCH 10/15] =?UTF-8?q?fix:=20=EC=9E=85=EB=A0=A5=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EB=B0=9C=EC=83=9D=20=EC=8B=9C=20=ED=95=B4=EB=8B=B9?= =?UTF-8?q?=20=EB=8B=A8=EA=B3=84=EB=B6=80=ED=84=B0=20=EB=8B=A4=EC=8B=9C=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/App.js b/src/App.js index 57bd1fac6..a54d753d9 100644 --- a/src/App.js +++ b/src/App.js @@ -13,8 +13,9 @@ class App { validatePurchaseAmount(amount) { const purchaseAmount = Number(amount); - if (isNaN(purchaseAmount) || purchaseAmount % 1000 !== 0) { + if (Number.isNaN(purchaseAmount) || purchaseAmount % 1000 !== 0) { this.handleError("[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์€ 1,000์› ๋‹จ์œ„๋กœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + this.inputPurchaseAmount(); return; } this.purchaseAmount = purchaseAmount; @@ -46,19 +47,21 @@ class App { ); const winningNumbers = winningNumbersInput.split(",").map(Number); this.validateWinningNumbers(winningNumbers); - this.inputBonusNumber(); } validateWinningNumbers(numbers) { if (numbers.length !== 6 || new Set(numbers).size !== 6) { this.handleError("[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ๋Š” ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” 6๊ฐœ์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + this.inputWinningNumbers(); return; } if (numbers.some((number) => number < 1 || number > 45)) { this.handleError("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + this.inputWinningNumbers(); return; } this.winningNumbers = numbers; + this.inputBonusNumber(); } async inputBonusNumber() { @@ -70,18 +73,20 @@ class App { validateBonusNumber(number) { if (Number.isNaN(number) || number < 1 || number > 45) { this.handleError("[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + this.inputBonusNumber(); return; } if (this.winningNumbers.includes(number)) { this.handleError("[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + this.inputBonusNumber(); return; } this.bonusNumber = number; + Console.print("๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ ์„ค์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค."); } - handleError(message, retryFunction) { + handleError(message) { Console.print(message); - retryFunction(); // ์ž˜๋ชป๋œ ์ž…๋ ฅ์ผ ๊ฒฝ์šฐ ํ•ด๋‹น ์ง€์ ๋ถ€ํ„ฐ ๋‹ค์‹œ ์ž…๋ ฅ ์š”์ฒญ } } From 5d90158fb2547e97c829b673e8787324dea22a1d Mon Sep 17 00:00:00 2001 From: Minji Kim Date: Mon, 4 Nov 2024 22:52:36 +0900 Subject: [PATCH 11/15] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=20=EA=B3=84=EC=82=B0=20=EB=B0=8F=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index a54d753d9..f08bb3c8b 100644 --- a/src/App.js +++ b/src/App.js @@ -82,7 +82,46 @@ class App { return; } this.bonusNumber = number; - Console.print("๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ ์„ค์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค."); + this.calculateResults(); + } + + calculateResults() { + this.results = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 }; + + this.lottoTickets.forEach((ticket) => { + const matchedCount = ticket.filter((num) => this.winningNumbers.includes(num)).length; + const isBonusMatched = ticket.includes(this.bonusNumber); + + if (matchedCount === 6) this.results[1] += 1; // 1๋“ฑ + else if (matchedCount === 5 && isBonusMatched) this.results[2] += 1; // 2๋“ฑ + else if (matchedCount === 5) this.results[3] += 1; // 3๋“ฑ + else if (matchedCount === 4) this.results[4] += 1; // 4๋“ฑ + else if (matchedCount === 3) this.results[5] += 1; // 5๋“ฑ + }); + + this.printResults(); + } + + printResults() { + Console.print("\n๋‹น์ฒจ ํ†ต๊ณ„\n---"); + Console.print(`3๊ฐœ ์ผ์น˜ (5,000์›) - ${this.results[5]}๊ฐœ`); + Console.print(`4๊ฐœ ์ผ์น˜ (50,000์›) - ${this.results[4]}๊ฐœ`); + Console.print(`5๊ฐœ ์ผ์น˜ (1,500,000์›) - ${this.results[3]}๊ฐœ`); + Console.print(`5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ${this.results[2]}๊ฐœ`); + Console.print(`6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ${this.results[1]}๊ฐœ`); + + this.calculateProfit(); + } + + calculateProfit() { + const prizeAmounts = { 1: 2000000000, 2: 30000000, 3: 1500000, 4: 50000, 5: 5000 }; + const totalPrize = Object.keys(this.results).reduce( + (sum, key) => sum + this.results[key] * prizeAmounts[key], + 0, + ); + + const profitRate = ((totalPrize / this.purchaseAmount) * 100).toFixed(1); + Console.print(`์ด ์ˆ˜์ต๋ฅ ์€ ${profitRate}%์ž…๋‹ˆ๋‹ค.`); } handleError(message) { From 763e2426ed869f5630d8fe1aa5a76a4843783c10 Mon Sep 17 00:00:00 2001 From: Minji Kim Date: Mon, 4 Nov 2024 23:09:42 +0900 Subject: [PATCH 12/15] =?UTF-8?q?refactor:=20Lotto=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 19 +++++++++++-------- src/Lotto.js | 4 +++- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/App.js b/src/App.js index f08bb3c8b..0e0faba8d 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,5 @@ import { Console, Random } from "@woowacourse/mission-utils"; +import Lotto from "./Lotto.js"; class App { run() { @@ -25,20 +26,22 @@ class App { printPurchasedLotto() { const lottoCount = this.purchaseAmount / 1000; Console.print(`\n${lottoCount}๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.`); - this.lottoTickets = Array.from({ length: lottoCount }); - this.generateLottoTickets(); + this.lottoTickets = this.generateLottoTickets(lottoCount); + this.displayLottoTickets(); this.inputWinningNumbers(); } - generateLottoTickets() { - this.lottoTickets = this.lottoTickets.map(() => - Random.pickUniqueNumbersInRange(1, 45, 6).sort((a, b) => a - b), - ); - this.displayLottoTickets(); + generateLottoTickets(count) { + return Array.from({ length: count }, () => { + const numbers = Random.pickUniqueNumbersInRange(1, 45, 6).sort((a, b) => a - b); + return new Lotto(numbers); + }); } displayLottoTickets() { - this.lottoTickets.forEach((ticket) => Console.print(`[${ticket.join(", ")}]`)); + this.lottoTickets.forEach((ticket) => { + Console.print(`[${ticket.getNumbers().join(", ")}]`); + }); } async inputWinningNumbers() { diff --git a/src/Lotto.js b/src/Lotto.js index cb0b1527e..87d6db3f2 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -12,7 +12,9 @@ class Lotto { } } - // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ + getNumbers() { + return this.#numbers; + } } export default Lotto; From 679716f42595f55f0f2049a15fa54d08a37c283a Mon Sep 17 00:00:00 2001 From: Minji Kim Date: Mon, 4 Nov 2024 23:13:25 +0900 Subject: [PATCH 13/15] =?UTF-8?q?fix:=20Lotto=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=9D=B8=EC=8A=A4=ED=84=B4=EC=8A=A4=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=B2=88=ED=98=B8=20=EB=B0=B0=EC=97=B4=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC=20=EB=B0=A9=EC=8B=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/App.js b/src/App.js index 0e0faba8d..38dc5fb45 100644 --- a/src/App.js +++ b/src/App.js @@ -92,14 +92,34 @@ class App { this.results = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 }; this.lottoTickets.forEach((ticket) => { - const matchedCount = ticket.filter((num) => this.winningNumbers.includes(num)).length; - const isBonusMatched = ticket.includes(this.bonusNumber); - - if (matchedCount === 6) this.results[1] += 1; // 1๋“ฑ - else if (matchedCount === 5 && isBonusMatched) this.results[2] += 1; // 2๋“ฑ - else if (matchedCount === 5) this.results[3] += 1; // 3๋“ฑ - else if (matchedCount === 4) this.results[4] += 1; // 4๋“ฑ - else if (matchedCount === 3) this.results[5] += 1; // 5๋“ฑ + const matchedCount = ticket + .getNumbers() + .filter((num) => this.winningNumbers.includes(num)).length; + const isBonusMatched = ticket.getNumbers().includes(this.bonusNumber); + + if (matchedCount === 6) { + this.results[1] += 1; // 1๋“ฑ + return; + } + + if (matchedCount === 5 && isBonusMatched) { + this.results[2] += 1; // 2๋“ฑ + return; + } + + if (matchedCount === 5) { + this.results[3] += 1; // 3๋“ฑ + return; + } + + if (matchedCount === 4) { + this.results[4] += 1; // 4๋“ฑ + return; + } + + if (matchedCount === 3) { + this.results[5] += 1; // 5๋“ฑ + } }); this.printResults(); From 87c15223e275c96d9400e93440282407b6b2b2db Mon Sep 17 00:00:00 2001 From: Minji Kim Date: Mon, 4 Nov 2024 23:36:56 +0900 Subject: [PATCH 14/15] =?UTF-8?q?refactor:=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 64 +++++++++++++++++++++++++++++------------------- src/constants.js | 26 ++++++++++++++++++++ 2 files changed, 65 insertions(+), 25 deletions(-) create mode 100644 src/constants.js diff --git a/src/App.js b/src/App.js index 38dc5fb45..7042ecf6e 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,13 @@ import { Console, Random } from "@woowacourse/mission-utils"; import Lotto from "./Lotto.js"; +import { + LOTTO_PRICE, + LOTTO_NUMBER_COUNT, + LOTTO_NUMBER_RANGE, + WINNING_PRIZES, + MATCH_COUNTS, + ERROR_MESSAGES, +} from "./constants.js"; class App { run() { @@ -14,8 +22,8 @@ class App { validatePurchaseAmount(amount) { const purchaseAmount = Number(amount); - if (Number.isNaN(purchaseAmount) || purchaseAmount % 1000 !== 0) { - this.handleError("[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์€ 1,000์› ๋‹จ์œ„๋กœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + if (Number.isNaN(purchaseAmount) || purchaseAmount % LOTTO_PRICE !== 0) { + this.handleError(ERROR_MESSAGES.INVALID_AMOUNT); this.inputPurchaseAmount(); return; } @@ -24,7 +32,7 @@ class App { } printPurchasedLotto() { - const lottoCount = this.purchaseAmount / 1000; + const lottoCount = this.purchaseAmount / LOTTO_PRICE; Console.print(`\n${lottoCount}๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.`); this.lottoTickets = this.generateLottoTickets(lottoCount); this.displayLottoTickets(); @@ -53,13 +61,15 @@ class App { } validateWinningNumbers(numbers) { - if (numbers.length !== 6 || new Set(numbers).size !== 6) { - this.handleError("[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ๋Š” ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” 6๊ฐœ์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + if (numbers.length !== LOTTO_NUMBER_COUNT || new Set(numbers).size !== LOTTO_NUMBER_COUNT) { + this.handleError(ERROR_MESSAGES.INVALID_LOTTO_COUNT); this.inputWinningNumbers(); return; } - if (numbers.some((number) => number < 1 || number > 45)) { - this.handleError("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + if ( + numbers.some((number) => number < LOTTO_NUMBER_RANGE.MIN || number > LOTTO_NUMBER_RANGE.MAX) + ) { + this.handleError(ERROR_MESSAGES.INVALID_NUMBER_RANGE); this.inputWinningNumbers(); return; } @@ -74,13 +84,17 @@ class App { } validateBonusNumber(number) { - if (Number.isNaN(number) || number < 1 || number > 45) { - this.handleError("[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + if ( + Number.isNaN(number) || + number < LOTTO_NUMBER_RANGE.MIN || + number > LOTTO_NUMBER_RANGE.MAX + ) { + this.handleError(ERROR_MESSAGES.INVALID_NUMBER_RANGE); this.inputBonusNumber(); return; } if (this.winningNumbers.includes(number)) { - this.handleError("[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + this.handleError(ERROR_MESSAGES.BONUS_NUMBER_DUPLICATE); this.inputBonusNumber(); return; } @@ -97,28 +111,28 @@ class App { .filter((num) => this.winningNumbers.includes(num)).length; const isBonusMatched = ticket.getNumbers().includes(this.bonusNumber); - if (matchedCount === 6) { - this.results[1] += 1; // 1๋“ฑ + if (matchedCount === MATCH_COUNTS.FIRST) { + this.results[1] += 1; return; } - if (matchedCount === 5 && isBonusMatched) { - this.results[2] += 1; // 2๋“ฑ + if (matchedCount === MATCH_COUNTS.SECOND && isBonusMatched) { + this.results[2] += 1; return; } - if (matchedCount === 5) { - this.results[3] += 1; // 3๋“ฑ + if (matchedCount === MATCH_COUNTS.THIRD) { + this.results[3] += 1; return; } - if (matchedCount === 4) { - this.results[4] += 1; // 4๋“ฑ + if (matchedCount === MATCH_COUNTS.FOURTH) { + this.results[4] += 1; return; } - if (matchedCount === 3) { - this.results[5] += 1; // 5๋“ฑ + if (matchedCount === MATCH_COUNTS.FIFTH) { + this.results[5] += 1; } }); @@ -127,11 +141,11 @@ class App { printResults() { Console.print("\n๋‹น์ฒจ ํ†ต๊ณ„\n---"); - Console.print(`3๊ฐœ ์ผ์น˜ (5,000์›) - ${this.results[5]}๊ฐœ`); - Console.print(`4๊ฐœ ์ผ์น˜ (50,000์›) - ${this.results[4]}๊ฐœ`); - Console.print(`5๊ฐœ ์ผ์น˜ (1,500,000์›) - ${this.results[3]}๊ฐœ`); - Console.print(`5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ${this.results[2]}๊ฐœ`); - Console.print(`6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ${this.results[1]}๊ฐœ`); + Console.print(`3๊ฐœ ์ผ์น˜ (${WINNING_PRIZES.FIFTH}์›) - ${this.results[5]}๊ฐœ`); + Console.print(`4๊ฐœ ์ผ์น˜ (${WINNING_PRIZES.FOURTH}์›) - ${this.results[4]}๊ฐœ`); + Console.print(`5๊ฐœ ์ผ์น˜ (${WINNING_PRIZES.THIRD}์›) - ${this.results[3]}๊ฐœ`); + Console.print(`5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (${WINNING_PRIZES.SECOND}์›) - ${this.results[2]}๊ฐœ`); + Console.print(`6๊ฐœ ์ผ์น˜ (${WINNING_PRIZES.FIRST}์›) - ${this.results[1]}๊ฐœ`); this.calculateProfit(); } diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 000000000..5b1b0b30f --- /dev/null +++ b/src/constants.js @@ -0,0 +1,26 @@ +export const LOTTO_PRICE = 1000; +export const LOTTO_NUMBER_COUNT = 6; +export const LOTTO_NUMBER_RANGE = Object.freeze({ MIN: 1, MAX: 45 }); + +export const WINNING_PRIZES = Object.freeze({ + FIRST: 2000000000, + SECOND: 30000000, + THIRD: 1500000, + FOURTH: 50000, + FIFTH: 5000, +}); + +export const MATCH_COUNTS = Object.freeze({ + FIRST: 6, + SECOND: 5, + THIRD: 5, + FOURTH: 4, + FIFTH: 3, +}); + +export const ERROR_MESSAGES = Object.freeze({ + INVALID_AMOUNT: "[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์€ 1,000์› ๋‹จ์œ„๋กœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.", + INVALID_LOTTO_COUNT: "[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” 6๊ฐœ์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.", + INVALID_NUMBER_RANGE: "[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.", + BONUS_NUMBER_DUPLICATE: "[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.", +}); From a5ce77eae921dbd47f23665096c37db510a1ed61 Mon Sep 17 00:00:00 2001 From: Minji Kim Date: Mon, 4 Nov 2024 23:56:36 +0900 Subject: [PATCH 15/15] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __tests__/ApplicationTest.js | 14 ++++---------- __tests__/LottoTest.js | 7 +++++-- src/App.js | 29 ++++++++++++++--------------- src/Lotto.js | 3 +++ 4 files changed, 26 insertions(+), 27 deletions(-) diff --git a/__tests__/ApplicationTest.js b/__tests__/ApplicationTest.js index 872380c9c..a4f152d30 100644 --- a/__tests__/ApplicationTest.js +++ b/__tests__/ApplicationTest.js @@ -1,12 +1,11 @@ import App from "../src/App.js"; import { MissionUtils } from "@woowacourse/mission-utils"; +// Mock functions for console input and output const mockQuestions = (inputs) => { MissionUtils.Console.readLineAsync = jest.fn(); - MissionUtils.Console.readLineAsync.mockImplementation(() => { const input = inputs.shift(); - return Promise.resolve(input); }); }; @@ -24,21 +23,17 @@ const getLogSpy = () => { return logSpy; }; +// Error test helper const runException = async (input) => { - // given const logSpy = getLogSpy(); - const RANDOM_NUMBERS_TO_END = [1, 2, 3, 4, 5, 6]; const INPUT_NUMBERS_TO_END = ["1000", "1,2,3,4,5,6", "7"]; - mockRandoms([RANDOM_NUMBERS_TO_END]); mockQuestions([input, ...INPUT_NUMBERS_TO_END]); - // when const app = new App(); await app.run(); - // then expect(logSpy).toHaveBeenCalledWith(expect.stringContaining("[ERROR]")); }; @@ -48,7 +43,6 @@ describe("๋กœ๋˜ ํ…Œ์ŠคํŠธ", () => { }); test("๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ", async () => { - // given const logSpy = getLogSpy(); mockRandoms([ @@ -63,11 +57,11 @@ describe("๋กœ๋˜ ํ…Œ์ŠคํŠธ", () => { ]); mockQuestions(["8000", "1,2,3,4,5,6", "7"]); - // when const app = new App(); await app.run(); - // then + console.log(logSpy.mock.calls.map((call) => call[0])); + const logs = [ "8๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.", "[8, 21, 23, 41, 42, 43]", diff --git a/__tests__/LottoTest.js b/__tests__/LottoTest.js index 409aaf69b..31460c656 100644 --- a/__tests__/LottoTest.js +++ b/__tests__/LottoTest.js @@ -7,12 +7,15 @@ describe("๋กœ๋˜ ํด๋ž˜์Šค ํ…Œ์ŠคํŠธ", () => { }).toThrow("[ERROR]"); }); - // TODO: ํ…Œ์ŠคํŠธ๊ฐ€ ํ†ต๊ณผํ•˜๋„๋ก ํ”„๋กœ๋•์…˜ ์ฝ”๋“œ ๊ตฌํ˜„ test("๋กœ๋˜ ๋ฒˆํ˜ธ์— ์ค‘๋ณต๋œ ์ˆซ์ž๊ฐ€ ์žˆ์œผ๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.", () => { expect(() => { new Lotto([1, 2, 3, 4, 5, 5]); }).toThrow("[ERROR]"); }); - // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„์— ๋”ฐ๋ฅธ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ + test("๋กœ๋˜ ๋ฒˆํ˜ธ๊ฐ€ 6๊ฐœ์ด๊ณ  ์ค‘๋ณต์ด ์—†์œผ๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.", () => { + expect(() => { + new Lotto([1, 2, 3, 4, 5, 6]); + }).not.toThrow(); + }); }); diff --git a/src/App.js b/src/App.js index 7042ecf6e..de3af9ec5 100644 --- a/src/App.js +++ b/src/App.js @@ -33,7 +33,7 @@ class App { printPurchasedLotto() { const lottoCount = this.purchaseAmount / LOTTO_PRICE; - Console.print(`\n${lottoCount}๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.`); + Console.print(`${lottoCount}๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.`); this.lottoTickets = this.generateLottoTickets(lottoCount); this.displayLottoTickets(); this.inputWinningNumbers(); @@ -53,9 +53,7 @@ class App { } async inputWinningNumbers() { - const winningNumbersInput = await Console.readLineAsync( - "\n๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”. (์˜ˆ: 1,2,3,4,5,6)\n", - ); + const winningNumbersInput = await Console.readLineAsync("\n๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n"); const winningNumbers = winningNumbersInput.split(",").map(Number); this.validateWinningNumbers(winningNumbers); } @@ -140,22 +138,23 @@ class App { } printResults() { - Console.print("\n๋‹น์ฒจ ํ†ต๊ณ„\n---"); - Console.print(`3๊ฐœ ์ผ์น˜ (${WINNING_PRIZES.FIFTH}์›) - ${this.results[5]}๊ฐœ`); - Console.print(`4๊ฐœ ์ผ์น˜ (${WINNING_PRIZES.FOURTH}์›) - ${this.results[4]}๊ฐœ`); - Console.print(`5๊ฐœ ์ผ์น˜ (${WINNING_PRIZES.THIRD}์›) - ${this.results[3]}๊ฐœ`); - Console.print(`5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (${WINNING_PRIZES.SECOND}์›) - ${this.results[2]}๊ฐœ`); - Console.print(`6๊ฐœ ์ผ์น˜ (${WINNING_PRIZES.FIRST}์›) - ${this.results[1]}๊ฐœ`); + Console.print("๋‹น์ฒจ ํ†ต๊ณ„\n---"); + Console.print(`3๊ฐœ ์ผ์น˜ (5,000์›) - ${this.results[5]}๊ฐœ`); + Console.print(`4๊ฐœ ์ผ์น˜ (50,000์›) - ${this.results[4]}๊ฐœ`); + Console.print(`5๊ฐœ ์ผ์น˜ (1,500,000์›) - ${this.results[3]}๊ฐœ`); + Console.print(`5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ${this.results[2]}๊ฐœ`); + Console.print(`6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ${this.results[1]}๊ฐœ`); this.calculateProfit(); } calculateProfit() { - const prizeAmounts = { 1: 2000000000, 2: 30000000, 3: 1500000, 4: 50000, 5: 5000 }; - const totalPrize = Object.keys(this.results).reduce( - (sum, key) => sum + this.results[key] * prizeAmounts[key], - 0, - ); + const totalPrize = + this.results[1] * WINNING_PRIZES.FIRST + + this.results[2] * WINNING_PRIZES.SECOND + + this.results[3] * WINNING_PRIZES.THIRD + + this.results[4] * WINNING_PRIZES.FOURTH + + this.results[5] * WINNING_PRIZES.FIFTH; const profitRate = ((totalPrize / this.purchaseAmount) * 100).toFixed(1); Console.print(`์ด ์ˆ˜์ต๋ฅ ์€ ${profitRate}%์ž…๋‹ˆ๋‹ค.`); diff --git a/src/Lotto.js b/src/Lotto.js index 87d6db3f2..7b34fc6c3 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -10,6 +10,9 @@ class Lotto { if (numbers.length !== 6) { throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 6๊ฐœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); } + if (new Set(numbers).size !== numbers.length) { + throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ์—๋Š” ์ค‘๋ณต๋œ ์ˆซ์ž๊ฐ€ ์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } } getNumbers() {