Skip to content

๐Ÿš€ 3๋‹จ๊ณ„ - ๋กœ๋˜(2๋“ฑ) #4158

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Apr 8, 2025
9 changes: 4 additions & 5 deletions src/main/java/lotto/LottoApplication.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package lotto;

import lotto.domain.Lotto;
import lotto.domain.LottoCalculator;
import lotto.domain.LottoMachine;
import lotto.domain.LottoResult;
import lotto.domain.*;
import lotto.view.InputView;
import lotto.view.ResultView;

Expand All @@ -16,8 +13,10 @@ public static void main(String[] args) {
List<Lotto> lottoList = machine.buy(purchaseAmount);
ResultView.printLotto(lottoList);
List<Integer> winningNumbers = InputView.getWinningNumbers();
int bonusNumber = InputView.getBonusNumber();
LottoWinnings lottoWinnings = new LottoWinnings(winningNumbers, bonusNumber);
LottoCalculator calculator = new LottoCalculator();
LottoResult result = calculator.calculate(purchaseAmount, lottoList, winningNumbers);
LottoResult result = calculator.calculate(purchaseAmount, lottoList, lottoWinnings);
ResultView.printResult(result);
}
}
34 changes: 11 additions & 23 deletions src/main/java/lotto/domain/Lotto.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@
import java.util.*;

