diff --git a/README.md b/README.md index aff2c46597..05447c1f57 100644 --- a/README.md +++ b/README.md @@ -1,129 +1,28 @@ # ๋ฏธ์…˜ - ๋กœ๋˜ -## ๐Ÿ” ์ง„ํ–‰ ๋ฐฉ์‹ +## ํ”„๋กœ๊ทธ๋žจ ์†Œ๊ฐœ -- ๋ฏธ์…˜์€ **๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ, ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ, ๊ณผ์ œ ์ง„ํ–‰ ์š”๊ตฌ ์‚ฌํ•ญ** ์„ธ ๊ฐ€์ง€๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. -- ์„ธ ๊ฐœ์˜ ์š”๊ตฌ ์‚ฌํ•ญ์„ ๋งŒ์กฑํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•œ๋‹ค. ํŠนํžˆ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „์— ๊ธฐ๋Šฅ ๋ชฉ๋ก์„ ๋งŒ๋“ค๊ณ , ๊ธฐ๋Šฅ ๋‹จ์œ„๋กœ ์ปค๋ฐ‹ ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰ํ•œ๋‹ค. -- ๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ์— ๊ธฐ์žฌ๋˜์ง€ ์•Š์€ ๋‚ด์šฉ์€ ์Šค์Šค๋กœ ํŒ๋‹จํ•˜์—ฌ ๊ตฌํ˜„ํ•œ๋‹ค. +- ๋กœ๋˜๋Š” ํ•œ ์žฅ์— 1000์›์œผ๋กœ, ์›ํ•˜๋Š” ๋งŒํผ ๊ตฌ๋งค ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. +- ๊ตฌ๋งคํ•œ ๋กœ๋˜์— ๋Œ€ํ•œ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด, ๋‹น์ฒจ ๋‚ด์—ญ ๋ฐ ์ˆ˜์ต๋ฅ ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ๊ทธ๋žจ์ž…๋‹ˆ๋‹ค. -## ๐Ÿ“ฎ ๋ฏธ์…˜ ์ œ์ถœ ๋ฐฉ๋ฒ• +## ๊ธฐ๋Šฅ ๋ชฉ๋ก -- ๋ฏธ์…˜ ๊ตฌํ˜„์„ ์™„๋ฃŒํ•œ ํ›„ GitHub์„ ํ†ตํ•ด ์ œ์ถœํ•ด์•ผ ํ•œ๋‹ค. - - GitHub์„ ํ™œ์šฉํ•œ ์ œ์ถœ ๋ฐฉ๋ฒ•์€ [ํ”„๋ฆฌ์ฝ”์Šค ๊ณผ์ œ ์ œ์ถœ](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด - ์ œ์ถœํ•œ๋‹ค. -- GitHub์— ๋ฏธ์…˜์„ ์ œ์ถœํ•œ ํ›„ [์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค ์ง€์›](https://apply.techcourse.co.kr) ์‚ฌ์ดํŠธ์— ์ ‘์†ํ•˜์—ฌ ํ”„๋ฆฌ์ฝ”์Šค ๊ณผ์ œ๋ฅผ ์ œ์ถœํ•œ๋‹ค. - - ์ž์„ธํ•œ ๋ฐฉ๋ฒ•์€ [์ œ์ถœ ๊ฐ€์ด๋“œ](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse#์ œ์ถœ-๊ฐ€์ด๋“œ) ์ฐธ๊ณ  - - **Pull Request๋งŒ ๋ณด๋‚ด๊ณ  ์ง€์› ํ”Œ๋žซํผ์—์„œ ๊ณผ์ œ๋ฅผ ์ œ์ถœํ•˜์ง€ ์•Š์œผ๋ฉด ์ตœ์ข… ์ œ์ถœํ•˜์ง€ ์•Š์€ ๊ฒƒ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋‹ˆ ์ฃผ์˜ํ•œ๋‹ค.** +[๊ตฌ๋งค] -## ๐Ÿšจ ๊ณผ์ œ ์ œ์ถœ ์ „ ์ฒดํฌ ๋ฆฌ์ŠคํŠธ - 0์  ๋ฐฉ์ง€ +- [x] ๊ตฌ๋งค ๊ธˆ์•ก ์ž…๋ ฅ๋ฐ›๊ธฐ +- [x] ๊ตฌ๋งค ๊ธˆ์•ก์ด ์ˆซ์ž ์•„๋‹ ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ +- [x] ๊ตฌ๋งค ๊ธˆ์•ก 1000์› ๋‹จ์œ„๊ฐ€ ์•„๋‹ ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ +- [x] ๋‹น์ฒจ ๋ฒˆํ˜ธ ๋ฐ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์ž…๋ ฅ ๋ฐ›๊ธฐ -- ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ๋ชจ๋‘ ์ •์ƒ์ ์œผ๋กœ ํ–ˆ๋”๋ผ๋„ **์š”๊ตฌ ์‚ฌํ•ญ์— ๋ช…์‹œ๋œ ์ถœ๋ ฅ๊ฐ’ ํ˜•์‹์„ ์ง€ํ‚ค์ง€ ์•Š์„ ๊ฒฝ์šฐ 0์ ์œผ๋กœ ์ฒ˜๋ฆฌ**ํ•œ๋‹ค. -- ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ์™„๋ฃŒํ•œ ๋’ค ์•„๋ž˜ ๊ฐ€์ด๋“œ์— ๋”ฐ๋ผ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ–ˆ์„ ๋•Œ ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. -- **ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ•  ๊ฒฝ์šฐ 0์ ์œผ๋กœ ์ฒ˜๋ฆฌ**๋˜๋ฏ€๋กœ, ๋ฐ˜๋“œ์‹œ ํ™•์ธ ํ›„ ์ œ์ถœํ•œ๋‹ค. +[๊ฒฐ๊ณผ ์ถœ๋ ฅ] -### ํ…Œ์ŠคํŠธ ์‹คํ–‰ ๊ฐ€์ด๋“œ +- [x] ๋žœ๋ค ์ˆซ์ž๋กœ ๋กœ๋˜ ๋ฐœํ–‰ ๋ฐ ๊ฒฐ๊ณผ(์ˆ˜๋Ÿ‰ ๋ฐ ๋ฒˆํ˜ธ) ์ถœ๋ ฅ +- [x] ๋‹น์ฒจ ๋‚ด์—ญ ๊ณ„์‚ฐ ๋ฐ ์ถœ๋ ฅ +- [x] ์ˆ˜์ต๋ฅ  ๊ณ„์‚ฐ ๋ฐ ์ถœ๋ ฅ -- ํ…Œ์ŠคํŠธ ํŒจํ‚ค์ง€ ์„ค์น˜๋ฅผ ์œ„ํ•ด `Node.js` ๋ฒ„์ „ `18.17.1` ์ด์ƒ์ด ํ•„์š”ํ•˜๋‹ค. -- ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•œ๋‹ค. +- [x] ๋กœ๋˜ ํด๋ž˜์Šค ์ž‘์„ฑ -```bash -npm install -``` - -- ์„ค์น˜๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ๋‹ค๋ฉด, ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. - -```bash -npm test -``` - ---- - -## ๐Ÿš€ ๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ - -- ๋กœ๋˜ ๊ฒŒ์ž„ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. ๋กœ๋˜ ๊ฒŒ์ž„์€ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ทœ์น™์œผ๋กœ ์ง„ํ–‰๋œ๋‹ค. - -``` -- ๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ์ˆซ์ž ๋ฒ”์œ„๋Š” 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์›์ด๋‹ค. -- ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค. -- ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ๋งคํ•œ ๋กœ๋˜ ๋ฒˆํ˜ธ์™€ ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ๋น„๊ตํ•˜์—ฌ ๋‹น์ฒจ ๋‚ด์—ญ ๋ฐ ์ˆ˜์ต๋ฅ ์„ ์ถœ๋ ฅํ•˜๊ณ  ๋กœ๋˜ ๊ฒŒ์ž„์„ ์ข…๋ฃŒํ•œ๋‹ค. -- ์‚ฌ์šฉ์ž๊ฐ€ ์ž˜๋ชป๋œ ๊ฐ’์„ ์ž…๋ ฅํ•  ๊ฒฝ์šฐ `throw`๋ฌธ์„ ์‚ฌ์šฉํ•ด ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ, "[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 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. -``` - -#### ์‹คํ–‰ ๊ฒฐ๊ณผ ์˜ˆ์‹œ +## ์‹คํ–‰ ์˜ˆ์‹œ ``` ๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”. @@ -157,83 +56,6 @@ npm test --- -## ๐ŸŽฏ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ - -- Node.js 18.17.1 ๋ฒ„์ „์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค. **Node.js 18.17.1์—์„œ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ 0์  ์ฒ˜๋ฆฌํ•œ๋‹ค.** -- ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰์˜ ์‹œ์ž‘์ ์€ `App.js`์˜ `play` ๋ฉ”์„œ๋“œ์ด๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. - -**์˜ˆ์‹œ** - -```javascript -const app = new App(); -app.play(); -``` - -- `package.json`์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๊ณ  ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(jQuery, Lodash ๋“ฑ)๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ˆœ์ˆ˜ Vanilla JS๋กœ๋งŒ ๊ตฌํ˜„ํ•œ๋‹ค. -- [JavaScript ์ฝ”๋“œ ์ปจ๋ฒค์…˜](https://github.com/woowacourse/woowacourse-docs/tree/main/styleguide/javascript)์„ ์ง€ํ‚ค๋ฉด์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ•œ๋‹ค -- ํ”„๋กœ๊ทธ๋žจ ์ข…๋ฃŒ ์‹œ `process.exit()`๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค. -- ํ”„๋กœ๊ทธ๋žจ ๊ตฌํ˜„์ด ์™„๋ฃŒ๋˜๋ฉด `ApplicationTest`์˜ ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ•ด์•ผ ํ•œ๋‹ค. **ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ•  ๊ฒฝ์šฐ 0์  ์ฒ˜๋ฆฌํ•œ๋‹ค.** -- ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ์—์„œ ๋‹ฌ๋ฆฌ ๋ช…์‹œํ•˜์ง€ ์•Š๋Š” ํ•œ ํŒŒ์ผ, ํŒจํ‚ค์ง€ ์ด๋ฆ„์„ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์ด๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค. -- indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ 3์ด ๋„˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. 2๊นŒ์ง€๋งŒ ํ—ˆ์šฉํ•œ๋‹ค. - - ์˜ˆ๋ฅผ ๋“ค์–ด while๋ฌธ ์•ˆ์— if๋ฌธ์ด ์žˆ์œผ๋ฉด ๋“ค์—ฌ์“ฐ๊ธฐ๋Š” 2์ด๋‹ค. - - ํžŒํŠธ: indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ ์ค„์ด๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์€ ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)๋ฅผ ๋ถ„๋ฆฌํ•˜๋ฉด ๋œ๋‹ค. -- ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)๊ฐ€ ํ•œ ๊ฐ€์ง€ ์ผ๋งŒ ํ•˜๋„๋ก ์ตœ๋Œ€ํ•œ ์ž‘๊ฒŒ ๋งŒ๋“ค์–ด๋ผ. -- Jest๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ณธ์ธ์ด ์ •๋ฆฌํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก์ด ์ •์ƒ ๋™์ž‘ํ•จ์„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋กœ ํ™•์ธํ•œ๋‹ค. - -### ์ถ”๊ฐ€๋œ ์š”๊ตฌ ์‚ฌํ•ญ - -- ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)์˜ ๊ธธ์ด๊ฐ€ 15๋ผ์ธ์„ ๋„˜์–ด๊ฐ€์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. - - ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)๊ฐ€ ํ•œ ๊ฐ€์ง€ ์ผ๋งŒ ์ž˜ ํ•˜๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. -- else๋ฅผ ์ง€์–‘ํ•œ๋‹ค. - - ํžŒํŠธ: if ์กฐ๊ฑด์ ˆ์—์„œ ๊ฐ’์„ returnํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด else๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. - - ๋•Œ๋กœ๋Š” if/else, switch๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ๊น”๋”ํ•ด ๋ณด์ผ ์ˆ˜ ์žˆ๋‹ค. ์–ด๋А ๊ฒฝ์šฐ์— ์“ฐ๋Š” ๊ฒƒ์ด ์ ์ ˆํ• ์ง€ ์Šค์Šค๋กœ ๊ณ ๋ฏผํ•ด ๋ณธ๋‹ค. -- ๋„๋ฉ”์ธ ๋กœ์ง์— ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. ๋‹จ, UI(Console.readLineAsync, Console.print) ๋กœ์ง์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š” ์ œ์™ธํ•œ๋‹ค. - - ํ•ต์‹ฌ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š” ์ฝ”๋“œ์™€ UI๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ๋กœ์ง์„ ๊ตฌ๋ถ„ํ•œ๋‹ค. - - ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ์ด ์ต์ˆ™ํ•˜์ง€ ์•Š๋‹ค๋ฉด `__tests__/LottoTest.js`๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ํ•™์Šตํ•œ ํ›„ ํ…Œ์ŠคํŠธ๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค. - -### ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ - -- `@woowacourse/mission-utils`์—์„œ ์ œ๊ณตํ•˜๋Š” `Random` ๋ฐ `Console` API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. - - Random ๊ฐ’ ์ถ”์ถœ์€ `Random.pickUniqueNumbersInRange()`๋ฅผ ํ™œ์šฉํ•œ๋‹ค. - - ์‚ฌ์šฉ์ž์˜ ๊ฐ’์„ ์ž…๋ ฅ ๋ฐ›๊ณ  ์ถœ๋ ฅํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” `Console.readLineAsync`, `Console.print`๋ฅผ ํ™œ์šฉํ•œ๋‹ค. - -#### ์‚ฌ์šฉ ์˜ˆ์‹œ - -```javascript -MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6); ``` -### Lotto ํด๋ž˜์Šค - -- ์ œ๊ณต๋œ `Lotto` ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•ด ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. -- `numbers`์˜ `#` prefix๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค. -- `Lotto`์— ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†๋‹ค. - -```javascript -class Lotto { - #numbers; - - constructor(numbers) { - this.#validate(numbers); - this.#numbers = numbers; - } - - #validate(numbers) { - if (numbers.length !== 6) { - throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 6๊ฐœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); - } - } - - // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ -} ``` - ---- - -## โœ๏ธ ๊ณผ์ œ ์ง„ํ–‰ ์š”๊ตฌ ์‚ฌํ•ญ - -- ๋ฏธ์…˜์€ [javascript-lotto-6](https://github.com/woowacourse-precourse/javascript-lotto-6/) ์ €์žฅ์†Œ๋ฅผ Fork & Cloneํ•ด ์‹œ์ž‘ํ•œ๋‹ค. -- **๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „ `docs/README.md`์— ๊ตฌํ˜„ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก์„ ์ •๋ฆฌ**ํ•ด ์ถ”๊ฐ€ํ•œ๋‹ค. -- **Git์˜ ์ปค๋ฐ‹ ๋‹จ์œ„๋Š” ์•ž ๋‹จ๊ณ„์—์„œ `docs/README.md`์— ์ •๋ฆฌํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก ๋‹จ์œ„**๋กœ ์ถ”๊ฐ€ํ•œ๋‹ค. - - [์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ ์ปจ๋ฒค์…˜](https://gist.github.com/stephenparish/9941e89d80e2bc58a153) ๊ฐ€์ด๋“œ๋ฅผ ์ฐธ๊ณ ํ•ด ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋ฅผ ์ž‘์„ฑํ•œ๋‹ค. -- ๊ณผ์ œ ์ง„ํ–‰ ๋ฐ ์ œ์ถœ ๋ฐฉ๋ฒ•์€ [ํ”„๋ฆฌ์ฝ”์Šค ๊ณผ์ œ ์ œ์ถœ](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•œ๋‹ค. diff --git a/__tests__/ApplicationTest.js b/__tests__/ApplicationTest.js index 227bd03864..c82e1f5f34 100644 --- a/__tests__/ApplicationTest.js +++ b/__tests__/ApplicationTest.js @@ -28,7 +28,7 @@ const runException = async (input) => { // given const logSpy = getLogSpy(); - const RANDOM_NUMBERS_TO_END = [1,2,3,4,5,6]; + 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]); @@ -40,12 +40,12 @@ const runException = async (input) => { // then expect(logSpy).toHaveBeenCalledWith(expect.stringContaining("[ERROR]")); -} +}; describe("๋กœ๋˜ ํ…Œ์ŠคํŠธ", () => { beforeEach(() => { jest.restoreAllMocks(); - }) + }); test("๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ", async () => { // given @@ -95,4 +95,3 @@ describe("๋กœ๋˜ ํ…Œ์ŠคํŠธ", () => { await runException("1000j"); }); }); - diff --git a/__tests__/LottoTest.js b/__tests__/LottoTest.js index 97bd457659..c8178db14c 100644 --- a/__tests__/LottoTest.js +++ b/__tests__/LottoTest.js @@ -15,4 +15,9 @@ describe("๋กœ๋˜ ํด๋ž˜์Šค ํ…Œ์ŠคํŠธ", () => { }); // ์•„๋ž˜์— ์ถ”๊ฐ€ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ ๊ฐ€๋Šฅ + // test("๋กœ๋˜๊ฐ€ 3๊ฐœ ์ผ์น˜ํ•˜๋ฉด checkWinningCount๊ฐ€ 3์„ ๋ฐ˜ํ™˜", () => { + // expect(() => { + // new Lotto([1, 2, 3, 4, 5, 6]).checkWinningCount([1, 2, 3, 10, 11, 12]); + // }).toBe(3); + // }); }); diff --git a/src/App.js b/src/App.js index c38b30d5b2..c83f1a44c9 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,142 @@ +import { MissionUtils } from "@woowacourse/mission-utils"; +import Lotto from "./Lotto.js"; + class App { - async play() {} + async play() { + //๊ตฌ์ž… ๊ธˆ์•ก ์ž…๋ ฅ๋ฐ›๋Š” ํ•จ์ˆ˜ + async function getUserCostInput() { + const isNumber = (pVal) => { + if (isEmpty(pVal)) { + return false; + } + return !isNaN(pVal); + }; + MissionUtils.Console.print("๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."); + const totalCost = await MissionUtils.Console.readLineAsync(""); + + // ๊ตฌ์ž… ๊ธˆ์•ก ์˜ˆ์™ธ ์ฒ˜๋ฆฌ - 1) ์ˆซ์ž๊ฐ€ ์•„๋‹ ๋•Œ + + if (!Number(totalCost)) { + throw new Error("[ERROR] ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } + + //๊ตฌ์ž… ๊ธˆ์•ก ์˜ˆ์™ธ ์ฒ˜๋ฆฌ - 2) 1000์› ๋‹จ์œ„๊ฐ€ ์•„๋‹ ๋•Œ + if (Number(totalCost) % 1000 !== 0) { + throw new Error("[ERROR] 1000์› ๋‹จ์œ„ ๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } + return totalCost; + } + + // ๊ตฌ๋งค ๊ฐœ์ˆ˜ ๋งŒํผ ์ถ”์ฒจ ๋ฒˆํ˜ธ ์ƒ์„ฑ ํ•จ์ˆ˜ + function makeNewLotto(boughtLottoCount) { + const totalLottoNumList = []; + for (let i = 0; i < boughtLottoCount; i++) { + const nowLottoNumList = MissionUtils.Random.pickUniqueNumbersInRange( + 1, + 45, + 6 + ); + totalLottoNumList.push(nowLottoNumList); + } + return totalLottoNumList; + } + + //๋กœ๋˜ ์ถœ๋ ฅ ํ•จ์ˆ˜ + function printNewLotto(boughtLottoCount, totalLottoNumList) { + MissionUtils.Console.print(`${boughtLottoCount}๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.`); + totalLottoNumList.forEach((lotto) => + MissionUtils.Console.print(`[${lotto.join(", ")}]`) + ); + } + + // ๋‹น์ฒจ ๋ฒˆํ˜ธ ์ž…๋ ฅ ๋ฐ›๋Š” ํ•จ์ˆ˜ + async function getUserWinningNumInput() { + MissionUtils.Console.print("๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."); + const winnigNum = await MissionUtils.Console.readLineAsync(""); + const winningNumList = winnigNum.split(","); + + return winningNumList; + } + + // ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์ž…๋ ฅ ๋ฐ›๋Š” ํ•จ์ˆ˜ + async function getUserBonusNumInput() { + MissionUtils.Console.print("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."); + const bonusNum = await MissionUtils.Console.readLineAsync(""); + return bonusNum; + } + + // ๋‹น์ฒจ ๊ฐœ์ˆ˜ ๋ฐ ๊ธˆ์•ก ๊ตฌํ•˜๋Š” ํ•จ์ˆ˜ + function calcTotalWinningCount( + boughtLottoCount, + totalLottoNumList, + winningNumList + ) { + const totalWinningCount = [0, 0, 0, 0, 0, 0, 0, 0]; + let totalWinningMoney = 0; + + for (let j = 0; j < boughtLottoCount; j++) { + let lotto = new Lotto(totalLottoNumList[j]); + + let tempWinningNum = lotto.checkWinningCount(winningNumList); + let tempIsBonusTrue = lotto.isBonusTrue(bonusNum); + let tempGetMoney = lotto.calcGetMoney(tempWinningNum, tempIsBonusTrue); + totalWinningMoney += tempGetMoney; + if (tempWinningNum === 5) { + //5๊ฐœ + ๋ณด๋„ˆ์Šค ๋งž์ถ˜ ๊ฒฝ์šฐ 7๋ฒˆ ์ธ๋ฑ์Šค์— ์ €์žฅ + if (tempIsBonusTrue) { + totalWinningCount[7] += 1; + } + } + totalWinningCount[tempWinningNum] += 1; + } + return [totalWinningCount, totalWinningMoney]; + } + + //๋‹น์ฒจ ๊ฐœ์ˆ˜ ์ถœ๋ ฅ + function printTotalNumber(totalWinningCount) { + MissionUtils.Console.print(`๋‹น์ฒจ ํ†ต๊ณ„`); + MissionUtils.Console.print(`---`); + MissionUtils.Console.print( + `3๊ฐœ ์ผ์น˜ (5,000์›) - ${totalWinningCount[3]}๊ฐœ` + ); + MissionUtils.Console.print( + `4๊ฐœ ์ผ์น˜ (50,000์›) - ${totalWinningCount[4]}๊ฐœ` + ); + MissionUtils.Console.print( + `5๊ฐœ ์ผ์น˜ (1,500,000์›) - ${totalWinningCount[5]}๊ฐœ` + ); + MissionUtils.Console.print( + `5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ${totalWinningCount[7]}๊ฐœ` + ); + MissionUtils.Console.print( + `6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ${totalWinningCount[6]}๊ฐœ` + ); + } + + //๋‹น์ฒจ ์ˆ˜์ต๋ฅ  ๊ณ„์‚ฐ + function calcTotalProfitPercent(totalWinningMoney, totalCost) { + const totalProfitPercent = (totalWinningMoney / totalCost) * 100; + const temp = Number((Math.abs(totalProfitPercent) * 100).toPrecision(15)); + return (Math.round(temp) / 100) * Math.sign(totalProfitPercent); + } + + const totalCost = await getUserCostInput(); + const boughtLottoCount = totalCost / 1000; + const totalLottoNumList = makeNewLotto(boughtLottoCount); + printNewLotto(boughtLottoCount, totalLottoNumList); + const winningNumList = await getUserWinningNumInput(); + const bonusNum = await getUserBonusNumInput(); + const [totalWinningCount, totalWinningMoney] = calcTotalWinningCount( + boughtLottoCount, + totalLottoNumList, + winningNumList + ); + printTotalNumber(totalWinningCount); + const totalProfit = calcTotalProfitPercent(totalWinningMoney, totalCost); + + //๋‹น์ฒจ ์ˆ˜์ต๋ฅ  ์ถœ๋ ฅ + MissionUtils.Console.print(`์ด ์ˆ˜์ต๋ฅ ์€ ${totalProfit}%์ž…๋‹ˆ๋‹ค.`); + } } export default App; diff --git a/src/Lotto.js b/src/Lotto.js index cb0b1527e9..78c8c79a65 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -1,8 +1,11 @@ -class Lotto { +import { MissionUtils } from "@woowacourse/mission-utils"; + +export class Lotto { #numbers; constructor(numbers) { this.#validate(numbers); + this.#numbers = numbers; } @@ -10,9 +13,56 @@ class Lotto { if (numbers.length !== 6) { throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 6๊ฐœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); } + for (let n = 0; n < numbers.length; n++) { + for (let m = n + 1; m < numbers.length; m++) { + if (numbers[m] === numbers[n]) { + throw new Error("[ERROR] ์ค‘๋ณต๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ์•ˆ๋ฉ๋‹ˆ๋‹ค."); + } + } + } + } + + //๋งž์ถ˜ ๊ฐœ์ˆ˜ ์นด์šดํŠธ + checkWinningCount(winningNumList) { + let coincideNumCount = 0; + for (var i = 0; i < 6; i++) { + winningNumList.forEach((num) => { + if (num === String(this.#numbers[i])) { + coincideNumCount += 1; + } + }); + } + return coincideNumCount; + } + + // ๋ณด๋„ˆ์Šค ์ˆซ์ž ๋งž์ท„๋Š”์ง€ ์—ฌ๋ถ€ ํ™•์ธ + isBonusTrue(numbers, bonusNum) { + if (numbers.includes(String(bonusNum))) { + return true; + } + return false; } - // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ + //๋งž์ถ˜ ์ˆซ์ž์— ๋”ฐ๋ฅธ ๋‹น์ฒจ ๊ธˆ์•ก ๊ณ„์‚ฐ + calcGetMoney(coincideNumCount, bonusTrue) { + if (coincideNumCount === 3) { + return 5000; + } + + if (coincideNumCount === 4) { + return 50000; + } + + if (coincideNumCount === 5) { + if (!bonusTrue) return 1500000; + return 30000000; + } + + if (coincideNumCount === 6) { + return 2000000000; + } + return 0; + } } export default Lotto;