-
Notifications
You must be signed in to change notification settings - Fork 1.1k
로또 - 2단계 PR요청드립니다 #4220
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
로또 - 2단계 PR요청드립니다 #4220
Changes from all commits
1e74285
1c52a14
72e1ab2
be061d3
3bb2bd6
98d7b01
e67feb0
220311b
825337e
5997498
b97a1a8
32139a4
3f27e24
70c380c
ea81f46
888683b
fb651e6
7365bbe
f0da2f1
b6564e0
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,20 @@ | ||
| package lotto; | ||
|
|
||
| import lotto.domain.Lotto; | ||
| import lotto.domain.LottoGame; | ||
| import lotto.domain.LottoResult; | ||
| import lotto.view.InputView; | ||
| import lotto.view.ResultView; | ||
|
|
||
| public class Main { | ||
| public static void main(String[] args) { | ||
| long price = InputView.initLottoPrice(); | ||
| LottoGame lottoGame = new LottoGame(price); | ||
| ResultView.printLottos(lottoGame.lottos()); | ||
|
|
||
| Lotto winningLotto = new Lotto(InputView.initWinningLotto()); | ||
| LottoResult result = lottoGame.check(winningLotto); | ||
| ResultView.printResult(result, lottoGame); | ||
|
|
||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,75 @@ | ||||||
| package lotto.domain; | ||||||
|
|
||||||
| import java.util.*; | ||||||
|
|
||||||
| public class Lotto { | ||||||
| public static final int LOTTO_NUMBER_SIZE = 6; | ||||||
|
|
||||||
| private final Set<Integer> numbers; | ||||||
|
|
||||||
| public Lotto() { | ||||||
| this(new TreeSet<>(LottoFactory.generateLotto())); | ||||||
| } | ||||||
|
|
||||||
| public Lotto(String value) { | ||||||
| this(splitAndParseInt(value)); | ||||||
| } | ||||||
|
|
||||||
| private static Set<Integer> splitAndParseInt(String value) { | ||||||
| String[] split = getSplit(value); | ||||||
| Set<Integer> numbers = strToIntSet(split); | ||||||
| return numbers; | ||||||
| } | ||||||
|
|
||||||
| private static Set<Integer> strToIntSet(String[] split) { | ||||||
| Set<Integer> numbers = new TreeSet<>(); | ||||||
| for (String s : split) { | ||||||
| numbers.add(Integer.parseInt(s)); | ||||||
| } | ||||||
| return numbers; | ||||||
| } | ||||||
|
|
||||||
| private static String[] getSplit(String value) { | ||||||
| return value.split(","); | ||||||
| } | ||||||
|
|
||||||
| public Lotto(Integer... numbers) { | ||||||
| this(new TreeSet<>(Arrays.asList(numbers))); | ||||||
| } | ||||||
|
|
||||||
| public Lotto(Set<Integer> numbers) { | ||||||
| validate(numbers); | ||||||
| this.numbers = Collections.unmodifiableSet(numbers); | ||||||
| } | ||||||
|
|
||||||
| private void validate(Set<Integer> numbers) { | ||||||
| if (numbers.size() != LOTTO_NUMBER_SIZE) { | ||||||
| throw new IllegalArgumentException(); | ||||||
| } | ||||||
|
|
||||||
| boolean invalidNumber = numbers.stream() | ||||||
| .anyMatch(n -> n < 1 || n > 45); | ||||||
| if (invalidNumber) { | ||||||
| throw new IllegalArgumentException(); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| public int match(Lotto winningLotto) { | ||||||
|
Contributor
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.
Suggested change
int보다 Rank로 반환하면 어떨까? |
||||||
| int count = 0; | ||||||
| for (Integer number : numbers) { | ||||||
| if (winningLotto.numbers().contains(number)) { | ||||||
| count++; | ||||||
| } | ||||||
| } | ||||||
| return count; | ||||||
| } | ||||||
|
|
||||||
| private Set<Integer> numbers() { | ||||||
| return numbers; | ||||||
| } | ||||||
|
|
||||||
| @Override | ||||||
| public String toString() { | ||||||
| return numbers.toString(); | ||||||
| } | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| package lotto.domain; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
| import java.util.stream.Collectors; | ||
| import java.util.stream.IntStream; | ||
|
|
||
| public class LottoFactory { | ||
|
|
||
| private static final List<Integer> DEFAULT_NUMBERS = IntStream | ||
|
Contributor
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. 데이터 재사용 👍 |
||
| .rangeClosed(1, 45) | ||
| .boxed() | ||
| .collect(Collectors.toList()); | ||
|
|
||
| private static final int LOTTO_SIZE = 6; | ||
|
|
||
| public static List<Integer> generateLotto() { | ||
| Collections.shuffle(DEFAULT_NUMBERS); | ||
| List<Integer> lottoNumbers = DEFAULT_NUMBERS.subList(0, LOTTO_SIZE); | ||
| Collections.sort(lottoNumbers); | ||
| return new ArrayList<>(lottoNumbers); | ||
| } | ||
|
|
||
| public static List<Lotto> generateLottos(int count) { | ||
| List<Lotto> list = new ArrayList<>(); | ||
| for (int i = 0; i < count; i++) { | ||
| list.add(new Lotto()); | ||
| } | ||
| return list; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| package lotto.domain; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class LottoGame { | ||
| private final Lottos lottos; | ||
| private final Money money; | ||
|
|
||
| public LottoGame(long amount) { | ||
| this(new Money(amount)); | ||
| } | ||
|
|
||
| public LottoGame(Money money) { | ||
| this(new Lottos(money.buyCount()), money); | ||
| } | ||
|
|
||
| public LottoGame(Lottos lottos, Money money) { | ||
| this.lottos = lottos; | ||
| this.money = money; | ||
| } | ||
|
|
||
| public List<Lotto> lottos() { | ||
| return lottos.values(); | ||
| } | ||
|
|
||
| public LottoResult check(Lotto winningLotto) { | ||
| return lottos.findResult(winningLotto); | ||
| } | ||
|
|
||
| public double rateOfReturn(LottoResult result) { | ||
| return money.rateOfReturn(result.getTotal()); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| package lotto.domain; | ||
|
|
||
| import java.util.HashMap; | ||
| import java.util.Map; | ||
|
|
||
| public class LottoResult { | ||
| private final Map<Rank, Integer> lottoResult = new HashMap<>(); | ||
|
Contributor
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. 일급 콜렉션 👍 |
||
|
|
||
| public LottoResult() { | ||
| for (Rank rank : Rank.values()) { | ||
| lottoResult.put(rank, 0); | ||
| } | ||
| } | ||
|
|
||
| public void addMatch(int match) { | ||
| Rank rank = Rank.from(match); | ||
| lottoResult.put(rank, lottoResult.get(rank) + 1); | ||
| } | ||
|
|
||
| public int getCount(Rank rank) { | ||
| return lottoResult.get(rank); | ||
| } | ||
|
|
||
| public long getTotal() { | ||
| return lottoResult.entrySet().stream() | ||
| .mapToLong(entry -> entry.getKey().prize() * entry.getValue()) | ||
| .sum(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package lotto.domain; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class Lottos { | ||
| private final List<Lotto> lottos; | ||
|
|
||
| public Lottos(int count) { | ||
| this(LottoFactory.generateLottos(count)); | ||
| } | ||
|
|
||
| public Lottos(List<Lotto> lottos) { | ||
| this.lottos = lottos; | ||
| } | ||
|
|
||
| public List<Lotto> values() { | ||
| return lottos; | ||
| } | ||
|
|
||
| public LottoResult findResult(Lotto winningLotto) { | ||
|
Contributor
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. 👍 |
||
| LottoResult result = new LottoResult(); | ||
| for (Lotto lotto : lottos) { | ||
| int match = lotto.match(winningLotto); | ||
| result.addMatch(match); | ||
| } | ||
| return result; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package lotto.domain; | ||
|
|
||
| public interface Matchable { | ||
| boolean isMatch(int matchCount); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package lotto.domain; | ||
|
|
||
| public class Money { | ||
| private static final long LOTTO_PRICE = 1_000; | ||
|
|
||
| private final long money; | ||
|
|
||
| public Money(long money) { | ||
| validate(money); | ||
| this.money = money; | ||
| } | ||
|
|
||
| private void validate(long money) { | ||
| if (money < LOTTO_PRICE) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| } | ||
|
|
||
| public int buyCount() { | ||
| return (int) (money / LOTTO_PRICE); | ||
| } | ||
|
|
||
| public double rateOfReturn(long getTotal) { | ||
| return Math.round((double) (getTotal / money) * 100) / 100.0; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| package lotto.domain; | ||
|
|
||
| import java.util.Arrays; | ||
|
|
||
| public enum Rank { | ||
| FIRST(6, 2_000_000_000), | ||
| THIRD(5, 1_500_000), | ||
| FOURTH(4, 50_000), | ||
| FIFTH(3, 5_000), | ||
| NONE(0, 0); | ||
|
|
||
| private final int match; | ||
| private final int prize; | ||
|
|
||
| Rank(int match, int prize) { | ||
| this.match = match; | ||
| this.prize = prize; | ||
| } | ||
|
|
||
| public int prize() { | ||
| return prize; | ||
| } | ||
|
|
||
| public int match() { | ||
| return match; | ||
| } | ||
|
|
||
| public boolean isMatch(int match) { | ||
| return this.match == match; | ||
| } | ||
|
|
||
| public static Rank from(int matchCount) { | ||
| return Arrays.stream(values()) | ||
| .filter(rank -> rank.isMatch(matchCount)) | ||
| .findFirst() | ||
| .orElse(NONE); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package lotto.view; | ||
|
|
||
| import java.util.Scanner; | ||
|
|
||
| public class InputView { | ||
| private static final Scanner SCANNER = new Scanner(System.in); | ||
|
|
||
| public static long initLottoPrice() { | ||
| System.out.println("구매금액을 입력해 주세요."); | ||
| return Long.parseLong(SCANNER.nextLine()); | ||
| } | ||
|
|
||
| public static String initWinningLotto() { | ||
| System.out.println("지난 주 당첨 번호를 입력해 주세요."); | ||
| return SCANNER.nextLine(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| package lotto.view; | ||
|
|
||
| import lotto.domain.Lotto; | ||
| import lotto.domain.LottoGame; | ||
| import lotto.domain.LottoResult; | ||
| import lotto.domain.Rank; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class ResultView { | ||
| public static void printLottos(List<Lotto> lottos) { | ||
| System.out.println(lottos.size() + "개를 구매했습니다."); | ||
| for (Lotto lotto : lottos) { | ||
| System.out.println(lotto); | ||
| } | ||
| } | ||
|
|
||
| public static void printResult(LottoResult result, LottoGame lottoGame) { | ||
| System.out.println("당첨 통계"); | ||
| System.out.println("---------"); | ||
| for (Rank rank : Rank.values()) { | ||
| System.out.println(rank.match() + "개 일치 (" + rank.prize() + "원) - " + result.getCount(rank) + "개"); | ||
| } | ||
| printRateOfReturn(result, lottoGame); | ||
|
|
||
| } | ||
|
|
||
| private static void printRateOfReturn(LottoResult result, LottoGame lottoGame) { | ||
| double rate = lottoGame.rateOfReturn(result); | ||
| String message = String.format("총 수익률은 %.2f입니다.", rate); | ||
| if (rate < 1.0) { | ||
| message += "(기준이 1이기 때문에 결과적으로 손해라는 의미임)"; | ||
| } | ||
| System.out.println(message); | ||
| } | ||
|
|
||
|
|
||
| } |
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.
여러 개의 생성자 추가 👍