From e2ccf7ac096543f89b1fc7e0f31379e068d81b09 Mon Sep 17 00:00:00 2001 From: jisub-dev Date: Mon, 3 Nov 2025 23:43:05 +0900 Subject: [PATCH 1/5] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 5fa2560b46..e3b34a680e 100644 --- a/README.md +++ b/README.md @@ -1 +1,10 @@ # java-lotto-precourse + +## 구현할 기능 목록 + +- 구입 금액 입력 +- 당첨 번호 입력 +- 보너스 번호 입력 +- 로또 번호 생성 (1~45, 중복 없음) +- 당첨 확인 및 통계 출력 +- 수익률 계산 From b97df9f969868f313ca248801cf50feffaff44c3 Mon Sep 17 00:00:00 2001 From: jisub-dev Date: Mon, 3 Nov 2025 23:43:34 +0900 Subject: [PATCH 2/5] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=83=81=EC=84=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e3b34a680e..2f6c9440d0 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,37 @@ ## 구현할 기능 목록 -- 구입 금액 입력 -- 당첨 번호 입력 -- 보너스 번호 입력 -- 로또 번호 생성 (1~45, 중복 없음) -- 당첨 확인 및 통계 출력 -- 수익률 계산 +### 입력 기능 +- 구입 금액 입력받기 + - 1,000원 단위로 입력 + - 숫자가 아닌 경우 예외 처리 + - 1,000원으로 나누어떨어지지 않으면 예외 처리 +- 당첨 번호 입력받기 + - 쉼표로 구분하여 6개 입력 + - 숫자가 아닌 경우 예외 처리 + - 중복된 숫자가 있으면 예외 처리 + - 1~45 범위 벗어나면 예외 처리 +- 보너스 번호 입력받기 + - 숫자가 아닌 경우 예외 처리 + - 1~45 범위 벗어나면 예외 처리 + - 당첨 번호와 중복되면 예외 처리 + +### 로또 생성 기능 +- 1~45 사이 중복없는 6개 번호 생성 +- 구입 금액에 맞춰 로또 개수만큼 생성 +- 생성된 로또 번호 오름차순 정렬 + +### 당첨 확인 기능 +- 당첨 번호와 일치하는 개수 확인 +- 보너스 번호 일치 여부 확인 +- 등수 판별 + - 6개 일치: 1등 (2,000,000,000원) + - 5개 일치 + 보너스: 2등 (30,000,000원) + - 5개 일치: 3등 (1,500,000원) + - 4개 일치: 4등 (50,000원) + - 3개 일치: 5등 (5,000원) + +### 출력 기능 +- 구매한 로또 개수 및 번호 출력 +- 당첨 통계 출력 (등수별 당첨 개수) +- 수익률 계산 및 출력 (소수점 둘째 자리에서 반올림) From 27002bd4c644a6d1204afc769d62cfa6d2d00865 Mon Sep 17 00:00:00 2001 From: jisub-dev Date: Mon, 3 Nov 2025 23:43:52 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20Lotto=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/Lotto.java | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/java/lotto/Lotto.java b/src/main/java/lotto/Lotto.java index 88fc5cf12b..f6ba9da63c 100644 --- a/src/main/java/lotto/Lotto.java +++ b/src/main/java/lotto/Lotto.java @@ -1,20 +1,42 @@ package lotto; +import java.util.HashSet; import java.util.List; +import java.util.stream.Collectors; public class Lotto { private final List numbers; public Lotto(List numbers) { validate(numbers); - this.numbers = numbers; + this.numbers = numbers.stream().sorted().collect(Collectors.toList()); } private void validate(List numbers) { if (numbers.size() != 6) { throw new IllegalArgumentException("[ERROR] 로또 번호는 6개여야 합니다."); } + if (numbers.size() != new HashSet<>(numbers).size()) { + throw new IllegalArgumentException("[ERROR] 로또 번호는 중복될 수 없습니다."); + } + for (int number : numbers) { + if (number < 1 || number > 45) { + throw new IllegalArgumentException("[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다."); + } + } + } + + public int countMatch(List winningNumbers) { + return (int) numbers.stream() + .filter(winningNumbers::contains) + .count(); } - // TODO: 추가 기능 구현 + public boolean contains(int number) { + return numbers.contains(number); + } + + public List getNumbers() { + return numbers; + } } From 6b9c8f742775859fcc08e40ae85f42100446a9bc Mon Sep 17 00:00:00 2001 From: jisub-dev Date: Mon, 3 Nov 2025 23:47:53 +0900 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/Application.java | 99 +++++++++++++++++++++++++++- src/main/java/lotto/Rank.java | 42 ++++++++++++ 2 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 src/main/java/lotto/Rank.java diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d190922ba4..fbc42fc1cd 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,7 +1,104 @@ package lotto; +import camp.nextstep.edu.missionutils.Console; +import camp.nextstep.edu.missionutils.Randoms; + +import java.util.*; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + try { + int amount = readAmount(); + List lottos = generateLottos(amount); + printLottos(lottos); + + List winningNumbers = readWinningNumbers(); + int bonusNumber = readBonusNumber(winningNumbers); + + Map result = checkWinning(lottos, winningNumbers, bonusNumber); + printResult(result, amount); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + } + } + + private static int readAmount() { + System.out.println("구입금액을 입력해 주세요."); + int amount = Integer.parseInt(Console.readLine()); + if (amount % 1000 != 0) { + throw new IllegalArgumentException("[ERROR] 구입 금액은 1,000원 단위여야 합니다."); + } + return amount; + } + + private static List generateLottos(int amount) { + int count = amount / 1000; + System.out.println(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 lottos; + } + + private static void printLottos(List lottos) { + for (Lotto lotto : lottos) { + System.out.println(lotto.getNumbers()); + } + System.out.println(); + } + + private static List readWinningNumbers() { + System.out.println("당첨 번호를 입력해 주세요."); + String input = Console.readLine(); + String[] parts = input.split(","); + List numbers = new ArrayList<>(); + for (String part : parts) { + numbers.add(Integer.parseInt(part.trim())); + } + return numbers; + } + + private static int readBonusNumber(List winningNumbers) { + System.out.println("보너스 번호를 입력해 주세요."); + int bonus = Integer.parseInt(Console.readLine()); + if (winningNumbers.contains(bonus)) { + throw new IllegalArgumentException("[ERROR] 보너스 번호는 당첨 번호와 중복될 수 없습니다."); + } + return bonus; + } + + private static Map checkWinning(List lottos, List winningNumbers, int bonusNumber) { + Map result = new HashMap<>(); + for (Rank rank : Rank.values()) { + result.put(rank, 0); + } + + for (Lotto lotto : lottos) { + int matchCount = lotto.countMatch(winningNumbers); + boolean bonusMatch = lotto.contains(bonusNumber); + Rank rank = Rank.of(matchCount, bonusMatch); + result.put(rank, result.get(rank) + 1); + } + return result; + } + + private static void printResult(Map result, int amount) { + System.out.println("당첨 통계"); + System.out.println("---"); + System.out.println("3개 일치 (5,000원) - " + result.get(Rank.FIFTH) + "개"); + System.out.println("4개 일치 (50,000원) - " + result.get(Rank.FOURTH) + "개"); + System.out.println("5개 일치 (1,500,000원) - " + result.get(Rank.THIRD) + "개"); + System.out.println("5개 일치, 보너스 볼 일치 (30,000,000원) - " + result.get(Rank.SECOND) + "개"); + System.out.println("6개 일치 (2,000,000,000원) - " + result.get(Rank.FIRST) + "개"); + + long totalPrize = 0; + for (Rank rank : result.keySet()) { + totalPrize += (long) rank.getPrize() * result.get(rank); + } + double rate = (double) totalPrize / amount * 100; + System.out.printf("총 수익률은 %.1f%%입니다.%n", rate); } } diff --git a/src/main/java/lotto/Rank.java b/src/main/java/lotto/Rank.java new file mode 100644 index 0000000000..1dab24e002 --- /dev/null +++ b/src/main/java/lotto/Rank.java @@ -0,0 +1,42 @@ +package lotto; + +public enum Rank { + FIRST(6, false, 2_000_000_000), + SECOND(5, true, 30_000_000), + THIRD(5, false, 1_500_000), + FOURTH(4, false, 50_000), + FIFTH(3, false, 5_000), + NONE(0, false, 0); + + private final int matchCount; + private final boolean bonusMatch; + private final int prize; + + Rank(int matchCount, boolean bonusMatch, int prize) { + this.matchCount = matchCount; + this.bonusMatch = bonusMatch; + this.prize = prize; + } + + public static Rank of(int matchCount, boolean bonusMatch) { + for (Rank rank : values()) { + if (rank.matchCount == matchCount) { + if (rank == SECOND && bonusMatch) { + return SECOND; + } + if (rank != SECOND) { + return rank; + } + } + } + return NONE; + } + + public int getPrize() { + return prize; + } + + public int getMatchCount() { + return matchCount; + } +} From 70199f1473dcc47a3d82100658df4cae7c79e282 Mon Sep 17 00:00:00 2001 From: jisub-dev Date: Mon, 3 Nov 2025 23:49:30 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20=EC=98=88=EC=99=B8=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=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 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index fbc42fc1cd..86b021f865 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -17,8 +17,8 @@ public static void main(String[] args) { Map result = checkWinning(lottos, winningNumbers, bonusNumber); printResult(result, amount); - } catch (IllegalArgumentException e) { - System.out.println(e.getMessage()); + } catch (Exception e) { + System.out.println("[ERROR]"); } }