-
Notifications
You must be signed in to change notification settings - Fork 92
[그리디] 이고은 로또 미션 3, 4, 5단계 제출합니다. #144
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
base: ke-62
Are you sure you want to change the base?
Changes from 25 commits
01a15d2
b74016a
c56ec71
e7fdac1
7c0f366
8d25d65
aa93828
712355d
5483100
a950c6d
32e4236
db12651
3ee3b9e
a7f1d52
c1a8a28
684a177
bb099d0
c0a617d
0a3d25d
a195cdd
31cf72e
448f371
461131a
58cf0ec
fff7970
7995e01
ebf2453
f157862
050a96b
b2ca2bc
43244b9
0e25574
9326c01
cea3d80
0f760a5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| ## 로또 미션 1-5단계 | ||
|
|
||
| ### 기능 요구사항 | ||
|
|
||
| #### 1단계 | ||
| - 사용자는 로또 구매 금액을 입력할 수 있다. | ||
| - 로또 가격은 1,000원이다. | ||
| - 사용자는 구매 금액에 해당하는 로또를 자동으로 발급받는다. | ||
| - 1~45 사이의 숫자 중 6개를 랜덤으로 선택한다. | ||
| - 겹치는 숫자는 있으면 안 된다. | ||
| - 로또 번호는 크기 순서대로 정렬되어야 한다. | ||
|
|
||
| #### 2단계 | ||
| - 사용자는 당첨 번호를 입력할 수 있다. | ||
| - 일치한 번호 수에 따른 당첨 금액을 알려준다. | ||
| - 3개 일치: 5000원 | ||
| - 4개 일치: 50000원 | ||
| - 5개 일치: 1500000원 | ||
| - 5개 일치: 30000000원 | ||
| - 6개 일치: 2000000000원 | ||
| - 총 수익률을 알려준다. | ||
| - 수익률 = (총 당첨 금액) / (총 구매 금액) | ||
| - 소수점 둘째 자리까지 표시한다. | ||
| - 1미만시 손해이고 1이상이면 이득이다. | ||
|
|
||
| #### 3단계 | ||
| - 보너스볼이 들어온다 | ||
| - 5개 일치 + 보너스볼 일치: 30000000원 | ||
| - 5개 일치 + 보너스볼 일치하지 않음 : 1500000원 | ||
|
|
||
| #### 4단계 | ||
| - 사용자는 수동으로 구매할 로또 수를 입력할 수 있다. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,10 @@ | ||
| plugins { | ||
| id 'java' | ||
| id 'application' | ||
| } | ||
|
|
||
| application { | ||
| mainClass = 'Main' | ||
| } | ||
|
|
||
| group = 'cholog' | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| import controller.LottoController; | ||
|
|
||
| public class Main { | ||
| public static void main(String[] args) { | ||
|
|
||
| LottoController lottoController = new LottoController(); | ||
| lottoController.run(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| package controller; | ||
|
|
||
| import domain.Lotto; | ||
| import domain.LottoNumber; | ||
| import domain.LottoService; | ||
| import domain.LottoTicketCount; | ||
| import domain.LottoTickets; | ||
| import domain.LottoTotalPrice; | ||
| import domain.Money; | ||
| import domain.MatchCount; | ||
| import domain.ProfitRate; | ||
| import view.InputView; | ||
| import view.OutputView; | ||
| import view.ResultView; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
|
|
||
| public class LottoController { | ||
| OutputView outputView = new OutputView(); | ||
| InputView inputView = new InputView(); | ||
| ResultView resultView = new ResultView(); | ||
|
|
||
| public void run() { | ||
| outputView.printWonMessage(); | ||
| Money money = new Money(inputView.inputMoney()); | ||
|
|
||
| LottoTickets lottoTickets = buyLotto(money); | ||
| checkLotto(lottoTickets, money); | ||
| } | ||
|
|
||
|
|
||
| public LottoTickets buyLotto(Money money) { | ||
| LottoTicketCount ticketNumber = Money.getTicketCount(money); | ||
|
||
| resultView.printTicketNumbers(ticketNumber.getCount()); | ||
|
|
||
| outputView.printManualCount(); | ||
| int manualCount = inputView.inputManualCount(); | ||
|
|
||
| List<Lotto> manualLottos = new ArrayList<>(); | ||
| outputView.printManualNumbers(); | ||
|
|
||
| LottoService lottoService = new LottoService(); | ||
| for (int i = 0; i < manualCount; i++) { | ||
| String manualNumbers = inputView.inputManualNumbers(); | ||
| manualLottos.add(lottoService.parseLottoAnswer(manualNumbers)); | ||
|
|
||
| } | ||
|
|
||
| int autoCount = ticketNumber.getCount() - manualCount; | ||
|
|
||
| resultView.printManualAuto(manualCount, autoCount); | ||
| outputView.lottoResult(); | ||
| LottoTickets lottoTickets = LottoTickets.createMixedTickets(manualLottos, autoCount); | ||
|
|
||
| for (Lotto lotto : lottoTickets.getTickets()) { | ||
| System.out.println(lotto); | ||
| } | ||
|
|
||
| return lottoTickets; | ||
| } | ||
|
|
||
|
|
||
| public void checkLotto(LottoTickets tickektAutoCount, Money money) { | ||
| outputView.printLottoAnswer(); | ||
|
|
||
| LottoService lottoService = new LottoService(); | ||
| String lottoAnswer = inputView.inputLottoAnswer(); | ||
| outputView.printBonusMessage(); | ||
| int bonusBallNumber = inputView.inputBonusNumber(); | ||
| LottoNumber bonuseBall = new LottoNumber(bonusBallNumber); | ||
|
|
||
| Lotto lottoAnswerObj = lottoService.parseLottoAnswer(lottoAnswer); | ||
| lottoService.validateBonusBall(lottoAnswerObj, bonuseBall); | ||
|
|
||
| MatchCount matchCount = lottoService.calculateMatchCount(tickektAutoCount.getTickets(), lottoAnswerObj, bonuseBall); | ||
|
|
||
| ProfitRate profitRate = new ProfitRate(money, new LottoTotalPrice(matchCount)); | ||
|
|
||
| outputView.lottoResult(); | ||
| resultView.printLottoMatch(matchCount); | ||
| resultView.printLottoProfit(profitRate.getProfitRate()); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| package domain; | ||
|
|
||
| import java.util.SortedSet; | ||
| import java.util.TreeSet; | ||
|
|
||
| public class Lotto { | ||
| private final SortedSet<LottoNumber> numbers; | ||
|
|
||
| public Lotto(SortedSet<LottoNumber> numbers) { | ||
| if (numbers.size() != createList.LOTTO_NUMBER_COUNT) { | ||
| throw new IllegalArgumentException("로또 숫자는 6개여야 하며, 중복될 수 없습니다."); | ||
| } | ||
| this.numbers = new TreeSet<>(numbers); | ||
| } | ||
|
|
||
| public int contains(LottoNumber number) { | ||
| if (numbers.contains(number)) return 1; | ||
| return 0; | ||
| } | ||
|
|
||
| public SortedSet<LottoNumber> getNumbers() { | ||
| return new TreeSet<>(numbers); | ||
| } | ||
|
Comment on lines
26
to
28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 방어적 복사를 하고 싶은 의도가 가장 컸습니다. 처음에는 반환 타입이 SortedSet이니 그대로 생성할 수 있을 거라 생각했는데, SortedSet은 인터페이스라 직접 인스턴스를 만들 수 없어서 정렬과 중복 제거 특성을 가진 대표 구현체인 TreeSet으로 복사하여 반환하도록 했습니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 처음에는 List를 사용해 코드를 작성했지만, 중복 체크와 정렬을 직접 처리해야 하는 불편함이 있었습니다. 1, 2단계 리뷰어님께서 “적절한 자료구조를 사용하면 코드가 훨씬 간결해진다”는 조언을 주셔서 여러 자료구조를 공부한 끝에 Set을 선택했습니다. |
||
|
|
||
| @Override | ||
| public String toString() { | ||
| return numbers.toString(); | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| package domain; | ||
|
|
||
| public class LottoNumber implements Comparable<LottoNumber> { | ||
| private final int number; | ||
|
|
||
| public LottoNumber(int number) { | ||
| if (number < createList.LOTTO_MIN_NUMBER || number > createList.LOTTO_MAX_NUMBER) { | ||
| throw new IllegalArgumentException("로또 번호는 1부터 45 사이의 숫자여야 합니다."); | ||
| } | ||
| this.number = number; | ||
| } | ||
|
|
||
| public int getNumber() { | ||
| return number; | ||
| } | ||
|
|
||
| @Override | ||
| public int compareTo(LottoNumber o) { | ||
| return Integer.compare(this.number, o.number); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean equals(Object o) { | ||
| if (this == o) return true; | ||
| if (o == null || getClass() != o.getClass()) return false; | ||
| LottoNumber that = (LottoNumber) o; | ||
| return number == that.number; | ||
| } | ||
|
|
||
| @Override | ||
| public int hashCode() { | ||
| return number; | ||
| } | ||
|
|
||
| public String toString() { | ||
| return String.valueOf(number); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package domain; | ||
|
|
||
| public enum LottoPrice { | ||
| MATCH_3(5000), | ||
| MATCH_4(50000), | ||
| MATCH_5(1500000), | ||
| MATCH_5_BONUS(30000000), | ||
| MATCH_6(2000000000); | ||
|
|
||
| private final int price; | ||
|
|
||
| LottoPrice(int price) { | ||
| this.price = price; | ||
| } | ||
|
|
||
| public int getPrice() { | ||
| return price; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package domain; | ||
|
|
||
| import java.util.List; | ||
| import java.util.SortedSet; | ||
| import java.util.TreeSet; | ||
|
|
||
| public class LottoService { | ||
| public Lotto parseLottoAnswer(String lottoAnswer) { | ||
| SortedSet<LottoNumber> numbers = new TreeSet<>(); | ||
| for (String num : lottoAnswer.split(",")) { | ||
| numbers.add(new LottoNumber(Integer.parseInt(num.trim()))); | ||
| } | ||
| return new Lotto(numbers); | ||
| } | ||
|
|
||
| public void validateBonusBall(Lotto answer, LottoNumber bonusBall) { | ||
| if (answer.getNumbers().contains(bonusBall)) { | ||
| throw new IllegalArgumentException("보너스 볼은 당첨 번호와 중복될 수 없습니다."); | ||
| } | ||
| } | ||
|
|
||
| public MatchCount calculateMatchCount(List<Lotto> tickets, Lotto answer, LottoNumber bonusBall) { | ||
| return MatchCount.calculateStatistics(tickets, answer, bonusBall); | ||
| } | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package domain; | ||
|
|
||
| public class LottoTicketCount { | ||
| private final int count; | ||
|
|
||
| public LottoTicketCount(int count) { | ||
| this.count = count; | ||
| } | ||
|
|
||
| public int getCount() { | ||
| return count; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| package domain; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
| import java.util.Set; | ||
| import java.util.SortedSet; | ||
| import java.util.TreeSet; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| public class LottoTickets { | ||
| private List<Lotto> tickets; | ||
|
|
||
| public LottoTickets() { | ||
| this.tickets = new ArrayList<>(); | ||
| } | ||
|
|
||
| public static LottoTickets createMixedTickets(List<Lotto> manualLottos, int autoCount) { | ||
| LottoTickets lottoTickets = new LottoTickets(); | ||
|
|
||
| lottoTickets.tickets.addAll(manualLottos); | ||
|
|
||
| for (int i = 0; i < autoCount; i++) { | ||
| Set<Integer> generatedNumbers = createList.generateLottoNumbers(); | ||
| if (generatedNumbers.size() != 6) { | ||
| throw new IllegalArgumentException("로또 번호에 중복된 숫자가 있습니다."); | ||
| } | ||
| SortedSet<LottoNumber> lottoNumbers = generatedNumbers.stream().map(LottoNumber::new).collect(Collectors.toCollection(TreeSet::new)); | ||
| lottoTickets.tickets.add(new Lotto(lottoNumbers)); | ||
| } | ||
|
|
||
| return lottoTickets; | ||
| } | ||
|
|
||
| public List<Lotto> getTickets() { | ||
| return tickets; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package domain; | ||
|
|
||
| import java.util.Arrays; | ||
|
|
||
| public class LottoTotalPrice { | ||
| private final long totalSum; | ||
|
|
||
| public LottoTotalPrice(MatchCount matchCount) { | ||
| this.totalSum = calculateTotalSum(matchCount); | ||
| } | ||
|
|
||
| private long calculateTotalSum(MatchCount matchCount) { | ||
| return Arrays.stream(LottoPrice.values()).mapToLong(price -> (long) matchCount.getCount(price) * price.getPrice()).sum(); | ||
| } | ||
|
|
||
| public long getTotalSum() { | ||
| return totalSum; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package domain; | ||
|
|
||
| public class Match { | ||
|
|
||
| public static int getMatchCount(Lotto lotto, Lotto lottoAnswer) { | ||
| int matchCount = 0; | ||
|
|
||
| for (LottoNumber number : lotto.getNumbers()) { | ||
| if (lottoAnswer.getNumbers().contains(number)) { | ||
| matchCount++; | ||
| } | ||
| } | ||
| return matchCount; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5단계 요구사항이 없어 보이는데 확인 부탁드려요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5단계는 리팩토링이라 크게 적은게 없긴 한데, 추가해 두겠습니다!!