diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d190922..ddc29eb 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,7 +1,10 @@ package lotto; +import lotto.controller.lottoController; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + lottoController controller = new lottoController(); + controller.run(); } } diff --git a/src/main/java/lotto/Lotto.java b/src/main/java/lotto/Lotto.java index 88fc5cf..76539c5 100644 --- a/src/main/java/lotto/Lotto.java +++ b/src/main/java/lotto/Lotto.java @@ -16,5 +16,15 @@ private void validate(List numbers) { } } - // TODO: 추가 기능 구현 + public List getNumbers() { + return numbers; + } + + public long countMatch(List winning){ + return numbers.stream().filter(winning::contains).count(); + } + + public boolean bonusContains(int bonusNumber) { + return numbers.contains(bonusNumber); + } } diff --git a/src/main/java/lotto/controller/lottoController.java b/src/main/java/lotto/controller/lottoController.java new file mode 100644 index 0000000..745bf2b --- /dev/null +++ b/src/main/java/lotto/controller/lottoController.java @@ -0,0 +1,31 @@ +package lotto.controller; + +import lotto.model.buyLotto; +import lotto.model.lottoResult; +import lotto.model.winningLotto; +import lotto.view.inputView; +import lotto.view.outputView; + +public class lottoController { + private final inputView inputView = new inputView(); + private final outputView outputView = new outputView(); + + public void run() { + try { + int purchaseAmount = inputView.readPurchaseAmount(); + buyLotto boughtTickets = buyLotto.generate(purchaseAmount); + + outputView.printLottosBought(boughtTickets .getBuy().size()); + + String winningNumbersInput = inputView.readWinningNumbers(); + int bonusNumber = inputView.readBonusNumber(); + + winningLotto winning = new winningLotto(winningNumbersInput, bonusNumber); + lottoResult result = lottoResult.of(winning, boughtTickets ); + + outputView.printResult(result, purchaseAmount); + } catch (IllegalArgumentException e) { + outputView.printError("[ERROR] " + e.getMessage()); + } + } +} diff --git a/src/main/java/lotto/model/buyLotto.java b/src/main/java/lotto/model/buyLotto.java new file mode 100644 index 0000000..0a02d84 --- /dev/null +++ b/src/main/java/lotto/model/buyLotto.java @@ -0,0 +1,32 @@ +package lotto.model; + +import camp.nextstep.edu.missionutils.Randoms; +import lotto.Lotto; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class buyLotto { + private final List buy; + + private buyLotto(List buy){ + this.buy = buy; + } + + public static buyLotto generate(int amount){ + if(amount % 1000 != 0){ + throw new IllegalArgumentException("구입 금액은 1000원 단위어야 합니다"); + } + + int count = amount / 1000; + List buy = IntStream.range(0, count) + .mapToObj(i -> new Lotto(Randoms.pickUniqueNumbersInRange(1, 45, 6))) + .collect(Collectors.toList()); + return new buyLotto(buy); + } + + public List getBuy(){ + return buy; + } +} diff --git a/src/main/java/lotto/model/lottoRank.java b/src/main/java/lotto/model/lottoRank.java new file mode 100644 index 0000000..f069f6d --- /dev/null +++ b/src/main/java/lotto/model/lottoRank.java @@ -0,0 +1,51 @@ +package lotto.model; + +import java.util.Arrays; + +public enum lottoRank { + 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); + + private final int match; + private final boolean matchBonus; + private final int prize; + + lottoRank(int match, boolean matchBonus, int prize){ + this.match = match; + this.matchBonus = matchBonus; + this.prize = prize; + } + + public static lottoRank valueOf(int matchCount, boolean matchBonus) { + return Arrays.stream(values()) + .filter(rank -> rank.match == matchCount && rank.matchBonus == matchBonus) + .findFirst() + .orElseGet(() -> Arrays.stream(values()) + .filter(rank -> rank.match == matchCount) + .findFirst() + .orElse(MISS)); + } + + public int getPrize() { + return prize; + } + + public int getMatchCount() { + return match; + } + + public boolean isBonusMatch() { + return matchBonus; + } + + public String getDes(){ + if(this == MISS) return "꽝"; + return String.format("%d개 일치%s", + match, + matchBonus ? ", 보너스 볼 일치" : ""); + } +} diff --git a/src/main/java/lotto/model/lottoResult.java b/src/main/java/lotto/model/lottoResult.java new file mode 100644 index 0000000..4b003fb --- /dev/null +++ b/src/main/java/lotto/model/lottoResult.java @@ -0,0 +1,45 @@ +package lotto.model; + +import lotto.Lotto; + +import java.util.EnumMap; +import java.util.Map; +import java.util.stream.Collectors; + +public class lottoResult { + private final Map result = new EnumMap<>(lottoRank.class); + + private lottoResult(){ + for(lottoRank rank : lottoRank.values()){ + result.put(rank, 0); + } + } + + public static lottoResult of(winningLotto winning, buyLotto buy){ + lottoResult result = new lottoResult(); + for(Lotto lotto : buy.getBuy()){ + int match = (int) lotto.countMatch(winning.getWinningNumbers()); + boolean matchBonus = lotto.bonusContains(winning.getBonusNumber()); + lottoRank rank = lottoRank.valueOf(match, matchBonus); + result.result.put(rank, result.result.get(rank)+1); + } + return result; + } + + public Map getResult() { + return result; + } + + public double calculateRate(int purchaseAmount) { + long totalPrize = result.entrySet().stream() + .mapToLong(e -> e.getKey().getPrize() * e.getValue()) + .sum(); + return ((double) totalPrize / purchaseAmount) * 100; + } + + public Map getWinningRanks() { + return result.entrySet().stream() + .filter(e -> e.getKey() != lottoRank.MISS && e.getValue() > 0) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } +} diff --git a/src/main/java/lotto/model/winningLotto.java b/src/main/java/lotto/model/winningLotto.java new file mode 100644 index 0000000..2a51727 --- /dev/null +++ b/src/main/java/lotto/model/winningLotto.java @@ -0,0 +1,34 @@ +package lotto.model; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class winningLotto { + private final List winningNums; + private final int bonus; + + public winningLotto(String input, int bonus){ + this.winningNums = parseInput(input); + this.bonus = bonus; + } + + private List parseInput(String input){ + List numbers = Arrays.stream(input.split(",")) + .map(String::trim) + .map(Integer::parseInt) + .collect(Collectors.toList()); + if(numbers.size() != 6 || numbers.stream().distinct().count() != 6){ + throw new IllegalArgumentException("[ERROR] 당첨 번호는 중복되지 않는 6개여야 합니다."); + } + return numbers; + } + + public List getWinningNumbers() { + return winningNums; + } + + public int getBonusNumber() { + return bonus; + } +} diff --git a/src/main/java/lotto/view/inputView.java b/src/main/java/lotto/view/inputView.java new file mode 100644 index 0000000..120a704 --- /dev/null +++ b/src/main/java/lotto/view/inputView.java @@ -0,0 +1,23 @@ +package lotto.view; + +import java.util.Scanner; + +public class inputView { + private final Scanner scanner = new Scanner(System.in); + + public int readPurchaseAmount() { + System.out.println("구입금액을 입력해 주세요."); + return Integer.parseInt(scanner.nextLine()); + } + + public String readWinningNumbers() { + System.out.println("당첨 번호를 입력해 주세요."); + return scanner.nextLine(); + } + + public int readBonusNumber() { + System.out.println("보너스 번호를 입력해 주세요."); + return Integer.parseInt(scanner.nextLine()); + } + +} diff --git a/src/main/java/lotto/view/outputView.java b/src/main/java/lotto/view/outputView.java new file mode 100644 index 0000000..feb0154 --- /dev/null +++ b/src/main/java/lotto/view/outputView.java @@ -0,0 +1,32 @@ +package lotto.view; + +import lotto.Lotto; +import lotto.model.buyLotto; +import lotto.model.lottoRank; +import lotto.model.lottoResult; + +import java.util.List; +import java.util.Map; + +public class outputView { + public void printLottosBought(int count) { + System.out.printf("%d개를 구매했습니다.\n", count); + } + + public void printResult(lottoResult result, int purchaseAmount) { + System.out.println("\n당첨 통계"); + System.out.println("---------"); + + for (Map.Entry entry : result.getWinningRanks().entrySet()) { + lottoRank rank = entry.getKey(); + int count = entry.getValue(); + System.out.printf("%s - %d개\n", rank.getDes(), count); + } + + System.out.printf("총 수익률은 %.2f%%입니다.\n", result.calculateRate(purchaseAmount)); + } + + public void printError(String message) { + System.out.println(message); + } +}