public class Lotto {
private final List<Integer> numbers;
public final int MIN_NUMBER = 1;
public final int MAX_NUMBER = 45;
private final List<LottoNumber> numbers;

public Lotto(List<Integer> numbers) {
validateNumbers(numbers);
this.numbers = numbers;
this.numbers = validateNumbers(numbers);
}

private void validateNumbers(List<Integer> numbers) {
private List<LottoNumber> validateNumbers(List<Integer> numbers) {
Objects.requireNonNull(numbers, "numbers must not be null");

List<LottoNumber> lottoNumbers = new ArrayList<>();
for (Integer number : numbers) {
lottoNumbers.add(new LottoNumber(number));
}

if (numbers.size() != 6) {
throw new IllegalArgumentException("Lotto numbers must contain exactly 6 numbers.");
}
Expand All @@ -24,25 +26,11 @@ private void validateNumbers(List<Integer> numbers) {
throw new IllegalArgumentException("Lotto numbers must be unique.");
}

for (Integer number : numbers) {
if (number < MIN_NUMBER || number > MAX_NUMBER) {
throw new IllegalArgumentException("Lotto number " + number + " is out of valid range (1-45).");
}
}
return lottoNumbers;
}

public int countMatches(List<Integer> winningNumbers) {
validateNumbers(winningNumbers);
int count = 0;
for (Integer number : this.numbers) {
if (winningNumbers.contains(number)) {
count++;
}
}
return count;
}

public List<Integer> getNumbers() {
public List<LottoNumber> getNumbers() {
return numbers;
}

}
14 changes: 5 additions & 9 deletions src/main/java/lotto/domain/LottoCalculator.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,13 @@

public class LottoCalculator {

public LottoResult calculate(int purchaseAmount, List<Lotto> lottoList, List<Integer> winningNumbers) {
long totalPrize = 0;
Map<Integer, Integer> matchCounts = new HashMap<>();
public LottoResult calculate(int purchaseAmount, List<Lotto> lottoList, LottoWinnings lottoWinnings) {
Map<LottoPrize, Integer> lottoPrizes = new HashMap<>();
for (Lotto lotto : lottoList) {
int matchCount = lotto.countMatches(winningNumbers);
long prize = LottoPrize.getPrizeByMatchCount(matchCount);
totalPrize += prize;
matchCounts.put(matchCount, matchCounts.getOrDefault(matchCount, 0) + 1);
LottoPrize lottoPrize = lottoWinnings.countMatches(lotto);
lottoPrizes.put(lottoPrize, lottoPrizes.getOrDefault(lottoPrize, 0) + 1);
}
double rate = (double) totalPrize / purchaseAmount;
return new LottoResult(matchCounts, rate);
return new LottoResult(lottoPrizes, purchaseAmount);
}

}
40 changes: 40 additions & 0 deletions src/main/java/lotto/domain/LottoNumber.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package lotto.domain;

import java.util.Objects;

public class LottoNumber {
public static final int MIN_NUMBER = 1;
public static final int MAX_NUMBER = 45;

private final int value;

public LottoNumber(int value) {
if (value < MIN_NUMBER || value > MAX_NUMBER) {
throw new IllegalArgumentException("Lotto number " + value + " is out of valid range (" + MIN_NUMBER + "-" + MAX_NUMBER + ").");
}
this.value = value;
}

public int getValue() {
return value;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof LottoNumber)) return false;
LottoNumber that = (LottoNumber) o;
return value == that.value;
}

@Override
public int hashCode() {
return Objects.hash(value);
}

@Override
public String toString() {
return String.valueOf(value);
}

}
41 changes: 26 additions & 15 deletions src/main/java/lotto/domain/LottoPrize.java
Original file line number Diff line number Diff line change
@@ -1,33 +1,44 @@
package lotto.domain;

public enum LottoPrize {
THREE(3, 5000),
FOUR(4, 50000),
FIVE(5, 1500000),
SIX(6, 2000000000L);
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),
MISS(0, false, 0);
Comment on lines +4 to +9
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿ‘
๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ •ํ™•ํžˆ ํ‘œํ˜„ํ•˜๋ ค๋ฉด, 2๋“ฑ์„ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ ํ•ญ๋ชฉ์€ ๋ณด๋„ˆ์Šค ์—ฌ๋ถ€๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์€ ์ƒํƒœ์—์š”!
๋ณด๋„ˆ์Šค ์—ฌ๋ถ€๋ฅผ ๊ฐ„๊ฒฐํ•œ ํ˜•ํƒœ์˜ enum์œผ๋กœ ๋ฆฌํŒฉํ† ๋งํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ผ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

enum BonusCondition {
    MATCH, 
    MISMATCH, 
    IGNORED;
}


private final int matchCount;
private final long prize;
private final boolean bonus;
private final int winningMoney;

LottoPrize(int matchCount, long prize) {
LottoPrize(int matchCount, boolean bonus, int winningMoney) {
this.matchCount = matchCount;
this.prize = prize;
this.bonus = bonus;
this.winningMoney = winningMoney;
}

public int getMatchCount() {
return matchCount;
}

public long getPrize() {
return prize;
public int getWinningMoney() {
return winningMoney;
}

public static long getPrizeByMatchCount(int count) {
for (LottoPrize lottoPrize : values()) {
if (lottoPrize.getMatchCount() == count) {
return lottoPrize.getPrize();
}
public static LottoPrize from(int matchCount, boolean bonusMatch) {
if (matchCount == 6) {
return FIRST;
}
return 0;
if (matchCount == 5) {
return bonusMatch ? SECOND : THIRD;
}
if (matchCount == 4) {
return FOURTH;
}
if (matchCount == 3) {
return FIFTH;
}
return MISS;
}
}
24 changes: 18 additions & 6 deletions src/main/java/lotto/domain/LottoResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,28 @@
import java.util.Map;

public class LottoResult {
private final Map<Integer, Integer> matchCounts;
private final Map<LottoPrize, Integer> lottoPrizes;
private final double rate;

public LottoResult(Map<Integer, Integer> matchCounts, double rate) {
this.matchCounts = matchCounts;
this.rate = rate;
public LottoResult(Map<LottoPrize, Integer> lottoPrizes, int purchaseAmount) {
this.lottoPrizes = lottoPrizes;
this.rate = calculateRate(purchaseAmount);
}

public Map<Integer, Integer> getMatchCounts() {
return matchCounts;
private long calculateTotalWinningMoney() {
return lottoPrizes.entrySet()
.stream()
.mapToLong(entry -> (long) entry.getKey().getWinningMoney() * entry.getValue())
.sum();
}

public double calculateRate(int purchaseAmount) {
long totalWinningMoney = calculateTotalWinningMoney();
return (double) totalWinningMoney / purchaseAmount;
}

public Map<LottoPrize, Integer> getLottoPrizes() {
return lottoPrizes;
}

public double getRate() {
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/lotto/domain/LottoWinnings.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package lotto.domain;

import java.util.List;

public class LottoWinnings extends Lotto {
private final LottoNumber bonusNumber;

public LottoWinnings(List<Integer> numbers, int bonusNumber) {
super(numbers);
validateBonusNumber(numbers, bonusNumber);
this.bonusNumber = new LottoNumber(bonusNumber);
}

private void validateBonusNumber(List<Integer> numbers, int bonusNumber) {
if (numbers.contains(bonusNumber)) {
throw new IllegalArgumentException("Bonus number must not be one of the winning numbers.");
}
}

public boolean isBonusMatch(LottoNumber number) {
return bonusNumber.equals(number);
}

public LottoPrize countMatches(Lotto lotto) {
int count = 0;
boolean bonusMatch = false;
for (LottoNumber number : lotto.getNumbers()) {
if (getNumbers().contains(number)) {
count++;
}
if (isBonusMatch(number)) {
bonusMatch = true;
}
}
return LottoPrize.from(count, bonusMatch);
}
}
6 changes: 6 additions & 0 deletions src/main/java/lotto/view/InputView.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ public static List<Integer> getWinningNumbers() {
return parseNumbers(input);
}

public static int getBonusNumber() {
System.out.println("๋ณด๋„ˆ์Šค ๋ณผ์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.");
String input = scanner.nextLine();
return Integer.parseInt(input.trim());
}

private static List<Integer> parseNumbers(String input) {
String[] parts = input.split(",");
List<Integer> numbers = new ArrayList<>();
Expand Down
15 changes: 13 additions & 2 deletions src/main/java/lotto/view/ResultView.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lotto.domain.LottoResult;

import java.util.List;
import java.util.Map;

public class ResultView {

Expand All @@ -16,10 +17,20 @@ public static void printLotto(List<Lotto> lottoList) {
}

public static void printResult(LottoResult result) {
Map<LottoPrize, Integer> lottoPrizes = result.getLottoPrizes();
System.out.println("๋‹น์ฒจ ํ†ต๊ณ„");
System.out.println("---------");
for (int i = 3; i <= 6; i++) {
System.out.println(i + "๊ฐœ ์ผ์น˜ (" + LottoPrize.getPrizeByMatchCount(i) + "์›)- " + result.getMatchCounts().getOrDefault(i, 0) + "๊ฐœ");
for (Map.Entry<LottoPrize, Integer> entry : lottoPrizes.entrySet()) {
LottoPrize lottoPrize = entry.getKey();
int lottoPrizeCount = entry.getValue();
if (lottoPrize == LottoPrize.MISS) {
continue;
}
if (lottoPrize == LottoPrize.SECOND) {
System.out.println(lottoPrize.getMatchCount() + "๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (" + lottoPrize.getWinningMoney() + "์›)- " + lottoPrizeCount + "๊ฐœ");
continue;
}
System.out.println(lottoPrize.getMatchCount() + "๊ฐœ ์ผ์น˜ (" + lottoPrize.getWinningMoney() + "์›)- " + lottoPrizeCount + "๊ฐœ");
}
System.out.printf("์ด ์ˆ˜์ต๋ฅ ์€ %,.2f์ž…๋‹ˆ๋‹ค.%n", result.getRate());
}
Expand Down
48 changes: 48 additions & 0 deletions src/test/java/lotto/domain/LottoPrizeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package lotto.domain;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class LottoPrizeTest {

@Test
@DisplayName("๋งค์น˜ 6๊ฐœ์ผ ๊ฒฝ์šฐ FIRST ๋ฐ˜ํ™˜ ํ™•์ธ")
public void testFirstPrize() {
assertEquals(LottoPrize.FIRST, LottoPrize.from(6, false));
}

@Test
@DisplayName("๋งค์น˜ 5๊ฐœ + ๋ณด๋„ˆ์Šค ๋งค์น˜์ผ ๊ฒฝ์šฐ SECOND ๋ฐ˜ํ™˜ ํ™•์ธ")
public void testSecondPrize() {
assertEquals(LottoPrize.SECOND, LottoPrize.from(5, true));
}

@Test
@DisplayName("๋งค์น˜ 5๊ฐœ์ด๋‚˜ ๋ณด๋„ˆ์Šค ๋ฏธ๋งค์น˜์ผ ๊ฒฝ์šฐ THIRD ๋ฐ˜ํ™˜ ํ™•์ธ")
public void testThirdPrize() {
assertEquals(LottoPrize.THIRD, LottoPrize.from(5, false));
}

@Test
@DisplayName("๋งค์น˜ 4๊ฐœ์ผ ๊ฒฝ์šฐ FOURTH ๋ฐ˜ํ™˜ ํ™•์ธ")
public void testFourthPrize() {
assertEquals(LottoPrize.FOURTH, LottoPrize.from(4, true));
assertEquals(LottoPrize.FOURTH, LottoPrize.from(4, false));
}

@Test
@DisplayName("๋งค์น˜ 3๊ฐœ์ผ ๊ฒฝ์šฐ FIFTH ๋ฐ˜ํ™˜ ํ™•์ธ")
public void testFifthPrize() {
assertEquals(LottoPrize.FIFTH, LottoPrize.from(3, true));
assertEquals(LottoPrize.FIFTH, LottoPrize.from(3, false));
}

@Test
@DisplayName("๋งค์น˜๊ฐ€ 2๊ฐœ ์ดํ•˜์ธ ๊ฒฝ์šฐ MISS ๋ฐ˜ํ™˜ ํ™•์ธ")
public void testMissPrize() {
assertEquals(LottoPrize.MISS, LottoPrize.from(2, false));
assertEquals(LottoPrize.MISS, LottoPrize.from(0, false));
}
}
1 change: 0 additions & 1 deletion src/test/java/lotto/domain/LottoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ public void testDuplicateNumbers() {
@Test
@DisplayName("๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ๋ฒˆํ˜ธ๊ฐ€ ์žˆ์„ ๋•Œ IllegalArgumentException ๋ฐœ์ƒ ํ™•์ธ")
public void testOutOfRangeNumbers() {
// 0์€ ์œ ํšจ ๋ฒ”์œ„(1~45)๋ฅผ ๋ฒ—์–ด๋‚จ
List<Integer> numbers = Arrays.asList(0, 2, 3, 4, 5, 6);
assertThrows(IllegalArgumentException.class, () -> new Lotto(numbers));
}
Expand Down