diff --git a/README.md b/README.md index 6d53050121a..8476e079bdd 100644 --- a/README.md +++ b/README.md @@ -1,123 +1,27 @@ -# ๋ฏธ์…˜ - ๋กœ๋˜ - -## ๐Ÿ” ์ง„ํ–‰ ๋ฐฉ์‹ - -- ๋ฏธ์…˜์€ **๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ, ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ, ๊ณผ์ œ ์ง„ํ–‰ ์š”๊ตฌ ์‚ฌํ•ญ** ์„ธ ๊ฐ€์ง€๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. -- ์„ธ ๊ฐœ์˜ ์š”๊ตฌ ์‚ฌํ•ญ์„ ๋งŒ์กฑํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•œ๋‹ค. ํŠนํžˆ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „์— ๊ธฐ๋Šฅ ๋ชฉ๋ก์„ ๋งŒ๋“ค๊ณ , ๊ธฐ๋Šฅ ๋‹จ์œ„๋กœ ์ปค๋ฐ‹ ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰ํ•œ๋‹ค. -- ๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ์— ๊ธฐ์žฌ๋˜์ง€ ์•Š์€ ๋‚ด์šฉ์€ ์Šค์Šค๋กœ ํŒ๋‹จํ•˜์—ฌ ๊ตฌํ˜„ํ•œ๋‹ค. - -## ๐Ÿ“ฎ ๋ฏธ์…˜ ์ œ์ถœ ๋ฐฉ๋ฒ• - -- ๋ฏธ์…˜ ๊ตฌํ˜„์„ ์™„๋ฃŒํ•œ ํ›„ 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์  ๋ฐฉ์ง€ - -- ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ๋ชจ๋‘ ์ •์ƒ์ ์œผ๋กœ ํ–ˆ๋”๋ผ๋„ **์š”๊ตฌ ์‚ฌํ•ญ์— ๋ช…์‹œ๋œ ์ถœ๋ ฅ๊ฐ’ ํ˜•์‹์„ ์ง€ํ‚ค์ง€ ์•Š์„ ๊ฒฝ์šฐ 0์ ์œผ๋กœ ์ฒ˜๋ฆฌ**ํ•œ๋‹ค. -- ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ์™„๋ฃŒํ•œ ๋’ค ์•„๋ž˜ ๊ฐ€์ด๋“œ์— ๋”ฐ๋ผ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ–ˆ์„ ๋•Œ ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. -- **ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ•  ๊ฒฝ์šฐ 0์ ์œผ๋กœ ์ฒ˜๋ฆฌ**๋˜๋ฏ€๋กœ, ๋ฐ˜๋“œ์‹œ ํ™•์ธ ํ›„ ์ œ์ถœํ•œ๋‹ค. - -### ํ…Œ์ŠคํŠธ ์‹คํ–‰ ๊ฐ€์ด๋“œ - -- ํ„ฐ๋ฏธ๋„์—์„œ `java -version`์„ ์‹คํ–‰ํ•˜์—ฌ Java ๋ฒ„์ „์ด 17์ธ์ง€ ํ™•์ธํ•œ๋‹ค. - Eclipse ๋˜๋Š” IntelliJ IDEA์™€ ๊ฐ™์€ IDE์—์„œ Java 17๋กœ ์‹คํ–‰๋˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. -- ํ„ฐ๋ฏธ๋„์—์„œ Mac ๋˜๋Š” Linux ์‚ฌ์šฉ์ž์˜ ๊ฒฝ์šฐ `./gradlew clean test` ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๊ณ , - Windows ์‚ฌ์šฉ์ž์˜ ๊ฒฝ์šฐ `gradlew.bat clean test` ๋˜๋Š” `./gradlew.bat clean test` ๋ช…๋ น์„ ์‹คํ–‰ํ•  ๋•Œ ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ์•„๋ž˜์™€ ๊ฐ™์ด ํ†ต๊ณผํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. - -``` -BUILD SUCCESSFUL in 0s -``` +# ๐Ÿ’ป ์šฐํ…Œ์ฝ” 8๊ธฐ ์ตœ์ข… - ๋กœ๋˜ +Console์„ ์ด์šฉํ•˜์—ฌ ๋กœ๋˜ ์ƒ์„ฑ๊ธฐ๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค. +๊ตฌ์ž… ๊ธˆ์•ก์— ๋งž์ถฐ ๋กœ๋˜๋ฅผ ๋ฐœํ–‰ํ•˜๊ณ , ๋‹น์ฒจ ๋‚ด์—ญ์„ ์ถœ๋ ฅํ•œ๋‹ค. --- -## ๐Ÿš€ ๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ - -๋กœ๋˜ ๊ฒŒ์ž„ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. ๋กœ๋˜ ๊ฒŒ์ž„์€ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ทœ์น™์œผ๋กœ ์ง„ํ–‰๋œ๋‹ค. - -``` -- ๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ์ˆซ์ž ๋ฒ”์œ„๋Š” 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์›์ด๋‹ค. -- ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค. -- ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ๋งคํ•œ ๋กœ๋˜ ๋ฒˆํ˜ธ์™€ ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ๋น„๊ตํ•˜์—ฌ ๋‹น์ฒจ ๋‚ด์—ญ ๋ฐ ์ˆ˜์ต๋ฅ ์„ ์ถœ๋ ฅํ•˜๊ณ  ๋กœ๋˜ ๊ฒŒ์ž„์„ ์ข…๋ฃŒํ•œ๋‹ค. -- ์‚ฌ์šฉ์ž๊ฐ€ ์ž˜๋ชป๋œ ๊ฐ’์„ ์ž…๋ ฅํ•  ๊ฒฝ์šฐ `IllegalArgumentException`๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ , "[ERROR]"๋กœ ์‹œ์ž‘ํ•˜๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅ ํ›„ ๊ทธ ๋ถ€๋ถ„๋ถ€ํ„ฐ ์ž…๋ ฅ์„ ๋‹ค์‹œ ๋ฐ›๋Š”๋‹ค. - - `Exception`์ด ์•„๋‹Œ `IllegalArgumentException`, `IllegalStateException` ๋“ฑ๊ณผ ๊ฐ™์€ ๋ช…ํ™•ํ•œ ์œ ํ˜•์„ ์ฒ˜๋ฆฌํ•œ๋‹ค. - -### ์ž…์ถœ๋ ฅ ์š”๊ตฌ ์‚ฌํ•ญ - -#### ์ž…๋ ฅ - -- ๋กœ๋˜ ๊ตฌ์ž… ๊ธˆ์•ก์„ ์ž…๋ ฅ ๋ฐ›๋Š”๋‹ค. ๊ตฌ์ž… ๊ธˆ์•ก์€ 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%) +1. ๋กœ๋˜ ๊ตฌ์ž… ๊ธˆ์•ก์„ ์ž…๋ ฅ ๋ฐ›๋Š”๋‹ค. ๊ตฌ์ž… ๊ธˆ์•ก์€ 1,000์› ๋‹จ์œ„๋กœ ์ž…๋ ฅ ๋ฐ›์œผ๋ฉฐ 1,000์›์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•œ๋‹ค. +2. ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ ๋ฐ›๋Š”๋‹ค. ๋ฒˆํ˜ธ๋Š” ์‰ผํ‘œ(,)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค. +3. ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ ๋ฐ›๋Š”๋‹ค. -``` -์ด ์ˆ˜์ต๋ฅ ์€ 62.5%์ž…๋‹ˆ๋‹ค. -``` +### โ–ซ ์ถœ๋ ฅ -- ์˜ˆ์™ธ ์ƒํ™ฉ ์‹œ ์—๋Ÿฌ ๋ฌธ๊ตฌ๋ฅผ ์ถœ๋ ฅํ•ด์•ผ ํ•œ๋‹ค. ๋‹จ, ์—๋Ÿฌ ๋ฌธ๊ตฌ๋Š” "[ERROR]"๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค. +1. ๋ฐœํ–‰ํ•œ ๋กœ๋˜ ์ˆ˜๋Ÿ‰ ๋ฐ ๋ฒˆํ˜ธ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ๋ณด์—ฌ์ค€๋‹ค. + ) +2. ๋‹น์ฒจ ๋‚ด์—ญ์„ ์ถœ๋ ฅํ•œ๋‹ค. +3. ์ˆ˜์ต๋ฅ ์€ ์†Œ์ˆ˜์  ๋‘˜์งธ ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผํ•œ๋‹ค. (ex. 100.0%, 51.5%, 1,000,000.0%) +4. ์˜ˆ์™ธ ์ƒํ™ฉ ์‹œ ์—๋Ÿฌ ๋ฌธ๊ตฌ๋ฅผ ์ถœ๋ ฅํ•ด์•ผ ํ•œ๋‹ค. ๋‹จ, ์—๋Ÿฌ ๋ฌธ๊ตฌ๋Š” "[ERROR]"๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค. -``` -[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. -``` -#### ์‹คํ–‰ ๊ฒฐ๊ณผ ์˜ˆ์‹œ +### โ–ซ ์‹คํ–‰ ์˜ˆ์‹œ ``` ๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”. @@ -148,82 +52,55 @@ BUILD SUCCESSFUL in 0s 6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - 0๊ฐœ ์ด ์ˆ˜์ต๋ฅ ์€ 62.5%์ž…๋‹ˆ๋‹ค. ``` - ---- - -## ๐ŸŽฏ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ - -- JDK 17 ๋ฒ„์ „์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค. **JDK 17์—์„œ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ 0์  ์ฒ˜๋ฆฌํ•œ๋‹ค.** -- ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰์˜ ์‹œ์ž‘์ ์€ `Application`์˜ `main()`์ด๋‹ค. -- `build.gradle` ํŒŒ์ผ์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๊ณ , ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. -- [Java ์ฝ”๋“œ ์ปจ๋ฒค์…˜](https://github.com/woowacourse/woowacourse-docs/tree/master/styleguide/java) ๊ฐ€์ด๋“œ๋ฅผ ์ค€์ˆ˜ํ•˜๋ฉฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•œ๋‹ค. -- ํ”„๋กœ๊ทธ๋žจ ์ข…๋ฃŒ ์‹œ `System.exit()`๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค. -- ํ”„๋กœ๊ทธ๋žจ ๊ตฌํ˜„์ด ์™„๋ฃŒ๋˜๋ฉด `ApplicationTest`์˜ ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ•ด์•ผ ํ•œ๋‹ค. **ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ•  ๊ฒฝ์šฐ 0์  ์ฒ˜๋ฆฌํ•œ๋‹ค.** -- ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ์—์„œ ๋‹ฌ๋ฆฌ ๋ช…์‹œํ•˜์ง€ ์•Š๋Š” ํ•œ ํŒŒ์ผ, ํŒจํ‚ค์ง€ ์ด๋ฆ„์„ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์ด๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค. -- indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ 3์ด ๋„˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. 2๊นŒ์ง€๋งŒ ํ—ˆ์šฉํ•œ๋‹ค. - - ์˜ˆ๋ฅผ ๋“ค์–ด while๋ฌธ ์•ˆ์— if๋ฌธ์ด ์žˆ์œผ๋ฉด ๋“ค์—ฌ์“ฐ๊ธฐ๋Š” 2์ด๋‹ค. - - ํžŒํŠธ: indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ ์ค„์ด๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์€ ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)๋ฅผ ๋ถ„๋ฆฌํ•˜๋ฉด ๋œ๋‹ค. -- 3ํ•ญ ์—ฐ์‚ฐ์ž๋ฅผ ์“ฐ์ง€ ์•Š๋Š”๋‹ค. -- ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)๊ฐ€ ํ•œ ๊ฐ€์ง€ ์ผ๋งŒ ํ•˜๋„๋ก ์ตœ๋Œ€ํ•œ ์ž‘๊ฒŒ ๋งŒ๋“ค์–ด๋ผ. -- JUnit 5์™€ AssertJ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ณธ์ธ์ด ์ •๋ฆฌํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก์ด ์ •์ƒ ๋™์ž‘ํ•จ์„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋กœ ํ™•์ธํ•œ๋‹ค. - -### ์ถ”๊ฐ€๋œ ์š”๊ตฌ ์‚ฌํ•ญ - -- ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)์˜ ๊ธธ์ด๊ฐ€ 15๋ผ์ธ์„ ๋„˜์–ด๊ฐ€์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. - - ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)๊ฐ€ ํ•œ ๊ฐ€์ง€ ์ผ๋งŒ ์ž˜ ํ•˜๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. -- else ์˜ˆ์•ฝ์–ด๋ฅผ ์“ฐ์ง€ ์•Š๋Š”๋‹ค. - - ํžŒํŠธ: if ์กฐ๊ฑด์ ˆ์—์„œ ๊ฐ’์„ returnํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด else๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. - - else๋ฅผ ์“ฐ์ง€ ๋ง๋ผ๊ณ  ํ•˜๋‹ˆ switch/case๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”๋ฐ switch/case๋„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. -- Java Enum์„ ์ ์šฉํ•œ๋‹ค. -- ๋„๋ฉ”์ธ ๋กœ์ง์— ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. ๋‹จ, UI(System.out, System.in, Scanner) ๋กœ์ง์€ ์ œ์™ธํ•œ๋‹ค. - - ํ•ต์‹ฌ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š” ์ฝ”๋“œ์™€ UI๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ๋กœ์ง์„ ๋ถ„๋ฆฌํ•ด ๊ตฌํ˜„ํ•œ๋‹ค. - - ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ์ด ์ต์ˆ™ํ•˜์ง€ ์•Š๋‹ค๋ฉด `test/java/lotto/LottoTest`๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ํ•™์Šตํ•œ ํ›„ ํ…Œ์ŠคํŠธ๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค. - -### ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ - -- `camp.nextstep.edu.missionutils`์—์„œ ์ œ๊ณตํ•˜๋Š” `Randoms` ๋ฐ `Console` - API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. - - Random ๊ฐ’ ์ถ”์ถœ์€ `camp.nextstep.edu.missionutils.Randoms`์˜ `pickUniqueNumbersInRange()`๋ฅผ ํ™œ์šฉํ•œ๋‹ค. - - ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•˜๋Š” ๊ฐ’์€ `camp.nextstep.edu.missionutils.Console`์˜ `readLine()`์„ ํ™œ์šฉํ•œ๋‹ค. - -#### ์‚ฌ์šฉ ์˜ˆ์‹œ - -```java -List numbers = Randoms.pickUniqueNumbersInRange(1, 45, 6); -``` - -### Lotto ํด๋ž˜์Šค - -- ์ œ๊ณต๋œ `Lotto` ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•ด ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. -- `numbers`์˜ ์ ‘๊ทผ ์ œ์–ด์ž์ธ private์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค. -- `Lotto`์— ํ•„๋“œ(์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜)๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†๋‹ค. -- `Lotto`์˜ ํŒจํ‚ค์ง€ ๋ณ€๊ฒฝ์€ ๊ฐ€๋Šฅํ•˜๋‹ค. - -```java -public class Lotto { - private final List numbers; - - public Lotto(List numbers) { - validate(numbers); - this.numbers = numbers; - } - - private void validate(List numbers) { - if (numbers.size() != 6) { - throw new IllegalArgumentException(); - } - } - - // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ -} -``` - --- -## โœ๏ธ ๊ณผ์ œ ์ง„ํ–‰ ์š”๊ตฌ ์‚ฌํ•ญ - -- ๋ฏธ์…˜์€ [java-lotto-6](https://github.com/woowacourse-precourse/java-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) ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•œ๋‹ค. +## ๐Ÿ“„๊ธฐ๋Šฅ ๊ตฌํ˜„ ๋ชฉ๋ก + +### 1) ์ž…๋ ฅ ํ๋ฆ„ + +- [x] InputView, OutputView ์ž…์ถœ๋ ฅ ๋ผˆ๋Œ€ ๊ตฌ์„ฑ +- [x] ๊ตฌ์ž…๊ธˆ์•ก ์ž…๋ ฅ๋ฐ›์•„ ํŒŒ์‹ฑ +- [x] ๋‹น์ฒจ๋ฒˆํ˜ธ ์ž…๋ ฅ๋ฐ›์•„ ํŒŒ์‹ฑ +- [x] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์ž…๋ ฅ๋ฐ›์•„ ํŒŒ์‹ฑ + +### 2) ์ฃผ์š” ๊ธฐ๋Šฅ +- [x] Lottos ๋„๋ฉ”์ธ ๊ตฌํ˜„ +- [x] LottoGenerator ๊ตฌํ˜„ +- [x] Lotto ๋„๋ฉ”์ธ ๊ตฌํ˜„ +- [x] Rank(Enum) ๊ตฌํ˜„ +- [x] WinningNumbers ๋„๋ฉ”์ธ ๊ตฌํ˜„ +- [x] ๋กœ๋˜ ์ƒ์„ฑ ๊ธฐ๋Šฅ ๊ตฌํ˜„ +- [x] WinCountCalculator ๊ตฌํ˜„(๋กœ๋˜ ๋‹น์ฒจ ํšŸ์ˆ˜ ๊ณ„์‚ฐ) +- [x] ๋กœ๋˜ ๋‹น์ฒจ ๋‚ด์—ญ ๊ธฐ๋Šฅ ๊ตฌํ˜„ +- [x] ๋กœ๋˜ ์ˆ˜์ต๋ฅ  ๊ณ„์‚ฐ ๊ธฐ๋Šฅ ๊ตฌํ˜„ + +### 3) ์˜ˆ์™ธ ๋ฐ ์ฃผ์˜์‚ฌํ•ญ ์ฒดํฌ +- [x] ๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ์ˆซ์ž ๋ฒ”์œ„๋Š” 1~45๊นŒ์ง€์ด๋‹ค. +- [x] 1๊ฐœ์˜ ๋กœ๋˜๋ฅผ ๋ฐœํ–‰ํ•  ๋•Œ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” 6๊ฐœ์˜ ์ˆซ์ž๋ฅผ ๋ฝ‘๋Š”๋‹ค. +- [x] ๋กœ๋˜ ๊ตฌ์ž… ๊ธˆ์•ก์„ ์ž…๋ ฅํ•˜๋ฉด ๊ตฌ์ž… ๊ธˆ์•ก์— ํ•ด๋‹นํ•˜๋Š” ๋งŒํผ ๋กœ๋˜๋ฅผ ๋ฐœํ–‰ํ•ด์•ผ ํ•œ๋‹ค. +- [x] ๋กœ๋˜ 1์žฅ์˜ ๊ฐ€๊ฒฉ์€ 1,000์›์ด๋‹ค. +- [x] ์‚ฌ์šฉ์ž๊ฐ€ ์ž˜๋ชป๋œ ๊ฐ’์„ ์ž…๋ ฅํ•  ๊ฒฝ์šฐ IllegalArgumentException๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ , "[ERROR]"๋กœ ์‹œ์ž‘ํ•˜๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅ ํ›„ ๊ทธ ๋ถ€๋ถ„๋ถ€ํ„ฐ ์ž…๋ ฅ์„ ๋‹ค์‹œ ๋ฐ›๋Š”๋‹ค. +- [x] ๊ตฌ์ž… ๊ธˆ์•ก์€ 1,000์› ๋‹จ์œ„๋กœ ์ž…๋ ฅ ๋ฐ›์œผ๋ฉฐ 1,000์›์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•œ๋‹ค. +- [x] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ๋ณด์—ฌ์ค€๋‹ค. +- [x] ์ˆ˜์ต๋ฅ ์€ ์†Œ์ˆ˜์  ๋‘˜์งธ ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผํ•œ๋‹ค. +- [x] ์—๋Ÿฌ ๋ฌธ๊ตฌ๋Š” "[ERROR]"๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค. +- [x] Java Enum์„ ์ ์šฉํ•œ๋‹ค. +- [ ] ๋„๋ฉ”์ธ ๋กœ์ง์— ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. +- [x] Randoms ๋ฐ Console API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. +- [x] ์ œ๊ณต๋œ Lotto ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•ด ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. +- [x] numbers์˜ ์ ‘๊ทผ ์ œ์–ด์ž์ธ private์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค. +- [x] Lotto์— ํ•„๋“œ(์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜)๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†๋‹ค. +### 4) ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ ์ฒดํฌ +- [x] ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ์—์„œ ๋‹ฌ๋ฆฌ ๋ช…์‹œํ•˜์ง€ ์•Š๋Š” ํ•œ ํŒŒ์ผ, ํŒจํ‚ค์ง€ ์ด๋ฆ„์„ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์ด๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค. +- [x] indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ 3์ด ๋„˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. 2๊นŒ์ง€๋งŒ ํ—ˆ์šฉํ•œ๋‹ค. +- [x] 3ํ•ญ ์—ฐ์‚ฐ์ž๋ฅผ ์“ฐ์ง€ ์•Š๋Š”๋‹ค. + + +### 5) ๋ฆฌํŒฉํ† ๋ง +- [x] ์ฒดํฌ์™„๋ฃŒ + +### 6) ํ…Œ์ŠคํŠธ ๊ธฐ๋Šฅ ๋ชฉ๋ก ์ฒดํฌ +- [x] ๊ธฐ๋Šฅํ…Œ์ŠคํŠธ: ์ „์ฒด ๊ธฐ๋Šฅ ๊ตฌํ˜„: ("8000", "1,2,3,4,5,6", "7") ์ž…๋ ฅ ์‹œ ์‹คํ–‰์˜ˆ์‹œ์— ๋งž๊ฒŒ ์ถœ๋ ฅ +- [x] ์˜ˆ์™ธํ…Œ์ŠคํŠธ: ๊ตฌ์ž…๊ธˆ์•ก("1000j") ์ž…๋ ฅ ์‹œ ์—๋Ÿฌ๋ฐœ์ƒ +- [x] ์—๋Ÿฌ ํ…Œ์ŠคํŠธ: ๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ๊ฐœ์ˆ˜๊ฐ€ 6๊ฐœ๊ฐ€ ๋„˜์–ด๊ฐ€๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒ +- [x] ์—๋Ÿฌ ํ…Œ์ŠคํŠธ: ๋กœ๋˜ ๋ฒˆํ˜ธ์— ์ค‘๋ณต๋œ ์ˆซ์ž๊ฐ€ ์žˆ์œผ๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒ \ No newline at end of file diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d190922ba44..33ddf75cacd 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,7 +1,9 @@ package lotto; +import lotto.controller.MainController; + public class Application { public static void main(String[] args) { - // TODO: ํ”„๋กœ๊ทธ๋žจ ๊ตฌํ˜„ + new MainController().run(); } } diff --git a/src/main/java/lotto/Lotto.java b/src/main/java/lotto/Lotto.java deleted file mode 100644 index 519793d1f73..00000000000 --- a/src/main/java/lotto/Lotto.java +++ /dev/null @@ -1,20 +0,0 @@ -package lotto; - -import java.util.List; - -public class Lotto { - private final List numbers; - - public Lotto(List numbers) { - validate(numbers); - this.numbers = numbers; - } - - private void validate(List numbers) { - if (numbers.size() != 6) { - throw new IllegalArgumentException(); - } - } - - // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ -} diff --git a/src/main/java/lotto/controller/MainController.java b/src/main/java/lotto/controller/MainController.java new file mode 100644 index 00000000000..91384f1efbb --- /dev/null +++ b/src/main/java/lotto/controller/MainController.java @@ -0,0 +1,61 @@ +package lotto.controller; + +import lotto.domain.*; +import lotto.view.InputView; +import lotto.view.OutputView; + +import java.util.List; +import java.util.Map; + +public class MainController { + + private final InputView inputView = new InputView(); + private final OutputView outputView = new OutputView(); + private final LottoGenerator lottoGenerator = new LottoGenerator(); + private final WinCountCalculator winCountCalculator = new WinCountCalculator(); + private final ProfitRateCalculator profitRateCalculator = new ProfitRateCalculator(); + + + public void run() { + long purchaseAmount = readPurchaseAmountWithRetry(); + Lottos lottos = lottoGenerator.generate(purchaseAmount / 1000); + outputView.printLottos(lottos); + List winning = readWinningNumbersWithRetry(); + int bonusNumber = readBonusNumberWithRetry(); + WinningNumbers winningNumbers = new WinningNumbers(winning, bonusNumber); + Map ranks = winCountCalculator.calculate(lottos, winningNumbers); + outputView.printWinningDetails(ranks); + String profitRate = profitRateCalculator.calculate(ranks, purchaseAmount); + outputView.printProfitRate(profitRate); + } + + private int readPurchaseAmountWithRetry() { + while (true) { + try { + return inputView.readPurchaseAmount(); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + } + } + } + + private List readWinningNumbersWithRetry() { + while (true) { + try { + return inputView.readWinningNumbers(); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + } + } + } + + private int readBonusNumberWithRetry() { + while (true) { + try { + return inputView.readBonusNumber(); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + } + } + } +} diff --git a/src/main/java/lotto/domain/Lotto.java b/src/main/java/lotto/domain/Lotto.java new file mode 100644 index 00000000000..9e5d8b9cf44 --- /dev/null +++ b/src/main/java/lotto/domain/Lotto.java @@ -0,0 +1,44 @@ +package lotto.domain; + +import java.util.*; + +public class Lotto { + private final List numbers; + + public Lotto(List numbers) { + validate(numbers); + this.numbers = toSortedUnmodifiable(numbers); + } + + private void validate(List numbers) { + if (numbers == null) { + throw new IllegalArgumentException("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ ๋ชฉ๋ก์ด null์ผ ์ˆ˜ ์—†๋‹ค."); + } + + if (numbers.size() != 6) { + throw new IllegalArgumentException(); + } + for (Integer n : numbers) { + if (n < 1 || n > 45) { + throw new IllegalArgumentException("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ์ˆซ์ž ๋ฒ”์œ„๋Š” 1~45๊นŒ์ง€์ž…๋‹ˆ๋‹ค."); + } + } + + Set set = new HashSet<>(numbers); + if (set.size() != numbers.size()) { + throw new IllegalArgumentException("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์ค‘๋ณต๋  ์ˆ˜ ์—†๋‹ค."); + } + } + + + private List toSortedUnmodifiable(List numbers) { + List copy = new ArrayList<>(numbers); + Collections.sort(copy); + return Collections.unmodifiableList(copy); + } + + public List getNumbers() { + return numbers; + } + +} diff --git a/src/main/java/lotto/domain/LottoGenerator.java b/src/main/java/lotto/domain/LottoGenerator.java new file mode 100644 index 00000000000..b90e30fc11f --- /dev/null +++ b/src/main/java/lotto/domain/LottoGenerator.java @@ -0,0 +1,18 @@ +package lotto.domain; + +import camp.nextstep.edu.missionutils.Randoms; + +import java.util.ArrayList; +import java.util.List; + +public class LottoGenerator { + public Lottos generate(long count) { + List lottos = new ArrayList<>(); + for (int i = 0; i < count; i++) { + List numbers = Randoms.pickUniqueNumbersInRange(1, 45, 6); + lottos.add(new Lotto(numbers)); + } + return new Lottos(lottos); + } + +} diff --git a/src/main/java/lotto/domain/Lottos.java b/src/main/java/lotto/domain/Lottos.java new file mode 100644 index 00000000000..bf0ba3d0abc --- /dev/null +++ b/src/main/java/lotto/domain/Lottos.java @@ -0,0 +1,20 @@ +package lotto.domain; + +import java.util.List; + +public class Lottos { + public List lottos; + + public Lottos(List lottos) { + this.lottos = lottos; + } + + public List getLottos() { + return lottos; + } + + public int size() { + return lottos.size(); + } + +} diff --git a/src/main/java/lotto/domain/ProfitRateCalculator.java b/src/main/java/lotto/domain/ProfitRateCalculator.java new file mode 100644 index 00000000000..aa62be4a581 --- /dev/null +++ b/src/main/java/lotto/domain/ProfitRateCalculator.java @@ -0,0 +1,29 @@ +package lotto.domain; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Map; + +public class ProfitRateCalculator { + public String calculate(Map ranks, long purchaseAmount) { + long totalPrize = 0; + for (Rank rank : ranks.keySet()) { + totalPrize += (long) ranks.get(rank) * rank.getPrize(); + } + if (purchaseAmount == 0) { + return "0.0%"; + } + + BigDecimal prize = BigDecimal.valueOf(totalPrize); + BigDecimal cost = BigDecimal.valueOf(purchaseAmount); + BigDecimal hundred = BigDecimal.valueOf(100); + + BigDecimal rate = prize + .divide(cost, 10, RoundingMode.HALF_UP) + .multiply(hundred) + .setScale(1, RoundingMode.HALF_UP); + + return rate.toPlainString() + "%"; + } + +} diff --git a/src/main/java/lotto/domain/Rank.java b/src/main/java/lotto/domain/Rank.java new file mode 100644 index 00000000000..6f1eef8a1d0 --- /dev/null +++ b/src/main/java/lotto/domain/Rank.java @@ -0,0 +1,52 @@ +package lotto.domain; + +public enum Rank { + FIRST(6, false, 2_000_000_000L), + SECOND(5, true, 30_000_000L), + THIRD(5, false, 1_500_000L), + FOURTH(4, false, 50_000L), + FIFTH(3, false, 5_000L), + NONE(0, false, 0L); + + final int matchCount; + final boolean isBonus; + final long prize; + + Rank(int matchCount, boolean isBonus, long prize) { + this.matchCount = matchCount; + this.isBonus = isBonus; + this.prize = prize; + } + + public int getMatchCount() { + return matchCount; + } + + public boolean getIsBonus() { + return isBonus; + } + + public long getPrize() { + return prize; + } + + public static Rank of(int matchCount, boolean isBonus) { + if (matchCount == 6) { + return FIRST; + } + if (matchCount == 5 && isBonus) { + return SECOND; + } + if (matchCount == 5) { + return THIRD; + } + if (matchCount == 4) { + return FOURTH; + } + if (matchCount == 3) { + return FIFTH; + } + return NONE; + } + +} diff --git a/src/main/java/lotto/domain/WinCountCalculator.java b/src/main/java/lotto/domain/WinCountCalculator.java new file mode 100644 index 00000000000..634832a740e --- /dev/null +++ b/src/main/java/lotto/domain/WinCountCalculator.java @@ -0,0 +1,24 @@ +package lotto.domain; + +import java.util.*; + +public class WinCountCalculator { + Map ranks; + + public Map calculate(Lottos lottos, WinningNumbers winningNumbers) { + List winning = winningNumbers.getNumbers(); + Map ranks = new EnumMap<>(Rank.class); + + for (Lotto lotto : lottos.getLottos()) { + List lott = lotto.getNumbers(); + Set intersection = new HashSet<>(winning); + intersection.retainAll(lott); + int matchCount = intersection.size(); + boolean isBonus = lott.contains(winningNumbers.getBonusNum()); + Rank rank = Rank.of(matchCount, isBonus); + ranks.put(rank, ranks.getOrDefault(rank, 0) + 1); + } + return ranks; + } + +} diff --git a/src/main/java/lotto/domain/WinningNumbers.java b/src/main/java/lotto/domain/WinningNumbers.java new file mode 100644 index 00000000000..bd1f8faa220 --- /dev/null +++ b/src/main/java/lotto/domain/WinningNumbers.java @@ -0,0 +1,22 @@ +package lotto.domain; + +import java.util.List; + +public class WinningNumbers { + private final List numbers; + private final int bonusNum; + + public WinningNumbers(List numbers, int bonusNum) { + this.numbers = numbers; + this.bonusNum = bonusNum; + } + + public List getNumbers() { + return numbers; + } + + public int getBonusNum() { + return bonusNum; + } + +} diff --git a/src/main/java/lotto/support/parser/BonusNumberParser.java b/src/main/java/lotto/support/parser/BonusNumberParser.java new file mode 100644 index 00000000000..cfebb104d0d --- /dev/null +++ b/src/main/java/lotto/support/parser/BonusNumberParser.java @@ -0,0 +1,40 @@ +package lotto.support.parser; + +public final class BonusNumberParser { + + private BonusNumberParser() { + } + + public static int parse(String input) { + validateNotNull(input); + + String trimmed = input.trim(); + validateNotEmpty(trimmed); + + int bonus; + try { + bonus = Integer.parseInt(trimmed); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("[ERROR] ์ˆซ์ž ํ˜•์‹์ด ์•„๋‹™๋‹ˆ๋‹ค."); + } + if (bonus < 1 || bonus > 45) { + throw new IllegalArgumentException("[ERROR] ๋ณด๋„ˆ์Šค ์ˆซ์ž๋Š” 1์—์„œ 45 ์‚ฌ์ด์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } + return bonus; + } + + + private static void validateNotNull(String input) { + if (input == null) { + throw new IllegalArgumentException("[ERROR] ์ž…๋ ฅ์€ null์ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + } + + private static void validateNotEmpty(String input) { + if (input.isEmpty()) { + throw new IllegalArgumentException("[ERROR] ์ž…๋ ฅ์€ ๋นˆ ๊ฐ’์ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + } + + +} diff --git a/src/main/java/lotto/support/parser/PurchaseAmountParser.java b/src/main/java/lotto/support/parser/PurchaseAmountParser.java new file mode 100644 index 00000000000..69adfee815e --- /dev/null +++ b/src/main/java/lotto/support/parser/PurchaseAmountParser.java @@ -0,0 +1,51 @@ +package lotto.support.parser; + +public final class PurchaseAmountParser { + + private PurchaseAmountParser() { + } + + public static int parse(String input) { + validateNotNull(input); + + String trimmed = input.trim(); + validateNotEmpty(trimmed); + + int amount; + try { + amount = Integer.parseInt(trimmed); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("[ERROR] ์ˆซ์ž ํ˜•์‹์ด ์•„๋‹™๋‹ˆ๋‹ค."); + } + + validateNegative(amount); + validateThousand(amount); + return amount; + + + } + + private static void validateNegative(int amount) { + if (amount < 0) { + throw new IllegalArgumentException("[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์€ ์Œ์ˆ˜์ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + } + + private static void validateThousand(int amount) { + if (amount % 1000 != 0) { + throw new IllegalArgumentException("[ERROR] ๊ตฌ์ž…๊ธˆ์•ก์€ 1,000๋‹จ์œ„๋กœ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”."); + } + } + + private static void validateNotNull(String input) { + if (input == null) { + throw new IllegalArgumentException("[ERROR] ์ž…๋ ฅ์€ null์ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + } + + private static void validateNotEmpty(String input) { + if (input.isEmpty()) { + throw new IllegalArgumentException("[ERROR] ์ž…๋ ฅ์€ ๋นˆ ๊ฐ’์ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + } +} diff --git a/src/main/java/lotto/support/parser/WinningNumberParser.java b/src/main/java/lotto/support/parser/WinningNumberParser.java new file mode 100644 index 00000000000..9e12a74fd48 --- /dev/null +++ b/src/main/java/lotto/support/parser/WinningNumberParser.java @@ -0,0 +1,74 @@ +package lotto.support.parser; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public final class WinningNumberParser { + + private WinningNumberParser() { + } + + public static List parse(String input) { + validateNotNull(input); + + String trimmed = input.trim(); + validateNotEmpty(trimmed); + + String[] tokens = trimmed.split(","); + + List result = getIntegers(tokens); + validateSize(result); + validateDuplicate(result); + + return result; + } + + private static void validateDuplicate(List result) { + Set set = new HashSet<>(result); + if (set.size() != result.size()) { + throw new IllegalArgumentException("[ERROR] ๋‹น์ฒจ๋ฒˆํ˜ธ์— ์ค‘๋ณต๋˜๋Š” ์ˆซ์ž๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค."); + } + } + + private static void validateSize(List result) { + if (result.size() != 6) { + throw new IllegalArgumentException("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 6๊ฐœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } + } + + private static List getIntegers(String[] tokens) { + List result = new ArrayList<>(); + for (String token : tokens) { + String value = token.trim(); + if (value.isEmpty()) { + throw new IllegalArgumentException("[ERROR] ์ž˜๋ชป๋œ ํ˜•์‹์˜ ์ž…๋ ฅ์ž…๋‹ˆ๋‹ค."); + } + + int number; + try { + number = Integer.parseInt(value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("[ERROR] ์ˆซ์ž๊ฐ€ ์•„๋‹Œ ๊ฐ’์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค."); + } + if (number < 1 || number > 45) { + throw new IllegalArgumentException("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ์ˆซ์ž ๋ฒ”์œ„๋Š” 1~45๊นŒ์ง€์ž…๋‹ˆ๋‹ค."); + } + result.add(number); + } + return result; + } + + private static void validateNotNull(String input) { + if (input == null) { + throw new IllegalArgumentException("[ERROR] ์ž…๋ ฅ์€ null์ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + } + + private static void validateNotEmpty(String input) { + if (input.isEmpty()) { + throw new IllegalArgumentException("[ERROR] ์ž…๋ ฅ์€ ๋นˆ ๊ฐ’์ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + } +} diff --git a/src/main/java/lotto/view/InputView.java b/src/main/java/lotto/view/InputView.java new file mode 100644 index 00000000000..db00bf15938 --- /dev/null +++ b/src/main/java/lotto/view/InputView.java @@ -0,0 +1,32 @@ +package lotto.view; + +import camp.nextstep.edu.missionutils.Console; +import lotto.support.parser.BonusNumberParser; +import lotto.support.parser.PurchaseAmountParser; +import lotto.support.parser.WinningNumberParser; + +import java.util.List; + +public final class InputView { + + public int readPurchaseAmount() { + System.out.println("๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."); + String input = Console.readLine(); + return PurchaseAmountParser.parse(input); + } + + public List readWinningNumbers() { + System.out.println(); + System.out.println("๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."); + String input = Console.readLine(); + return WinningNumberParser.parse(input); + } + + public int readBonusNumber() { + System.out.println(); + System.out.println("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."); + String input = Console.readLine(); + return BonusNumberParser.parse(input); + } + +} diff --git a/src/main/java/lotto/view/OutputView.java b/src/main/java/lotto/view/OutputView.java new file mode 100644 index 00000000000..ad0ecc8167b --- /dev/null +++ b/src/main/java/lotto/view/OutputView.java @@ -0,0 +1,31 @@ +package lotto.view; + +import lotto.domain.Lotto; +import lotto.domain.Lottos; +import lotto.domain.Rank; + +import java.util.Map; + +public final class OutputView { + + public void printLottos(Lottos lottos) { + System.out.printf("%d๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.\n", lottos.size()); + for (Lotto lotto : lottos.getLottos()) { + System.out.println(lotto.getNumbers()); + } + } + + public void printWinningDetails(Map ranks) { + System.out.println(); + System.out.println("---"); + System.out.printf("3๊ฐœ ์ผ์น˜ (5,000์›) - %d๊ฐœ\n", ranks.getOrDefault(Rank.FIFTH, 0)); + System.out.printf("4๊ฐœ ์ผ์น˜ (50,000์›) - %d๊ฐœ\n", ranks.getOrDefault(Rank.FOURTH, 0)); + System.out.printf("5๊ฐœ ์ผ์น˜ (1,500,000์›) - %d๊ฐœ\n", ranks.getOrDefault(Rank.THIRD, 0)); + System.out.printf("5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - %d๊ฐœ\n", ranks.getOrDefault(Rank.SECOND, 0)); + System.out.printf("6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - %d๊ฐœ\n", ranks.getOrDefault(Rank.FIRST, 0)); + } + + public void printProfitRate(String rate) { + System.out.println("์ด ์ˆ˜์ต๋ฅ ์€ " + rate + "์ž…๋‹ˆ๋‹ค."); + } +} diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index 9f5dfe7eb83..0e4d4f73896 100644 --- a/src/test/java/lotto/LottoTest.java +++ b/src/test/java/lotto/LottoTest.java @@ -1,5 +1,6 @@ package lotto; +import lotto.domain.Lotto; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test;