Skip to content

Commit fd11412

Browse files
authored
step3 - 로또(2등) (#4223)
* feat: 로또 2등 추가 * feat: 당첨로또 6개의 번호 + 보너스 번호 합친 객체 생성 * feat: LottoNumber 캐싱 * fix: 3개 맞고 보너스 맞으면 MISS 반환 -> FIFTH 반환
1 parent 3784ba1 commit fd11412

File tree

14 files changed

+201
-55
lines changed

14 files changed

+201
-55
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,10 @@
4747
* 로또 숫자 생성
4848
* 로또 구매
4949
* 지난 주 당첨 번호 입력
50-
* 당첨 통계
50+
* 당첨 통계
51+
52+
## 3단계 - 로또(2등)
53+
54+
### 요구사항
55+
* 2등을 위해 추가 번호를 하나 더 추첨한다.
56+
* 당첨 통계에 2등도 추가해야 한다.

src/main/java/lotto/LottoMain.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package lotto;
22

3-
import lotto.domain.Lotto;
4-
import lotto.domain.LottoGroup;
5-
import lotto.domain.LottoResult;
6-
import lotto.domain.Money;
3+
import lotto.domain.*;
74
import lotto.view.InputView;
85
import lotto.view.ResultView;
96

@@ -17,7 +14,9 @@ public static void main(String[] args) {
1714

1815
Lotto winLotto = new Lotto(InputView.getInputWinNumber());
1916

20-
LottoResult result = lottoGroup.match(winLotto);
17+
LottoNumber bonusNumber = LottoNumber.valueOf(InputView.getInputBonusNumber());
18+
19+
LottoResult result = lottoGroup.match(new LottoWinningNumbers(winLotto, bonusNumber));
2120

2221
ResultView.showStatus(result, money);
2322
}

src/main/java/lotto/domain/Lotto.java

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,32 +21,22 @@ public Lotto(List<LottoNumber> numbers) {
2121

2222
private static List<LottoNumber> stringToList(String... numbers) {
2323
return Arrays.stream(numbers)
24-
.map(LottoNumber::new)
24+
.map(LottoNumber::valueOf)
2525
.toList();
2626
}
2727

2828
private static List<LottoNumber> intToList(int... numbers) {
2929
return Arrays.stream(numbers)
30-
.mapToObj(LottoNumber::new)
30+
.mapToObj(LottoNumber::valueOf)
3131
.toList();
3232
}
3333

34-
public LottoRank determineRank(Lotto lotto) {
35-
return LottoRank.getLottoRank(lotto.countMatchedNumbers(this.numbers));
34+
public int countMatchedNumbers(Lotto winningLotto) {
35+
return (int) numbers.stream().filter(winningLotto::contains).count();
3636
}
3737

38-
public int countMatchedNumbers(List<LottoNumber> lottoNumbers) {
39-
int cnt = 0;
40-
41-
for (LottoNumber lottoNumber: lottoNumbers) {
42-
cnt += containsNumber(lottoNumber);
43-
}
44-
45-
return cnt;
46-
}
47-
48-
private int containsNumber(LottoNumber number) {
49-
return this.numbers.contains(number) ? 1 : 0;
38+
public boolean contains(LottoNumber bonusNumber) {
39+
return this.numbers.contains(bonusNumber);
5040
}
5141

5242
@Override

src/main/java/lotto/domain/LottoGroup.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ public List<Lotto> getLottoNumbers() {
2929
return lottos;
3030
}
3131

32-
public LottoResult match(Lotto winLotto) {
33-
return calculate(winLotto);
32+
public LottoResult match(LottoWinningNumbers winLottoWinningNumbers) {
33+
return calculate(winLottoWinningNumbers);
3434
}
3535

36-
private LottoResult calculate(Lotto winLotto) {
36+
private LottoResult calculate(LottoWinningNumbers winLottoWinningNumbers) {
3737
LottoResult lottoResult = new LottoResult();
3838

3939
for (Lotto lotto : this.lottos) {
40-
LottoRank rank = lotto.determineRank(winLotto);
40+
LottoRank rank = winLottoWinningNumbers.determineRank(lotto);
4141

4242
lottoResult.rank(rank);
4343
}

src/main/java/lotto/domain/LottoNumber.java

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,39 @@
11
package lotto.domain;
22

3+
import java.util.HashMap;
4+
import java.util.Map;
35
import java.util.Objects;
46

57
public class LottoNumber {
6-
private final int number;
8+
private static final int MIN = 1;
9+
private static final int MAX = 45;
10+
private static final Map<Integer, LottoNumber> CACHE_NUM = new HashMap<>();
711

8-
public LottoNumber(String number) {
9-
this(Integer.parseInt(number));
12+
static{
13+
for (int i = MIN; i <= MAX; i++){
14+
CACHE_NUM.put(i, new LottoNumber(i));
15+
}
1016
}
1117

18+
private final int number;
19+
1220
public LottoNumber(int number) {
1321
validation(number);
1422
this.number = number;
1523
}
16-
private void validation(int number) {
17-
if (number < 1 || number > 45) {
24+
25+
public static LottoNumber valueOf(String number){
26+
validation(Integer.parseInt(number));
27+
return CACHE_NUM.get(Integer.parseInt(number));
28+
}
29+
30+
public static LottoNumber valueOf(int number){
31+
validation(number);
32+
return CACHE_NUM.get(number);
33+
}
34+
35+
private static void validation(int number) {
36+
if (number < MIN || number > MAX) {
1837
throw new RuntimeException("로또 번호는 1부터 45입니다.");
1938
}
2039
}

src/main/java/lotto/domain/LottoRank.java

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,46 @@
11
package lotto.domain;
22

3+
import java.util.Arrays;
4+
35
public enum LottoRank {
4-
MISS(0,0),
5-
THIRD(3, 5_000),
6-
FOUR(4, 50_000),
7-
FIVE(5, 1_500_000),
8-
SIX(6, 2_000_000_000),
6+
FIRST(6, 2_000_000_000, false),
7+
SECOND(5, 30_000_000, true),
8+
THIRD(5, 1_500_000, false),
9+
FOURTH(4, 50_000, false),
10+
FIFTH(3, 5_000, false),
11+
MISS(0, 0, false),
912
;
1013

1114
private final int matchCnt;
1215
private final int prizeMoney;
16+
private final boolean bonusMatched;
1317

14-
LottoRank(int matchCnt, int prizeMoney) {
18+
LottoRank(int matchCnt, int prizeMoney, boolean bonusMatched) {
1519
this.matchCnt = matchCnt;
1620
this.prizeMoney = prizeMoney;
21+
this.bonusMatched = bonusMatched;
22+
}
23+
24+
public static LottoRank getLottoRank(int matchCnt, boolean bonusMatched) {
25+
return Arrays.stream(values())
26+
.filter(rank -> rank.matches(matchCnt, bonusMatched))
27+
.findFirst()
28+
.orElse(MISS);
1729
}
1830

19-
public static LottoRank getLottoRank(int matchCnt) {
20-
for(LottoRank lottoRank : LottoRank.values()) {
21-
if(lottoRank.matchCnt == matchCnt) {
22-
return lottoRank;
23-
}
31+
private boolean matches(int matchCnt, boolean bonusMatched) {
32+
if (this.matchCnt != matchCnt) {
33+
return false;
2434
}
25-
return LottoRank.MISS;
35+
36+
if (matchCnt == 5) {
37+
return this.bonusMatched == bonusMatched;
38+
}
39+
40+
return true;
2641
}
2742

43+
2844
public int getMatchCnt() {
2945
return matchCnt;
3046
}
@@ -33,6 +49,16 @@ public int getPrizeMoney() {
3349
return prizeMoney;
3450
}
3551

52+
public String getMessage(int count) {
53+
if (this == SECOND) {
54+
return String.format("%d개 일치, 보너스 볼 일치 (%d원) - %d개",
55+
matchCnt, prizeMoney, count);
56+
}
57+
return String.format("%d개 일치 (%d원) - %d개",
58+
matchCnt, prizeMoney, count);
59+
}
60+
61+
3662
public boolean isAddAble() {
3763
return this != LottoRank.MISS;
3864
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package lotto.domain;
2+
3+
public class LottoWinningNumbers {
4+
private final Lotto winningLotto;
5+
private final LottoNumber bonusNumber;
6+
7+
public LottoWinningNumbers(Lotto winningLotto, LottoNumber bonusNumber) {
8+
this.winningLotto = winningLotto;
9+
this.bonusNumber = bonusNumber;
10+
}
11+
12+
public int getBonusNumber() {
13+
return this.bonusNumber.value();
14+
}
15+
16+
public LottoRank determineRank(Lotto lotto) {
17+
return LottoRank.getLottoRank(countMatchedNumbers(lotto), containsBonusNumber(lotto));
18+
}
19+
20+
private boolean containsBonusNumber(Lotto lotto) {
21+
return lotto.contains(this.bonusNumber);
22+
}
23+
24+
private int countMatchedNumbers(Lotto lotto) {
25+
return lotto.countMatchedNumbers(this.winningLotto);
26+
}
27+
}

src/main/java/lotto/view/InputView.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ public static String[] getInputWinNumber() {
1818
return parse(scanner.nextLine());
1919
}
2020

21+
public static int getInputBonusNumber() {
22+
System.out.println("보너스 볼을 입력해 주세요.");
23+
return Integer.parseInt(scanner.nextLine());
24+
}
25+
2126
private static String[] parse(String s) {
2227
String[] strs = s.split(",");
2328

src/main/java/lotto/view/ResultView.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@ public static void showStatus(LottoResult lottoResult, Money money) {
1818

1919
for (LottoRank lottoRank : LottoRank.values()) {
2020
if (lottoRank == LottoRank.MISS) continue;
21-
System.out.printf("%d개 일치 (%d원)- %d개%n", lottoRank.getMatchCnt(), lottoRank.getPrizeMoney(), lottoResult.getCntByLottoRank(lottoRank));
21+
22+
int count = lottoResult.getCntByLottoRank(lottoRank);
23+
System.out.println(lottoRank.getMessage(count));
2224
}
2325

24-
System.out.printf("총 수익률은 %.2f입니다.(기준이 1이기 때문에 결과적으로 손해라는 의미임)", money.getYield(lottoResult.calTotal()));
26+
System.out.printf("총 수익률은 %.2f입니다.(기준이 1이기 때문에 결과적으로 손해라는 의미임)",
27+
money.getYield(lottoResult.calTotal()));
2528
}
2629
}

src/test/java/lotto/domain/LottoNumberTest.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,21 @@
77
public class LottoNumberTest {
88
@Test
99
void create() {
10-
LottoNumber lottoNumber = new LottoNumber(1);
10+
LottoNumber lottoNumber = LottoNumber.valueOf(1);
1111

1212
assertThat(lottoNumber.value()).isEqualTo(1);
1313
}
1414

1515
@Test
1616
void 로또의_범위는_1에서_45이다() {
17-
assertThatThrownBy(() -> new LottoNumber(46))
17+
assertThatThrownBy(() -> LottoNumber.valueOf(46))
1818
.isInstanceOf(RuntimeException.class)
1919
.hasMessageContaining("로또 번호는 1부터 45입니다.");
2020

2121
}
22+
23+
@Test
24+
void 로또_번호_캐시한_결과() {
25+
assertThat(LottoNumber.valueOf(1)).isEqualTo(LottoNumber.valueOf(1));
26+
}
2227
}

0 commit comments

Comments
 (0)