From 7dd56cb7bd185ec769fe42b8a4b8ba216875e11e Mon Sep 17 00:00:00 2001 From: egg-silver Date: Mon, 4 Nov 2024 20:45:57 +0900 Subject: [PATCH 1/7] =?UTF-8?q?docs:=20README=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=ED=95=A0=20=EA=B8=B0=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 157 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 15bb106b5..3fbcdea7d 100644 --- a/README.md +++ b/README.md @@ -1 +1,157 @@ -# 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,000์› ๋‹จ์œ„๋กœ ์ž…๋ ฅ ๋ฐ›์œผ๋ฉฐ 1,000์›์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•œ๋‹ค. + +``` +14000 +``` + +- ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ ๋ฐ›๋Š”๋‹ค. ๋ฒˆํ˜ธ๋Š” ์‰ผํ‘œ(,)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค. + +``` +1,2,3,4,5,6 +``` + +- ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ ๋ฐ›๋Š”๋‹ค. + +``` +7 +``` + + +์ถœ๋ ฅ + +- ๋ฐœํ–‰ํ•œ ๋กœ๋˜ ์ˆ˜๋Ÿ‰ ๋ฐ ๋ฒˆํ˜ธ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ๋ณด์—ฌ์ค€๋‹ค. + +``` +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%์ž…๋‹ˆ๋‹ค. +``` + +- ์˜ˆ์™ธ ์ƒํ™ฉ ์‹œ ์—๋Ÿฌ ๋ฌธ๊ตฌ๋ฅผ ์ถœ๋ ฅํ•ด์•ผ ํ•œ๋‹ค. ๋‹จ, ์—๋Ÿฌ ๋ฌธ๊ตฌ๋Š” "[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%์ž…๋‹ˆ๋‹ค. +``` + +## ๐Ÿ”ฅ ๊ตฌํ˜„ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก + +1. ๋กœ๋˜ ๊ตฌ์ž… ๊ธˆ์•ก์„ ์ž…๋ ฅ ๋ฐ›๋Š”๋‹ค +- 1000์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ : [ERROR] ๊ธˆ์•ก์€ 1000์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€๋Š” ์ˆ˜๋งŒ ์ž…๋ ฅ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. + +2. ์ž…๋ ฅํ•œ ๊ธˆ์•ก๋งŒํผ(์ž…๋ ฅ ๊ธˆ/1000)์˜ ๋กœ๋˜๋ฅผ ๋ฐฐ์—ด์— ๋‹ด์•„์„œ ๋ฐœํ–‰ +- ํ•˜๋‚˜์˜ ๋กœ๋˜(๋ฐฐ์—ด)๋Š” 6๊ฐœ์˜ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ๋žœ๋ค ์ˆซ์ž๋ฅผ ๊ฐ€์ง +- ์ด๋•Œ ๊ฐ ๋ฐฐ์—ด์˜ ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ + +3. ๋‹น์ฒจ ๋ฒˆํ˜ธ 6๊ฐœ ์ž…๋ ฅ๋ฐ›๊ธฐ +- ๊ฐ ๋ฒˆํ˜ธ๋Š” ,๋ฅผ ํ†ตํ•ด์„œ ๊ตฌ๋ถ„ +- ,๋กœ ๊ตฌ๋ถ„ํ•œ ๋ฌธ์ž์—ด์— ์ˆซ์ž๊ฐ€ ์•„๋‹Œ ๊ฐ’์ด ์žˆ์œผ๋ฉด ์˜ˆ์™ธ์ฒ˜๋ฆฌ : +[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ๋Š” 1~45 ๋ฒ”์œ„ ๋‚ด์˜ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” 6๊ฐœ์˜ ์ˆซ์ž๊ฐ’์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +- ๊ฐ ๋ฒˆํ˜ธ๋Š” 1~45์˜ ๋ฒ”์œ„ ๋‚ด์— ์žˆ์–ด์•ผ ํ•œ๋‹ค. + ๋งŒ์•ฝ ๋ฒ”์œ„ ์™ธ์˜ ์ˆซ์ž๋ฅผ ํฌํ•จํ•œ๋‹ค๋ฉด ์˜ˆ์™ธ ์ฒ˜๋ฆฌ : [ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1~45์˜ ์ˆซ์ž์˜ ๋ฒ”์œ„์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. +- ๊ฐ ๋ฒˆํ˜ธ๋Š” ์ค‘๋ณต์—†์ด 6๊ฐœ์—ฌ์•ผ๋งŒ ํ•œ๋‹ค. + ๋งŒ์•ฝ, ๊ฐœ์ˆ˜๊ฐ€ 6๊ฐœ๊ฐ€ ์•ˆ๋˜๋ฉด ์˜ˆ์™ธ์ฒ˜๋ฆฌ: [ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 6๊ฐœ์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. + +4. ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์ž…๋ ฅ๋ฐ›๊ธฐ +- ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์—ญ์‹œ 1~45 ๋ฒ”์œ„ ๋‚ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•จ + ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ 1~45 ์™ธ์˜ ์ˆซ์ž์ผ ๊ฒฝ์šฐ ์˜ˆ์™ธ์ฒ˜๋ฆฌ : [ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” 1~45 ๋ฒ”์œ„ ์ค‘ ํ•˜๋‚˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค +- ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋˜๋ฉด ์•ˆ๋จ + ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ์™€ ๋‹น์ฒจ๋ฒˆํ˜ธ๊ฐ€ ์ค‘๋ณต๋  ๊ฒฝ์šฐ ์˜ˆ์™ธ์ฒ˜๋ฆฌ : [ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. + +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์› +``` + +- ๊ฐ ๋กœ๋˜ ๋ฐฐ์—ด๊ณผ ๋กœ๋˜ ๋‹น์ฒจ ๋ฐฐ์—ด์„ ํ™•์ธํ•ด์„œ ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•์‹์œผ๋กœ ์ถœ๋ ฅํ•œ๋‹ค. +``` +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%์ž…๋‹ˆ๋‹ค. +``` + +- ์ˆ˜์ต๋ฅ ์€ (์ด ์ˆ˜์ต/์ด ํˆฌ์ž ๊ธˆ์•ก) * 100๋กœ ๊ณ„์‚ฐํ•œ๋‹ค. +- ์ˆ˜์ต๋ฅ ์€ ์†Œ์ˆ˜์  ๋‘˜์งธ ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผํ•œ๋‹ค. From 0b9ea6d69caa6add2bea4ada7a1c9567c9f97855 Mon Sep 17 00:00:00 2001 From: egg-silver Date: Mon, 4 Nov 2024 22:00:51 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=EB=B3=B5=EA=B6=8C=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=EB=B0=9B?= =?UTF-8?q?=EA=B8=B0=20=EB=B0=8F=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 32 +++++++++++++++++++++++++++++++- src/constants.js | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/constants.js diff --git a/src/App.js b/src/App.js index 091aa0a5d..2df2e3104 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,35 @@ +import { Console } from '@woowacourse/mission-utils'; +import { CONSTANTS } from './constants.js'; + class App { - async run() {} + async run() { + try { + Console.print(CONSTANTS.MESSAGE_PURCHASE_AMOUNT); + const totalAmount = await this.getPurchaseAmount(); + this.validateAmount(totalAmount); + + const numberOfTickets = totalAmount / CONSTANTS.LOTTO_PRICE; + Console.print( + `\n${numberOfTickets}${CONSTANTS.MESSAGE_PURCHASED_TICKETS}` + ); + } catch (error) { + Console.print(error.message); + throw error; + } + } + + async getPurchaseAmount() { + const input = await Console.readLineAsync(''); + return Number(input); + } + + validateAmount(amount) { + if (isNaN(amount) || amount % CONSTANTS.LOTTO_PRICE !== 0) { + throw new Error(CONSTANTS.ERROR_INVALID_AMOUNT); + } + } } +const app = new App(); +app.run(); export default App; diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 000000000..1470c9918 --- /dev/null +++ b/src/constants.js @@ -0,0 +1,37 @@ +export const CONSTANTS = { + LOTTO_PRICE: 1000, + + MESSAGE_PURCHASE_AMOUNT: '๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.', + MESSAGE_PURCHASED_TICKETS: '๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.', + MESSAGE_WINNING_NUMBERS: '๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.', + MESSAGE_BONUS_NUMBER: '๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.', + MESSAGE_WINNING_STATISTICS: '๋‹น์ฒจ ํ†ต๊ณ„', + MESSAGE_PROFIT_RATE: '์ด ์ˆ˜์ต๋ฅ ์€', + + WINNING_RANKS: { + THREE_MATCH: { match: 3, prize: 5000, message: '3๊ฐœ ์ผ์น˜ (5,000์›)' }, + FOUR_MATCH: { match: 4, prize: 50000, message: '4๊ฐœ ์ผ์น˜ (50,000์›)' }, + FIVE_MATCH: { match: 5, prize: 1500000, message: '5๊ฐœ ์ผ์น˜ (1,500,000์›)' }, + FIVE_MATCH_BONUS: { + match: 5, + bonus: true, + prize: 30000000, + message: '5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›)', + }, + SIX_MATCH: { + match: 6, + prize: 2000000000, + message: '6๊ฐœ ์ผ์น˜ (2,000,000,000์›)', + }, + }, + + ERROR_INVALID_AMOUNT: + '[ERROR] ๊ธˆ์•ก์€ 1000์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€๋Š” ์ˆซ์ž๋งŒ ์ž…๋ ฅ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.', + ERROR_INVALID_WINNING_NUMBERS: + '[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ๋Š” 1~45 ๋ฒ”์œ„ ๋‚ด์˜ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” 6๊ฐœ์˜ ์ˆซ์ž๊ฐ’์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.', + ERROR_INVALID_RANGE: '[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1-45์˜ ์ˆซ์ž์˜ ๋ฒ”์œ„์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.', + ERROR_INVALID_BONUS_NUMBER: + '[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” 1~45 ๋ฒ”์œ„ ์ค‘ ํ•˜๋‚˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.', + ERROR_DUPLICATE_BONUS_NUMBER: + '[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.', +}; From 223574b6aa7ec2af79076900cb7e2c1640848f1a Mon Sep 17 00:00:00 2001 From: egg-silver Date: Mon, 4 Nov 2024 22:15:48 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20=EB=B3=B5=EA=B6=8C=20=EA=B5=AC?= =?UTF-8?q?=EB=A7=A4=20=EA=B0=9C=EC=88=98=EC=97=90=20=EB=A7=9E=EB=8A=94=20?= =?UTF-8?q?=EB=A1=9C=EB=98=90=20=EB=B0=B0=EC=97=B4=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 16 ++++++++++++++++ src/Lotto.js | 18 +++++++++--------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/App.js b/src/App.js index 2df2e3104..2269de6f0 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,6 @@ import { Console } from '@woowacourse/mission-utils'; import { CONSTANTS } from './constants.js'; +import Lotto from './Lotto.js'; class App { async run() { @@ -12,6 +13,12 @@ class App { Console.print( `\n${numberOfTickets}${CONSTANTS.MESSAGE_PURCHASED_TICKETS}` ); + + const lottos = this.generateLottos(numberOfTickets); + + lottos.forEach((lottoNumbers) => { + Console.print(`[${lottoNumbers.join(', ')}]`); + }); } catch (error) { Console.print(error.message); throw error; @@ -28,6 +35,15 @@ class App { throw new Error(CONSTANTS.ERROR_INVALID_AMOUNT); } } + + generateLottos(count) { + const lottos = []; + for (let i = 0; i < count; i++) { + const lotto = new Lotto(); + lottos.push(lotto.getNumbers()); + } + return lottos; + } } const app = new App(); diff --git a/src/Lotto.js b/src/Lotto.js index cb0b1527e..104d4ea8d 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -1,18 +1,18 @@ +import { Random } from '@woowacourse/mission-utils'; +import { CONSTANTS } from './constants.js'; + class Lotto { #numbers; - constructor(numbers) { - this.#validate(numbers); - this.#numbers = numbers; + constructor() { + this.#numbers = Random.pickUniqueNumbersInRange(1, 45, 6).sort( + (a, b) => a - b + ); } - #validate(numbers) { - if (numbers.length !== 6) { - throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 6๊ฐœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); - } + getNumbers() { + return this.#numbers; } - - // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ } export default Lotto; From 7eb4950298b5c5e21f7cd2beaaab4bf21dda3eb5 Mon Sep 17 00:00:00 2001 From: egg-silver Date: Mon, 4 Nov 2024 22:36:44 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=206=EA=B0=9C=20=EC=9E=85=EB=A0=A5=20=EB=B0=9B?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 20 ++++++++++++-------- src/Validation.js | 23 +++++++++++++++++++++++ src/constants.js | 11 ++++++----- 3 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 src/Validation.js diff --git a/src/App.js b/src/App.js index 2269de6f0..7f9af2a41 100644 --- a/src/App.js +++ b/src/App.js @@ -1,13 +1,14 @@ import { Console } from '@woowacourse/mission-utils'; import { CONSTANTS } from './constants.js'; import Lotto from './Lotto.js'; +import { validateAmount, validateWinningNumbers } from './Validation.js'; class App { async run() { try { Console.print(CONSTANTS.MESSAGE_PURCHASE_AMOUNT); const totalAmount = await this.getPurchaseAmount(); - this.validateAmount(totalAmount); + validateAmount(totalAmount); const numberOfTickets = totalAmount / CONSTANTS.LOTTO_PRICE; Console.print( @@ -15,10 +16,12 @@ class App { ); const lottos = this.generateLottos(numberOfTickets); - lottos.forEach((lottoNumbers) => { Console.print(`[${lottoNumbers.join(', ')}]`); }); + + Console.print(CONSTANTS.MESSAGE_WINNING_NUMBERS); + const winningNumbers = await this.getWinningNumbers(); } catch (error) { Console.print(error.message); throw error; @@ -30,12 +33,6 @@ class App { return Number(input); } - validateAmount(amount) { - if (isNaN(amount) || amount % CONSTANTS.LOTTO_PRICE !== 0) { - throw new Error(CONSTANTS.ERROR_INVALID_AMOUNT); - } - } - generateLottos(count) { const lottos = []; for (let i = 0; i < count; i++) { @@ -44,6 +41,13 @@ class App { } return lottos; } + + async getWinningNumbers() { + const input = await Console.readLineAsync(''); + const winningNumbers = input.split(',').map(Number); + validateWinningNumbers(winningNumbers); + return winningNumbers; + } } const app = new App(); diff --git a/src/Validation.js b/src/Validation.js new file mode 100644 index 000000000..453798a1a --- /dev/null +++ b/src/Validation.js @@ -0,0 +1,23 @@ +import { CONSTANTS } from './constants.js'; + +export function validateAmount(amount) { + if (isNaN(amount) || amount % CONSTANTS.LOTTO_PRICE !== 0) { + throw new Error(CONSTANTS.ERROR_INVALID_AMOUNT); + } +}; + +export function validateWinningNumbers(numbers) { + if (numbers.length !== 6) { + throw new Error(CONSTANTS.ERROR_INSUFFICIENT_NUMBERS); + } + + const isWithinRange = numbers.every((num) => num >= 1 && num <= 45); + if (!isWithinRange) { + throw new Error(CONSTANTS.ERROR_INVALID_RANGE); + } + + const isUnique = new Set(numbers).size === 6; + if (!isUnique) { + throw new Error(CONSTANTS.ERROR_INVALID_WINNING_NUMBERS); + } +} diff --git a/src/constants.js b/src/constants.js index 1470c9918..2ccf900c5 100644 --- a/src/constants.js +++ b/src/constants.js @@ -3,7 +3,7 @@ export const CONSTANTS = { MESSAGE_PURCHASE_AMOUNT: '๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.', MESSAGE_PURCHASED_TICKETS: '๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.', - MESSAGE_WINNING_NUMBERS: '๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.', + MESSAGE_WINNING_NUMBERS: '\n๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.', MESSAGE_BONUS_NUMBER: '๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.', MESSAGE_WINNING_STATISTICS: '๋‹น์ฒจ ํ†ต๊ณ„', MESSAGE_PROFIT_RATE: '์ด ์ˆ˜์ต๋ฅ ์€', @@ -28,10 +28,11 @@ export const CONSTANTS = { ERROR_INVALID_AMOUNT: '[ERROR] ๊ธˆ์•ก์€ 1000์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€๋Š” ์ˆซ์ž๋งŒ ์ž…๋ ฅ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.', ERROR_INVALID_WINNING_NUMBERS: - '[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ๋Š” 1~45 ๋ฒ”์œ„ ๋‚ด์˜ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” 6๊ฐœ์˜ ์ˆซ์ž๊ฐ’์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.', - ERROR_INVALID_RANGE: '[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1-45์˜ ์ˆซ์ž์˜ ๋ฒ”์œ„์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.', - ERROR_INVALID_BONUS_NUMBER: - '[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” 1~45 ๋ฒ”์œ„ ์ค‘ ํ•˜๋‚˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.', + '[ERROR] ์ˆซ์ž๊ฐ€ ์ค‘๋ณต๋ฉ๋‹ˆ๋‹ค. ๋‹น์ฒจ ๋ฒˆํ˜ธ๋Š” 1~45 ๋ฒ”์œ„ ๋‚ด์˜ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” 6๊ฐœ์˜ ์ˆซ์ž๊ฐ’์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.', + ERROR_INVALID_RANGE: + '[ERROR] ์ž…๋ ฅ ๊ฐ€๋Šฅํ•œ ์ˆซ์ž ๋ฒ”์œ„๋ฅผ ๋„˜์Šต๋‹ˆ๋‹ค. ๋ฒˆํ˜ธ๋Š” 1~45 ๋ฒ”์œ„ ์ค‘ ํ•˜๋‚˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.', + ERROR_INSUFFICIENT_NUMBERS: + '[ERROR] ์ž…๋ ฅ๋œ ์ˆซ์ž๊ฐ’์ด ๋ชจ์ž๋ฆ…๋‹ˆ๋‹ค. 6๊ฐœ์˜ ์ˆซ์ž๊ฐ€ ์ž…๋ ฅ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.', ERROR_DUPLICATE_BONUS_NUMBER: '[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.', }; From d6f9c58fadf06f58e2bf65f7e6f2d87ab12c04c8 Mon Sep 17 00:00:00 2001 From: egg-silver Date: Mon, 4 Nov 2024 22:41:29 +0900 Subject: [PATCH 5/7] =?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=EB=B0=9B=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 16 +++++++++++++++- src/Validation.js | 11 ++++++++++- src/constants.js | 2 +- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/App.js b/src/App.js index 7f9af2a41..fcf6a0edb 100644 --- a/src/App.js +++ b/src/App.js @@ -1,7 +1,11 @@ import { Console } from '@woowacourse/mission-utils'; import { CONSTANTS } from './constants.js'; import Lotto from './Lotto.js'; -import { validateAmount, validateWinningNumbers } from './Validation.js'; +import { + validateAmount, + validateWinningNumbers, + validateBonusNumber, +} from './Validation.js'; class App { async run() { @@ -22,6 +26,9 @@ class App { Console.print(CONSTANTS.MESSAGE_WINNING_NUMBERS); const winningNumbers = await this.getWinningNumbers(); + + Console.print(CONSTANTS.MESSAGE_BONUS_NUMBER); + const bonusNumber = await this.getBonusNumber(winningNumbers); } catch (error) { Console.print(error.message); throw error; @@ -48,6 +55,13 @@ class App { validateWinningNumbers(winningNumbers); return winningNumbers; } + + async getBonusNumber(winningNumbers) { + const input = await Console.readLineAsync(''); + const bonusNumber = Number(input); + validateBonusNumber(bonusNumber, winningNumbers); + return bonusNumber; + } } const app = new App(); diff --git a/src/Validation.js b/src/Validation.js index 453798a1a..8e4292ada 100644 --- a/src/Validation.js +++ b/src/Validation.js @@ -4,7 +4,7 @@ export function validateAmount(amount) { if (isNaN(amount) || amount % CONSTANTS.LOTTO_PRICE !== 0) { throw new Error(CONSTANTS.ERROR_INVALID_AMOUNT); } -}; +} export function validateWinningNumbers(numbers) { if (numbers.length !== 6) { @@ -21,3 +21,12 @@ export function validateWinningNumbers(numbers) { throw new Error(CONSTANTS.ERROR_INVALID_WINNING_NUMBERS); } } + +export function validateBonusNumber(bonusNumber, winningNumbers) { + if (bonusNumber < 1 || bonusNumber > 45) { + throw new Error(CONSTANTS.ERROR_INVALID_RANGE); + } + if (winningNumbers.includes(bonusNumber)) { + throw new Error(CONSTANTS.ERROR_DUPLICATE_BONUS_NUMBER); + } +} diff --git a/src/constants.js b/src/constants.js index 2ccf900c5..6af0d2ec4 100644 --- a/src/constants.js +++ b/src/constants.js @@ -4,7 +4,7 @@ export const CONSTANTS = { MESSAGE_PURCHASE_AMOUNT: '๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.', MESSAGE_PURCHASED_TICKETS: '๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.', MESSAGE_WINNING_NUMBERS: '\n๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.', - MESSAGE_BONUS_NUMBER: '๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.', + MESSAGE_BONUS_NUMBER: '\n๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.', MESSAGE_WINNING_STATISTICS: '๋‹น์ฒจ ํ†ต๊ณ„', MESSAGE_PROFIT_RATE: '์ด ์ˆ˜์ต๋ฅ ์€', From 7b8e91f9fadf7e77abdd20df821fa945a4acfd99 Mon Sep 17 00:00:00 2001 From: egg-silver Date: Mon, 4 Nov 2024 23:21:05 +0900 Subject: [PATCH 6/7] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8=20=EA=B8=B0?= =?UTF-8?q?=EC=A4=80=EC=97=90=20=EB=A7=9E=EB=8A=94=20=EB=8B=B9=EC=B2=A8=20?= =?UTF-8?q?=ED=86=B5=EA=B3=84=20=EC=B6=9C=EB=A0=A5=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- src/App.js | 3 +++ src/Statistics.js | 58 +++++++++++++++++++++++++++++++++++++++++++++++ src/constants.js | 15 +++++------- 4 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 src/Statistics.js diff --git a/README.md b/README.md index 3fbcdea7d..57454abde 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,8 @@ 5. ์•„๋ž˜์˜ ๋‹น์ฒจ ๊ธฐ์ค€์— ๋งž๋Š” ๋‹น์ฒจ ํ†ต๊ณ„ ์ถœ๋ ฅํ•˜๊ธฐ ``` 1๋“ฑ: 6๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 2,000,000,000์› -2๋“ฑ: 5๊ฐœ ๋ฒˆํ˜ธ + ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์ผ์น˜ / 30,000,000์› 3๋“ฑ: 5๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 1,500,000์› +2๋“ฑ: 5๊ฐœ ๋ฒˆํ˜ธ + ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์ผ์น˜ / 30,000,000์› +3๋“ฑ: 5๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 1,500,000์› 4๋“ฑ: 4๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 50,000์› 5๋“ฑ: 3๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 5,000์› ``` diff --git a/src/App.js b/src/App.js index fcf6a0edb..2c5b00984 100644 --- a/src/App.js +++ b/src/App.js @@ -6,6 +6,7 @@ import { validateWinningNumbers, validateBonusNumber, } from './Validation.js'; +import { calculateStatistics } from './Statistics.js'; class App { async run() { @@ -29,6 +30,8 @@ class App { Console.print(CONSTANTS.MESSAGE_BONUS_NUMBER); const bonusNumber = await this.getBonusNumber(winningNumbers); + + calculateStatistics(lottos, winningNumbers, bonusNumber, totalAmount); } catch (error) { Console.print(error.message); throw error; diff --git a/src/Statistics.js b/src/Statistics.js new file mode 100644 index 000000000..43e11d604 --- /dev/null +++ b/src/Statistics.js @@ -0,0 +1,58 @@ +import { Console } from '@woowacourse/mission-utils'; +import { CONSTANTS } from './constants.js'; + +export function calculateStatistics( + lottos, + winningNumbers, + bonusNumber, + totalAmount +) { + const rankCounts = { + THREE_MATCH: 0, + FOUR_MATCH: 0, + FIVE_MATCH: 0, + FIVE_MATCH_BONUS: 0, + SIX_MATCH: 0, + }; + + lottos.forEach((lottoNumbers) => { + const matchCount = lottoNumbers.filter((num) => + winningNumbers.includes(num) + ).length; + const hasBonus = lottoNumbers.includes(bonusNumber); + + if (matchCount === 6) rankCounts.SIX_MATCH++; + else if (matchCount === 5 && hasBonus) rankCounts.FIVE_MATCH_BONUS++; + else if (matchCount === 5) rankCounts.FIVE_MATCH++; + else if (matchCount === 4) rankCounts.FOUR_MATCH++; + else if (matchCount === 3) rankCounts.THREE_MATCH++; + }); + + const totalPrize = + rankCounts.SIX_MATCH * CONSTANTS.WINNING_RANKS.SIX_MATCH.prize + + rankCounts.FIVE_MATCH_BONUS * + CONSTANTS.WINNING_RANKS.FIVE_MATCH_BONUS.prize + + rankCounts.FIVE_MATCH * CONSTANTS.WINNING_RANKS.FIVE_MATCH.prize + + rankCounts.FOUR_MATCH * CONSTANTS.WINNING_RANKS.FOUR_MATCH.prize + + rankCounts.THREE_MATCH * CONSTANTS.WINNING_RANKS.THREE_MATCH.prize; + + const profitRate = ((totalPrize / totalAmount) * 100).toFixed(1); + + Console.print(CONSTANTS.MESSAGE_WINNING_STATISTICS); + Console.print( + `${CONSTANTS.WINNING_RANKS.THREE_MATCH.message}${rankCounts.THREE_MATCH}๊ฐœ` + ); + Console.print( + `${CONSTANTS.WINNING_RANKS.FOUR_MATCH.message}${rankCounts.FOUR_MATCH}๊ฐœ` + ); + Console.print( + `${CONSTANTS.WINNING_RANKS.FIVE_MATCH.message}${rankCounts.FIVE_MATCH}๊ฐœ` + ); + Console.print( + `${CONSTANTS.WINNING_RANKS.FIVE_MATCH_BONUS.message}${rankCounts.FIVE_MATCH_BONUS}๊ฐœ` + ); + Console.print( + `${CONSTANTS.WINNING_RANKS.SIX_MATCH.message}${rankCounts.SIX_MATCH}๊ฐœ` + ); + Console.print(`${CONSTANTS.MESSAGE_PROFIT_RATE} ${profitRate}%์ž…๋‹ˆ๋‹ค.`); +} diff --git a/src/constants.js b/src/constants.js index 6af0d2ec4..0d8ae5bd3 100644 --- a/src/constants.js +++ b/src/constants.js @@ -5,23 +5,20 @@ export const CONSTANTS = { MESSAGE_PURCHASED_TICKETS: '๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.', MESSAGE_WINNING_NUMBERS: '\n๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.', MESSAGE_BONUS_NUMBER: '\n๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.', - MESSAGE_WINNING_STATISTICS: '๋‹น์ฒจ ํ†ต๊ณ„', + MESSAGE_WINNING_STATISTICS: '\n๋‹น์ฒจ ํ†ต๊ณ„\n---', MESSAGE_PROFIT_RATE: '์ด ์ˆ˜์ต๋ฅ ์€', WINNING_RANKS: { - THREE_MATCH: { match: 3, prize: 5000, message: '3๊ฐœ ์ผ์น˜ (5,000์›)' }, - FOUR_MATCH: { match: 4, prize: 50000, message: '4๊ฐœ ์ผ์น˜ (50,000์›)' }, - FIVE_MATCH: { match: 5, prize: 1500000, message: '5๊ฐœ ์ผ์น˜ (1,500,000์›)' }, + THREE_MATCH: { prize: 5000, message: '3๊ฐœ ์ผ์น˜ (5,000์›) - ' }, + FOUR_MATCH: { prize: 50000, message: '4๊ฐœ ์ผ์น˜ (50,000์›) - ' }, + FIVE_MATCH: { prize: 1500000, message: '5๊ฐœ ์ผ์น˜ (1,500,000์›) - ' }, FIVE_MATCH_BONUS: { - match: 5, - bonus: true, prize: 30000000, - message: '5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›)', + message: '5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ', }, SIX_MATCH: { - match: 6, prize: 2000000000, - message: '6๊ฐœ ์ผ์น˜ (2,000,000,000์›)', + message: '6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ', }, }, From a37e1f26aa3964ec66a8a2d4f8ca303d902abeda Mon Sep 17 00:00:00 2001 From: egg-silver Date: Mon, 4 Nov 2024 23:52:40 +0900 Subject: [PATCH 7/7] =?UTF-8?q?feat:=20test=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __tests__/ApplicationTest.js | 56 +++++++++++++++++++----------------- __tests__/LottoTest.js | 35 ++++++++++++++++------ src/App.js | 1 - src/Lotto.js | 25 +++++++++++++--- src/constants.js | 2 ++ 5 files changed, 80 insertions(+), 39 deletions(-) diff --git a/__tests__/ApplicationTest.js b/__tests__/ApplicationTest.js index 872380c9c..18af06b9c 100644 --- a/__tests__/ApplicationTest.js +++ b/__tests__/ApplicationTest.js @@ -1,5 +1,5 @@ -import App from "../src/App.js"; -import { MissionUtils } from "@woowacourse/mission-utils"; +import App from '../src/App.js'; +import { MissionUtils } from '@woowacourse/mission-utils'; const mockQuestions = (inputs) => { MissionUtils.Console.readLineAsync = jest.fn(); @@ -19,7 +19,7 @@ const mockRandoms = (numbers) => { }; const getLogSpy = () => { - const logSpy = jest.spyOn(MissionUtils.Console, "print"); + const logSpy = jest.spyOn(MissionUtils.Console, 'print'); logSpy.mockClear(); return logSpy; }; @@ -29,25 +29,29 @@ const runException = async (input) => { 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"]; + 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(); + try { + await app.run(); + } catch (error) { + console.log('Captured Error:', error.message); + } // then - expect(logSpy).toHaveBeenCalledWith(expect.stringContaining("[ERROR]")); + expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('[ERROR]')); }; -describe("๋กœ๋˜ ํ…Œ์ŠคํŠธ", () => { +describe('๋กœ๋˜ ํ…Œ์ŠคํŠธ', () => { beforeEach(() => { jest.restoreAllMocks(); }); - test("๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ", async () => { + test('๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ', async () => { // given const logSpy = getLogSpy(); @@ -61,7 +65,7 @@ describe("๋กœ๋˜ ํ…Œ์ŠคํŠธ", () => { [2, 13, 22, 32, 38, 45], [1, 3, 5, 14, 22, 45], ]); - mockQuestions(["8000", "1,2,3,4,5,6", "7"]); + mockQuestions(['8000', '1,2,3,4,5,6', '7']); // when const app = new App(); @@ -69,21 +73,21 @@ describe("๋กœ๋˜ ํ…Œ์ŠคํŠธ", () => { // then const logs = [ - "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๊ฐœ", - "์ด ์ˆ˜์ต๋ฅ ์€ 62.5%์ž…๋‹ˆ๋‹ค.", + '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๊ฐœ', + '์ด ์ˆ˜์ต๋ฅ ์€ 62.5%์ž…๋‹ˆ๋‹ค.', ]; logs.forEach((log) => { @@ -91,7 +95,7 @@ describe("๋กœ๋˜ ํ…Œ์ŠคํŠธ", () => { }); }); - test("์˜ˆ์™ธ ํ…Œ์ŠคํŠธ", async () => { - await runException("1000j"); + test('์˜ˆ์™ธ ํ…Œ์ŠคํŠธ', async () => { + await runException('1000j'); }); }); diff --git a/__tests__/LottoTest.js b/__tests__/LottoTest.js index 409aaf69b..7ed17b8c9 100644 --- a/__tests__/LottoTest.js +++ b/__tests__/LottoTest.js @@ -1,18 +1,37 @@ -import Lotto from "../src/Lotto"; +import Lotto from '../src/Lotto'; -describe("๋กœ๋˜ ํด๋ž˜์Šค ํ…Œ์ŠคํŠธ", () => { - test("๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ๊ฐœ์ˆ˜๊ฐ€ 6๊ฐœ๊ฐ€ ๋„˜์–ด๊ฐ€๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.", () => { +describe('๋กœ๋˜ ํด๋ž˜์Šค ํ…Œ์ŠคํŠธ', () => { + test('๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ๊ฐœ์ˆ˜๊ฐ€ 6๊ฐœ๊ฐ€ ๋„˜์–ด๊ฐ€๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.', () => { expect(() => { new Lotto([1, 2, 3, 4, 5, 6, 7]); - }).toThrow("[ERROR]"); + }).toThrow('[ERROR]'); }); - // TODO: ํ…Œ์ŠคํŠธ๊ฐ€ ํ†ต๊ณผํ•˜๋„๋ก ํ”„๋กœ๋•์…˜ ์ฝ”๋“œ ๊ตฌํ˜„ - test("๋กœ๋˜ ๋ฒˆํ˜ธ์— ์ค‘๋ณต๋œ ์ˆซ์ž๊ฐ€ ์žˆ์œผ๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.", () => { + test('๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ๊ฐœ์ˆ˜๊ฐ€ 6๊ฐœ๋ณด๋‹ค ์ ์œผ๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.', () => { + expect(() => { + new Lotto([1, 2, 3, 4, 5]); + }).toThrow('[ERROR]'); + }); + + test('๋กœ๋˜ ๋ฒˆํ˜ธ์— ์ค‘๋ณต๋œ ์ˆซ์ž๊ฐ€ ์žˆ์œผ๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.', () => { expect(() => { new Lotto([1, 2, 3, 4, 5, 5]); - }).toThrow("[ERROR]"); + }).toThrow('[ERROR]'); + }); + + test('๋กœ๋˜ ๋ฒˆํ˜ธ๊ฐ€ 1~45 ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.', () => { + expect(() => { + new Lotto([0, 2, 3, 4, 5, 6]); + }).toThrow('[ERROR]'); + + expect(() => { + new Lotto([1, 2, 3, 4, 5, 46]); + }).toThrow('[ERROR]'); }); - // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„์— ๋”ฐ๋ฅธ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ + test('์œ ํšจํ•œ ๋กœ๋˜ ๋ฒˆํ˜ธ ๋ฐฐ์—ด์ด ์ฃผ์–ด์กŒ์„ ๋•Œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.', () => { + expect(() => { + new Lotto([1, 2, 3, 4, 5, 6]); + }).not.toThrow(); + }); }); diff --git a/src/App.js b/src/App.js index 2c5b00984..0070eb34f 100644 --- a/src/App.js +++ b/src/App.js @@ -68,5 +68,4 @@ class App { } const app = new App(); -app.run(); export default App; diff --git a/src/Lotto.js b/src/Lotto.js index 104d4ea8d..e62f8903a 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -4,10 +4,27 @@ import { CONSTANTS } from './constants.js'; class Lotto { #numbers; - constructor() { - this.#numbers = Random.pickUniqueNumbersInRange(1, 45, 6).sort( - (a, b) => a - b - ); + constructor(numbers) { + this.#numbers = + numbers || + Random.pickUniqueNumbersInRange(1, 45, 6).sort((a, b) => a - b); + this.#validate(this.#numbers); + } + + #validate(numbers) { + if (numbers.length !== 6) { + throw new Error(CONSTANTS.ERROR_INSUFFICIENT_LENGTH); + } + + const uniqueNumbers = new Set(numbers); + if (uniqueNumbers.size !== numbers.length) { + throw new Error(CONSTANTS.ERROR_DUPLICATE_NUMBERS); + } + + const isInRange = numbers.every((num) => num >= 1 && num <= 45); + if (!isInRange) { + throw new Error(CONSTANTS.ERROR_INVALID_RANGE); + } } getNumbers() { diff --git a/src/constants.js b/src/constants.js index 0d8ae5bd3..7ddda97f9 100644 --- a/src/constants.js +++ b/src/constants.js @@ -32,4 +32,6 @@ export const CONSTANTS = { '[ERROR] ์ž…๋ ฅ๋œ ์ˆซ์ž๊ฐ’์ด ๋ชจ์ž๋ฆ…๋‹ˆ๋‹ค. 6๊ฐœ์˜ ์ˆซ์ž๊ฐ€ ์ž…๋ ฅ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.', ERROR_DUPLICATE_BONUS_NUMBER: '[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.', + ERROR_INSUFFICIENT_LENGTH: '[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 6๊ฐœ์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.', + ERROR_DUPLICATE_NUMBERS: '[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ์— ์ค‘๋ณต๋œ ์ˆซ์ž๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.', };