Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,38 @@
# java-lotto-precourse

## 구현할 기능 목록

### 입력 기능
- 구입 금액 입력받기
- 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원)

### 출력 기능
- 구매한 로또 개수 및 번호 출력
- 당첨 통계 출력 (등수별 당첨 개수)
- 수익률 계산 및 출력 (소수점 둘째 자리에서 반올림)
99 changes: 98 additions & 1 deletion src/main/java/lotto/Application.java
Original file line number Diff line number Diff line change
@@ -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<Lotto> lottos = generateLottos(amount);
printLottos(lottos);

List<Integer> winningNumbers = readWinningNumbers();
int bonusNumber = readBonusNumber(winningNumbers);

Map<Rank, Integer> result = checkWinning(lottos, winningNumbers, bonusNumber);
printResult(result, amount);
} catch (Exception e) {
System.out.println("[ERROR]");
}
}

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<Lotto> generateLottos(int amount) {
int count = amount / 1000;
System.out.println(count + "개를 구매했습니다.");

List<Lotto> lottos = new ArrayList<>();
for (int i = 0; i < count; i++) {
List<Integer> numbers = Randoms.pickUniqueNumbersInRange(1, 45, 6);
lottos.add(new Lotto(numbers));
}
return lottos;
}

private static void printLottos(List<Lotto> lottos) {
for (Lotto lotto : lottos) {
System.out.println(lotto.getNumbers());
}
System.out.println();
}

private static List<Integer> readWinningNumbers() {
System.out.println("당첨 번호를 입력해 주세요.");
String input = Console.readLine();
String[] parts = input.split(",");
List<Integer> numbers = new ArrayList<>();
for (String part : parts) {
numbers.add(Integer.parseInt(part.trim()));
}
return numbers;
}

private static int readBonusNumber(List<Integer> winningNumbers) {
System.out.println("보너스 번호를 입력해 주세요.");
int bonus = Integer.parseInt(Console.readLine());
if (winningNumbers.contains(bonus)) {
throw new IllegalArgumentException("[ERROR] 보너스 번호는 당첨 번호와 중복될 수 없습니다.");
}
return bonus;
}

private static Map<Rank, Integer> checkWinning(List<Lotto> lottos, List<Integer> winningNumbers, int bonusNumber) {
Map<Rank, Integer> 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<Rank, Integer> 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);
}
}
26 changes: 24 additions & 2 deletions src/main/java/lotto/Lotto.java
Original file line number Diff line number Diff line change
@@ -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<Integer> numbers;

public Lotto(List<Integer> numbers) {
validate(numbers);
this.numbers = numbers;
this.numbers = numbers.stream().sorted().collect(Collectors.toList());
}

private void validate(List<Integer> 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<Integer> winningNumbers) {
return (int) numbers.stream()
.filter(winningNumbers::contains)
.count();
}

// TODO: 추가 기능 구현
public boolean contains(int number) {
return numbers.contains(number);
}

public List<Integer> getNumbers() {
return numbers;
}
}
42 changes: 42 additions & 0 deletions src/main/java/lotto/Rank.java
Original file line number Diff line number Diff line change
@@ -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;
}
}