From d78965df4b6e658416c4023e7d8d7cbc1c94edc9 Mon Sep 17 00:00:00 2001 From: JYP Date: Mon, 3 Nov 2025 22:46:25 +0900 Subject: [PATCH 01/15] =?UTF-8?q?feat:=20=EA=B8=B0=EB=B3=B8=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84=20=EB=AA=A9=EB=A1=9D=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 5fa2560b46..9d3e68be34 100644 --- a/README.md +++ b/README.md @@ -1 +1,12 @@ # java-lotto-precourse + +# 기능 구현목록 +- [ ] 로또 구입 예산 입력기능 +- [ ] 구입예산에 따른 로또 추출기능 +- [ ] 당첨번호 입력 받는 기능 +- [ ] 보너스번호 입력 받는 기능 +- [ ] 발행한 로또 수량,번호 출력 기능 +- [ ] 당첨내역 계산 기능 +- [ ] 당첨내역 출력 기능 +- [ ] 수익률 계산 기능 +- [ ] 수익률 출력 기능 From beb6021591c970ed7083ecf1d98219f9835bd305 Mon Sep 17 00:00:00 2001 From: JYP Date: Mon, 3 Nov 2025 23:00:03 +0900 Subject: [PATCH 02/15] =?UTF-8?q?feat:=20=EC=98=88=EC=82=B0=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EB=B0=9B=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20&=20=EC=9E=85=EB=A0=A5=EB=B0=9B=EC=9D=80=20?= =?UTF-8?q?=EC=98=88=EC=82=B0=EC=9C=BC=EB=A1=9C=20=EA=B5=AC=EB=A7=A4?= =?UTF-8?q?=ED=95=9C=20=EB=A1=9C=EB=98=90=20=EA=B0=9C=EC=88=98=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +- src/main/java/lotto/Application.java | 50 ++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d3e68be34..6ce0c0f62f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # java-lotto-precourse # 기능 구현목록 -- [ ] 로또 구입 예산 입력기능 +- [X] 로또 구입 예산 입력기능 +- [X] 로또 구입 개수 출력기능 - [ ] 구입예산에 따른 로또 추출기능 - [ ] 당첨번호 입력 받는 기능 - [ ] 보너스번호 입력 받는 기능 diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d190922ba4..d82b451e14 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,7 +1,57 @@ package lotto; + +enum Messages { + PURCHASEABLE_INPUT_MESSAGE("구입금액을 입력해 주세요."); + + private final String description; + + Messages(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } +} + public class Application { + private static final int TICKET_PRICE = 1000; + public static void main(String[] args) { // TODO: 프로그램 구현 + + // 예산 입력받기 기능 + int totalLottoCnt = getPurchaseableLottoNum(getBudgetInput()); + + // 입력받은 금액 출력 기능 + printTotalLottoNum(totalLottoCnt); + } + + // 예산 입력받기 기능구현 + public static Integer getPurchaseableLottoNum(int budget) { + if (budget < TICKET_PRICE) { + throw new IllegalArgumentException("구입 금액은 1000원 이상이어야 합니다."); + } + return budget / TICKET_PRICE; + } + + // 입력받은 금액 출력 기능 + public static void printTotalLottoNum(int totalLottoCNt){ + System.out.println(totalLottoCNt + "개를 구매했습니다."); } + + public static Integer getBudgetInput() { + System.out.println(Messages.PURCHASEABLE_INPUT_MESSAGE.getDescription()); + String input = camp.nextstep.edu.missionutils.Console.readLine(); + validateNumericInput(input); + return Integer.parseInt(input); + } + + private static void validateNumericInput(String input) { + if (!input.matches("\\d+")) { + throw new IllegalArgumentException("숫자만 입력 가능합니다."); + } + } + } From cdae6f8d7d3a902e6cde4f80c9d66ffa7c76c806 Mon Sep 17 00:00:00 2001 From: JYP Date: Mon, 3 Nov 2025 23:07:55 +0900 Subject: [PATCH 03/15] =?UTF-8?q?refactor:=20=EA=B5=AC=EC=9E=85=EA=B8=88?= =?UTF-8?q?=EC=95=A1=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EB=94=B0=EB=A1=9C=20=ED=95=A8=EC=88=98?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + src/main/java/lotto/Application.java | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ce0c0f62f..8f228262dc 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ # 기능 구현목록 - [X] 로또 구입 예산 입력기능 - [X] 로또 구입 개수 출력기능 +- [X] 구입금액메시지 출력 기능 - [ ] 구입예산에 따른 로또 추출기능 - [ ] 당첨번호 입력 받는 기능 - [ ] 보너스번호 입력 받는 기능 diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d82b451e14..99650adc05 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -41,13 +41,19 @@ public static void printTotalLottoNum(int totalLottoCNt){ System.out.println(totalLottoCNt + "개를 구매했습니다."); } - public static Integer getBudgetInput() { + // 구입금액 메시지 출력기능 + public static void printPurchaseableInputMessage(){ System.out.println(Messages.PURCHASEABLE_INPUT_MESSAGE.getDescription()); + } + + public static Integer getBudgetInput() { + printPurchaseableInputMessage(); String input = camp.nextstep.edu.missionutils.Console.readLine(); validateNumericInput(input); return Integer.parseInt(input); } + // 입력값 검증기능 private static void validateNumericInput(String input) { if (!input.matches("\\d+")) { throw new IllegalArgumentException("숫자만 입력 가능합니다."); From 67647d734fbf4c7705a11a1aa503d07b55b49ec6 Mon Sep 17 00:00:00 2001 From: JYP Date: Mon, 3 Nov 2025 23:11:29 +0900 Subject: [PATCH 04/15] =?UTF-8?q?feat:=20=EC=B6=94=EC=B6=9C=EB=90=9C=20?= =?UTF-8?q?=EB=A1=9C=EB=98=90=20=EC=A1=B0=ED=95=A9=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=EC=9D=84=20=EA=B5=AC=ED=98=84=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=EC=97=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8f228262dc..e88d2d1e11 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ - [X] 로또 구입 개수 출력기능 - [X] 구입금액메시지 출력 기능 - [ ] 구입예산에 따른 로또 추출기능 +- [ ] 추출된 로또 조합 출력기능 - [ ] 당첨번호 입력 받는 기능 - [ ] 보너스번호 입력 받는 기능 - [ ] 발행한 로또 수량,번호 출력 기능 From 333f45dadae13505093ac66737df508eb404028d Mon Sep 17 00:00:00 2001 From: JYP Date: Mon, 3 Nov 2025 23:14:24 +0900 Subject: [PATCH 05/15] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EC=B6=94?= =?UTF-8?q?=EC=B6=9C=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20&=20?= =?UTF-8?q?=EC=B6=94=EC=B6=9C=EB=90=9C=20=EB=A1=9C=EB=98=90=20=EC=A1=B0?= =?UTF-8?q?=ED=95=A9=20=EC=B6=9C=EB=A0=A5=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/Application.java | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index 99650adc05..09b888338e 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,6 +1,9 @@ package lotto; +import java.util.ArrayList; +import java.util.List; + enum Messages { PURCHASEABLE_INPUT_MESSAGE("구입금액을 입력해 주세요."); @@ -26,6 +29,10 @@ public static void main(String[] args) { // 입력받은 금액 출력 기능 printTotalLottoNum(totalLottoCnt); + + // 로또 추출기능 + List> extractedLottoNums = extractLottoNumbers(totalLottoCnt); + } // 예산 입력받기 기능구현 @@ -60,4 +67,20 @@ private static void validateNumericInput(String input) { } } + // 로또 추출기능 + public static List> extractLottoNumbers(int totalLottoCnt) { + List> lottos = new ArrayList<>(); + for (int i = 0; i < totalLottoCnt; i++) { + List numbers = camp.nextstep.edu.missionutils.Randoms.pickUniqueNumbersInRange(1, 45, 6); + printExtractedLottoNumbers(numbers); + lottos.add(numbers); + } + return lottos; + } + + // 추출된 로또번호 출력기능 + public static void printExtractedLottoNumbers(List numbers){ + System.out.println(numbers); + } + } From 2634b85b44ff1c6263f249fb45ce573142c650cf Mon Sep 17 00:00:00 2001 From: JYP Date: Mon, 3 Nov 2025 23:15:10 +0900 Subject: [PATCH 06/15] =?UTF-8?q?docs:=20=EB=A1=9C=EB=98=90=20=EC=B6=94?= =?UTF-8?q?=EC=B6=9C=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20&=20?= =?UTF-8?q?=EC=B6=94=EC=B6=9C=EB=90=9C=20=EB=A1=9C=EB=98=90=20=EC=A1=B0?= =?UTF-8?q?=ED=95=A9=20=EC=B6=9C=EB=A0=A5=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=EB=AA=A9=EB=A1=9D=EC=97=90=20=EC=B2=B4=ED=81=AC?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e88d2d1e11..976ad13b52 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ - [X] 로또 구입 예산 입력기능 - [X] 로또 구입 개수 출력기능 - [X] 구입금액메시지 출력 기능 -- [ ] 구입예산에 따른 로또 추출기능 -- [ ] 추출된 로또 조합 출력기능 +- [X] 구입예산에 따른 로또 추출기능 +- [X] 추출된 로또 조합 출력기능 - [ ] 당첨번호 입력 받는 기능 - [ ] 보너스번호 입력 받는 기능 - [ ] 발행한 로또 수량,번호 출력 기능 From b181daf67f75b4319ff235855ce0bdd1c7e523bc Mon Sep 17 00:00:00 2001 From: JYP Date: Mon, 3 Nov 2025 23:23:16 +0900 Subject: [PATCH 07/15] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EB=8B=B9?= =?UTF-8?q?=EC=B2=A8=EC=9E=85=EB=A0=A5,=20=EC=B6=9C=EB=A0=A5,=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=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 --- README.md | 2 ++ src/main/java/lotto/Application.java | 46 +++++++++++++++++++++++++++- src/main/java/lotto/Lotto.java | 21 +++++++++++-- 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 976ad13b52..cab9b0b732 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ - [X] 구입예산에 따른 로또 추출기능 - [X] 추출된 로또 조합 출력기능 - [ ] 당첨번호 입력 받는 기능 +- [ ] 로또 당첨번호 검증 기능 +- [ ] 입력받은 당첨번호 출력 기능 - [ ] 보너스번호 입력 받는 기능 - [ ] 발행한 로또 수량,번호 출력 기능 - [ ] 당첨내역 계산 기능 diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index 09b888338e..1046f109c5 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -2,10 +2,13 @@ import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; enum Messages { - PURCHASEABLE_INPUT_MESSAGE("구입금액을 입력해 주세요."); + PURCHASEABLE_INPUT_MESSAGE("구입금액을 입력해 주세요."), + ANSWER_INPUT_MESSAGE("당첨 번호를 입력해 주세요."); private final String description; @@ -33,6 +36,9 @@ public static void main(String[] args) { // 로또 추출기능 List> extractedLottoNums = extractLottoNumbers(totalLottoCnt); + // 당첨번호 입력받기 + Lotto lotto = new Lotto(getJackpotInput()); + } // 예산 입력받기 기능구현 @@ -83,4 +89,42 @@ public static void printExtractedLottoNumbers(List numbers){ System.out.println(numbers); } + // 로또 당첨번호 입력 기능 + public static List getJackpotInput() { + pringJackpotInputMessage(); + String input = camp.nextstep.edu.missionutils.Console.readLine(); + return parseAndValidateNumbers(input); + } + + // 로또 당첨번호 입력메시지 출력 기능 + public static void pringJackpotInputMessage(){ + System.out.println(Messages.ANSWER_INPUT_MESSAGE.getDescription()); + } + + private static List parseAndValidateNumbers(String input) { + try { + List numbers = Arrays.stream(input.split(",")) + .map(String::trim) + .map(Integer::parseInt) + .collect(Collectors.toList()); + validateLottoNumbers(numbers); + return numbers; + } catch (NumberFormatException e) { + throw new IllegalArgumentException("올바른 숫자 형식이 아닙니다."); + } + } + + // 로또 번호 형태 검증기능 + private static void validateLottoNumbers(List numbers) { + if (numbers.size() != 6) { + throw new IllegalArgumentException("로또 번호는 6개여야 합니다."); + } + if (numbers.stream().distinct().count() != 6) { + throw new IllegalArgumentException("로또 번호는 중복될 수 없습니다."); + } + if (numbers.stream().anyMatch(n -> n < 1 || n > 45)) { + throw new IllegalArgumentException("로또 번호는 1부터 45 사이여야 합니다."); + } + } + } diff --git a/src/main/java/lotto/Lotto.java b/src/main/java/lotto/Lotto.java index 88fc5cf12b..44036a657f 100644 --- a/src/main/java/lotto/Lotto.java +++ b/src/main/java/lotto/Lotto.java @@ -1,5 +1,6 @@ package lotto; +import java.util.HashSet; import java.util.List; public class Lotto { @@ -11,10 +12,26 @@ public Lotto(List numbers) { } private void validate(List numbers) { + validateSize(numbers); + validateDuplicate(numbers); + validateRange(numbers); + } + + private void validateSize(List numbers) { if (numbers.size() != 6) { - throw new IllegalArgumentException("[ERROR] 로또 번호는 6개여야 합니다."); + throw new IllegalArgumentException("로또 번호는 6개여야 합니다."); } } - // TODO: 추가 기능 구현 + private void validateDuplicate(List numbers) { + if (new HashSet<>(numbers).size() != 6) { + throw new IllegalArgumentException("로또 번호는 중복될 수 없습니다."); + } + } + + private void validateRange(List numbers) { + if (numbers.stream().anyMatch(num -> num < 1 || num > 45)) { + throw new IllegalArgumentException("로또 번호는 1부터 45 사이여야 합니다."); + } + } } From 12ddb6175521d7d01366277cae5966b6a68faf14 Mon Sep 17 00:00:00 2001 From: JYP Date: Mon, 3 Nov 2025 23:23:36 +0900 Subject: [PATCH 08/15] =?UTF-8?q?docs:=20=EB=A1=9C=EB=98=90=20=EB=8B=B9?= =?UTF-8?q?=EC=B2=A8=EC=9E=85=EB=A0=A5,=20=EC=B6=9C=EB=A0=A5,=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cab9b0b732..7ac4e8b9bb 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ - [X] 구입금액메시지 출력 기능 - [X] 구입예산에 따른 로또 추출기능 - [X] 추출된 로또 조합 출력기능 -- [ ] 당첨번호 입력 받는 기능 -- [ ] 로또 당첨번호 검증 기능 -- [ ] 입력받은 당첨번호 출력 기능 +- [X] 당첨번호 입력 받는 기능 +- [X] 로또 당첨번호 검증 기능 +- [X] 입력받은 당첨번호 출력 기능 - [ ] 보너스번호 입력 받는 기능 - [ ] 발행한 로또 수량,번호 출력 기능 - [ ] 당첨내역 계산 기능 From d30a93568e10171d51bacc6bfe0f344cf009c4d3 Mon Sep 17 00:00:00 2001 From: JYP Date: Mon, 3 Nov 2025 23:35:17 +0900 Subject: [PATCH 09/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,=EC=B6=9C=EB=A0=A5,?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +++- src/main/java/lotto/Application.java | 26 ++++++++++++++++++++++++-- src/main/java/lotto/Lotto.java | 22 ++++++++++++++++++++++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7ac4e8b9bb..fb5d885478 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,9 @@ - [X] 당첨번호 입력 받는 기능 - [X] 로또 당첨번호 검증 기능 - [X] 입력받은 당첨번호 출력 기능 -- [ ] 보너스번호 입력 받는 기능 +- [X] 보너스번호 입력 받는 기능 +- [X] 보너스번호 입력메시지 출력기능 +- [X] 보너스 번호 검증기능 - [ ] 발행한 로또 수량,번호 출력 기능 - [ ] 당첨내역 계산 기능 - [ ] 당첨내역 출력 기능 diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index 1046f109c5..7097f8879b 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,14 +1,15 @@ package lotto; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; + enum Messages { PURCHASEABLE_INPUT_MESSAGE("구입금액을 입력해 주세요."), - ANSWER_INPUT_MESSAGE("당첨 번호를 입력해 주세요."); + ANSWER_INPUT_MESSAGE("당첨 번호를 입력해 주세요."), + BONUS_INPUT_MESSAGE("보너스 번호를 입력해 주세요."); private final String description; @@ -39,6 +40,9 @@ public static void main(String[] args) { // 당첨번호 입력받기 Lotto lotto = new Lotto(getJackpotInput()); + // 보너스 번호 입력받기 + int bonusNum = lotto.addBonusNumbers(getBonusNumber()); + } // 예산 입력받기 기능구현 @@ -127,4 +131,22 @@ private static void validateLottoNumbers(List numbers) { } } + // 보너스 번호 입력받기 + public static Integer getBonusNumber() { + printBonumInputMessage(); + String input = camp.nextstep.edu.missionutils.Console.readLine().trim(); + validateNumericInput(input); + int number = Integer.parseInt(input); + if (number < 1 || number > 45) { + throw new IllegalArgumentException("보너스 번호는 1부터 45 사이여야 합니다."); + } + return number; + } + + // 보너스 번호입력 메시지 출력기능 + public static void printBonumInputMessage(){ + System.out.println(Messages.BONUS_INPUT_MESSAGE.getDescription()); + } + + } diff --git a/src/main/java/lotto/Lotto.java b/src/main/java/lotto/Lotto.java index 44036a657f..42c562ce85 100644 --- a/src/main/java/lotto/Lotto.java +++ b/src/main/java/lotto/Lotto.java @@ -17,6 +17,10 @@ private void validate(List numbers) { validateRange(numbers); } + public List getNumbers() { + return numbers; + } + private void validateSize(List numbers) { if (numbers.size() != 6) { throw new IllegalArgumentException("로또 번호는 6개여야 합니다."); @@ -34,4 +38,22 @@ private void validateRange(List numbers) { throw new IllegalArgumentException("로또 번호는 1부터 45 사이여야 합니다."); } } + + // 보너스 번호 생성 + public int addBonusNumbers(int bonusNumber) { + validateBonusNumber(bonusNumber); + return bonusNumber; + } + + // 보너스 번호 검증기능 + private void validateBonusNumber(int bonusNumber) { + if (numbers.contains(bonusNumber)) { + throw new IllegalArgumentException("보너스 번호는 당첨 번호와 중복될 수 없습니다."); + } + if (bonusNumber < 1 || bonusNumber > 45) { + throw new IllegalArgumentException("보너스 번호는 1부터 45 사이여야 합니다."); + } + } + + } From 2db621de2a1f9ead6cc883d2dd56cbe7b6a52c88 Mon Sep 17 00:00:00 2001 From: JYP Date: Mon, 3 Nov 2025 23:39:58 +0900 Subject: [PATCH 10/15] =?UTF-8?q?docs:=20=EB=B0=9C=ED=96=89=ED=95=9C=20?= =?UTF-8?q?=EB=A1=9C=EB=98=90=20=EC=88=98=EB=9F=89,=20=EB=B2=88=ED=98=B8?= =?UTF-8?q?=20=EC=B6=9C=EB=A0=A5=EA=B8=B0=EB=8A=A5=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fb5d885478..8aa9f48dbc 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,13 @@ - [X] 구입금액메시지 출력 기능 - [X] 구입예산에 따른 로또 추출기능 - [X] 추출된 로또 조합 출력기능 +- [X] 발행한 로또 수량,번호 출력 기능 - [X] 당첨번호 입력 받는 기능 - [X] 로또 당첨번호 검증 기능 - [X] 입력받은 당첨번호 출력 기능 - [X] 보너스번호 입력 받는 기능 - [X] 보너스번호 입력메시지 출력기능 - [X] 보너스 번호 검증기능 -- [ ] 발행한 로또 수량,번호 출력 기능 - [ ] 당첨내역 계산 기능 - [ ] 당첨내역 출력 기능 - [ ] 수익률 계산 기능 From b75c5b0a926b6aca455aa8b3854138b6aec6b0e3 Mon Sep 17 00:00:00 2001 From: JYP Date: Mon, 3 Nov 2025 23:40:32 +0900 Subject: [PATCH 11/15] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8=EB=82=B4?= =?UTF-8?q?=EC=97=AD=20=EA=B3=84=EC=82=B0,=20=EC=B6=9C=EB=A0=A5=20&=20?= =?UTF-8?q?=EC=88=98=EC=9D=B5=EB=A5=A0=20=EA=B3=84=EC=82=B0,=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +- src/main/java/lotto/Application.java | 124 ++++++++++++++++++++++++++- 2 files changed, 127 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8aa9f48dbc..b55934ac2b 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ - [X] 보너스번호 입력 받는 기능 - [X] 보너스번호 입력메시지 출력기능 - [X] 보너스 번호 검증기능 -- [ ] 당첨내역 계산 기능 -- [ ] 당첨내역 출력 기능 -- [ ] 수익률 계산 기능 -- [ ] 수익률 출력 기능 +- [X] 당첨내역 계산 기능 +- [X] 당첨내역 출력 기능 +- [X] 수익률 계산 기능 +- [X] 수익률 출력 기능 diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index 7097f8879b..63ef60b8e9 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -2,14 +2,17 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; enum Messages { PURCHASEABLE_INPUT_MESSAGE("구입금액을 입력해 주세요."), ANSWER_INPUT_MESSAGE("당첨 번호를 입력해 주세요."), - BONUS_INPUT_MESSAGE("보너스 번호를 입력해 주세요."); + BONUS_INPUT_MESSAGE("보너스 번호를 입력해 주세요."), + STATISTICS_HEADER("당첨 통계\n---"); private final String description; @@ -22,6 +25,57 @@ public String getDescription() { } } +enum Prize { + FIRST(6, 2_000_000_000, "6개 일치"), + SECOND(5, 30_000_000, "5개 일치, 보너스 볼 일치"), + THIRD(5, 1_500_000, "5개 일치"), + FOURTH(4, 50_000, "4개 일치"), + FIFTH(3, 5_000, "3개 일치"), + NONE(0, 0, "일치하는 번호 없음"); + + private final int matchCount; + private final int prizeMoney; + private final String description; + + Prize(int matchCount, int prizeMoney, String description) { + this.matchCount = matchCount; + this.prizeMoney = prizeMoney; + this.description = description; + } + + public static Prize of(int matchCount, boolean matchBonus) { + if (matchCount == 6) { + return FIRST; + } + if (matchCount == 5 && matchBonus) { + return SECOND; + } + if (matchCount == 5) { + return THIRD; + } + if (matchCount == 4) { + return FOURTH; + } + if (matchCount == 3) { + return FIFTH; + } + return NONE; + } + + public int getPrizeMoney() { + return prizeMoney; + } + + public String getDescription() { + return description; + } +} + +record WinningStatistics( + Map prizeCount, + double profitRate +) {} + public class Application { private static final int TICKET_PRICE = 1000; @@ -43,6 +97,12 @@ public static void main(String[] args) { // 보너스 번호 입력받기 int bonusNum = lotto.addBonusNumbers(getBonusNumber()); + // 당첨 여부 판단 + WinningStatistics statistics = calculateResults(extractedLottoNums, lotto.getNumbers(), bonusNum); + + // 당첨 여부 출력 + printStatistics(statistics); + } // 예산 입력받기 기능구현 @@ -148,5 +208,67 @@ public static void printBonumInputMessage(){ System.out.println(Messages.BONUS_INPUT_MESSAGE.getDescription()); } + private static WinningStatistics calculateResults( + List> purchasedLottos, + List winningNumbers, + int bonusNumber + ) { + Map prizeCount = initializePrizeCount(); + + for (List lotto : purchasedLottos) { + int matchCount = countMatches(lotto, winningNumbers); + boolean matchBonus = (matchCount == 5) && lotto.contains(bonusNumber); + Prize prize = Prize.of(matchCount, matchBonus); + prizeCount.merge(prize, 1, Integer::sum); + } + + int totalPrize = calculateTotalPrize(prizeCount); + double profitRate = calculateProfitRate(purchasedLottos.size() * TICKET_PRICE, totalPrize); + + return new WinningStatistics(prizeCount, profitRate); + } + + private static Map initializePrizeCount() { + return Arrays.stream(Prize.values()) + .collect(Collectors.toMap( + prize -> prize, + prize -> 0, + (prev, current) -> current, + HashMap::new + )); + } + + private static int countMatches(List lotto, List winningNumbers) { + return (int) lotto.stream() + .filter(winningNumbers::contains) + .count(); + } + + private static int calculateTotalPrize(Map prizeCount) { + return prizeCount.entrySet().stream() + .mapToInt(entry -> entry.getKey().getPrizeMoney() * entry.getValue()) + .sum(); + } + + private static double calculateProfitRate(int totalCost, int totalPrize) { + return ((double) totalPrize / totalCost) * 100; + } + + private static void printStatistics(WinningStatistics statistics) { + System.out.println(Messages.STATISTICS_HEADER.getDescription()); + + Arrays.stream(Prize.values()) + .filter(prize -> prize != Prize.NONE) + .forEach(prize -> printPrizeResult(prize, statistics.prizeCount().get(prize))); + + System.out.printf("총 수익률은 %.1f%%입니다.%n", statistics.profitRate()); + } + + private static void printPrizeResult(Prize prize, int count) { + System.out.printf("%s (%,d원) - %d개%n", + prize.getDescription(), + prize.getPrizeMoney(), + count); + } } From 1e514b25185c2d07ece5a92419c73aeba3f96abb Mon Sep 17 00:00:00 2001 From: JYP Date: Mon, 3 Nov 2025 23:43:22 +0900 Subject: [PATCH 12/15] =?UTF-8?q?fix:=20try-catch=20=EB=A1=9C=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=EB=B0=9C=EC=83=9D=EC=8B=9C=20=EC=98=88=EC=99=B8?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EA=B0=80=EB=8A=A5=ED=95=98=EA=B2=8C=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/main/java/lotto/Application.java | 37 +++++++++++++++------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index 63ef60b8e9..1be51ae668 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -12,7 +12,8 @@ enum Messages { PURCHASEABLE_INPUT_MESSAGE("구입금액을 입력해 주세요."), ANSWER_INPUT_MESSAGE("당첨 번호를 입력해 주세요."), BONUS_INPUT_MESSAGE("보너스 번호를 입력해 주세요."), - STATISTICS_HEADER("당첨 통계\n---"); + STATISTICS_HEADER("당첨 통계\n---"), + ERROR_MESSAGE("[ERROR] "); private final String description; @@ -81,28 +82,30 @@ public class Application { public static void main(String[] args) { // TODO: 프로그램 구현 + try { + // 예산 입력받기 기능 + int totalLottoCnt = getPurchaseableLottoNum(getBudgetInput()); - // 예산 입력받기 기능 - int totalLottoCnt = getPurchaseableLottoNum(getBudgetInput()); - - // 입력받은 금액 출력 기능 - printTotalLottoNum(totalLottoCnt); - - // 로또 추출기능 - List> extractedLottoNums = extractLottoNumbers(totalLottoCnt); + // 입력받은 금액 출력 기능 + printTotalLottoNum(totalLottoCnt); - // 당첨번호 입력받기 - Lotto lotto = new Lotto(getJackpotInput()); + // 로또 추출기능 + List> extractedLottoNums = extractLottoNumbers(totalLottoCnt); - // 보너스 번호 입력받기 - int bonusNum = lotto.addBonusNumbers(getBonusNumber()); + // 당첨번호 입력받기 + Lotto lotto = new Lotto(getJackpotInput()); - // 당첨 여부 판단 - WinningStatistics statistics = calculateResults(extractedLottoNums, lotto.getNumbers(), bonusNum); + // 보너스 번호 입력받기 + int bonusNum = lotto.addBonusNumbers(getBonusNumber()); - // 당첨 여부 출력 - printStatistics(statistics); + // 당첨 여부 판단 + WinningStatistics statistics = calculateResults(extractedLottoNums, lotto.getNumbers(), bonusNum); + // 당첨 여부 출력 + printStatistics(statistics); + } catch (IllegalArgumentException e) { + System.out.println(Messages.ERROR_MESSAGE.getDescription() + e.getMessage()); + } } // 예산 입력받기 기능구현 From 25cc50ec6de99500a10d585f81c9814bafd0440b Mon Sep 17 00:00:00 2001 From: JYP Date: Mon, 3 Nov 2025 23:50:32 +0900 Subject: [PATCH 13/15] =?UTF-8?q?test:=20=EB=A1=9C=EB=98=90=20=EC=9E=90?= =?UTF-8?q?=EB=8F=99=20=EC=83=9D=EC=84=B1=EC=8B=9C=20=EA=B0=9C=EC=88=98,?= =?UTF-8?q?=20=ED=98=95=ED=83=9C=20=EA=B2=80=EC=A6=9D=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/lotto/LottoTest.java | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index 309f4e50ae..e5e937d176 100644 --- a/src/test/java/lotto/LottoTest.java +++ b/src/test/java/lotto/LottoTest.java @@ -5,6 +5,7 @@ import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; class LottoTest { @@ -22,4 +23,31 @@ class LottoTest { } // TODO: 추가 기능 구현에 따른 테스트 코드 작성 + + @DisplayName("로또 자동 생성 시 요청한 개수만큼 로또를 생성한다.") + @Test + void 자동_생성된_로또_개수를_검증한다() { + int totalCount = 5; + + List> lottos = Application.extractLottoNumbers(totalCount); + + assertThat(lottos).hasSize(totalCount); + } + + @DisplayName("로또 자동 생성 시 각 로또는 1~45 사이의 중복되지 않은 6개의 숫자여야 한다.") + @Test + void 자동_생성된_로또_번호_형태를_검증한다() { + int totalCount = 5; + + List> lottos = Application.extractLottoNumbers(totalCount); + + for (List lotto : lottos) { + assertThat(lotto).hasSize(6); + assertThat(lotto).doesNotHaveDuplicates(); + assertThat(lotto).allMatch(number -> number >= 1 && number <= 45); + } + } + + + } From 0eb9a90bc0e36e4d044977beff85e3ba2a32104c Mon Sep 17 00:00:00 2001 From: JYP Date: Mon, 3 Nov 2025 23:52:22 +0900 Subject: [PATCH 14/15] =?UTF-8?q?test:=20=EB=A1=9C=EB=98=90=20=EA=B8=88?= =?UTF-8?q?=EC=95=A1=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EA=B5=AC=EB=A7=A4=20?= =?UTF-8?q?=EC=88=98=ED=96=A5=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=BD=94?= =?UTF-8?q?=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/lotto/LottoTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index e5e937d176..099bf8d91d 100644 --- a/src/test/java/lotto/LottoTest.java +++ b/src/test/java/lotto/LottoTest.java @@ -7,6 +7,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; class LottoTest { @Test @@ -49,5 +50,12 @@ class LottoTest { } + @DisplayName("구입 금액을 1000으로 나눈 값만큼 로또를 구매한다.") + @Test + void 구입_금액에_해당하는_수량만큼_로또를_구매한다() { + int count = Application.getPurchaseableLottoNum(8000); + + assertThat(count).isEqualTo(8); + } } From feb1d57f4e2a0d5a3de800f1175630f78ee1e0bf Mon Sep 17 00:00:00 2001 From: JYP Date: Mon, 3 Nov 2025 23:52:43 +0900 Subject: [PATCH 15/15] =?UTF-8?q?test:=20=EB=8B=B9=EC=B2=A8=20=EB=93=B1?= =?UTF-8?q?=EC=88=98=20=EB=A7=A4=ED=95=91=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=BD=94=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/lotto/LottoTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index 099bf8d91d..4f9ef8f949 100644 --- a/src/test/java/lotto/LottoTest.java +++ b/src/test/java/lotto/LottoTest.java @@ -58,4 +58,19 @@ class LottoTest { assertThat(count).isEqualTo(8); } + @DisplayName("일치 개수와 보너스 번호에 따라 올바른 등수가 매핑된다.") + @Test + void 당첨_조건에_따라_등수를_반환한다() { + assertAll( + () -> assertThat(Prize.of(6, false)).isEqualTo(Prize.FIRST), + () -> assertThat(Prize.of(5, true)).isEqualTo(Prize.SECOND), + () -> assertThat(Prize.of(5, false)).isEqualTo(Prize.THIRD), + () -> assertThat(Prize.of(4, false)).isEqualTo(Prize.FOURTH), + () -> assertThat(Prize.of(3, false)).isEqualTo(Prize.FIFTH), + () -> assertThat(Prize.of(2, false)).isEqualTo(Prize.NONE), + () -> assertThat(Prize.of(1, false)).isEqualTo(Prize.NONE), + () -> assertThat(Prize.of(0, false)).isEqualTo(Prize.NONE) + ); + } + }