From a3b818754a09c87b5ac621b61b7b8b7e71f0bad6 Mon Sep 17 00:00:00 2001 From: monsaumon Date: Tue, 31 Mar 2026 21:13:41 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=201=EB=8B=A8=EA=B3=84=20=EB=A1=9C?= =?UTF-8?q?=EB=98=90=20=EC=9E=90=EB=8F=99=20=EA=B5=AC=EB=A7=A4=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 권희준 <2390kwon@g.skku.edu> --- src/main/java/Application.java | 24 ++++++++++++ src/main/java/domain/Cashier.java | 39 +++++++++++++++++++ src/main/java/domain/Lotto.java | 19 +++++++++ src/main/java/domain/LottoTicket.java | 29 ++++++++++++++ src/main/java/domain/NumberListGenerator.java | 7 ++++ .../domain/RandomNumberListGenerator.java | 24 ++++++++++++ src/main/java/view/InputView.java | 11 ++++++ src/main/java/view/OutputView.java | 23 +++++++++++ 8 files changed, 176 insertions(+) create mode 100644 src/main/java/Application.java create mode 100644 src/main/java/domain/Cashier.java create mode 100644 src/main/java/domain/Lotto.java create mode 100644 src/main/java/domain/LottoTicket.java create mode 100644 src/main/java/domain/NumberListGenerator.java create mode 100644 src/main/java/domain/RandomNumberListGenerator.java create mode 100644 src/main/java/view/InputView.java create mode 100644 src/main/java/view/OutputView.java diff --git a/src/main/java/Application.java b/src/main/java/Application.java new file mode 100644 index 00000000..d96dc137 --- /dev/null +++ b/src/main/java/Application.java @@ -0,0 +1,24 @@ +import domain.Cashier; +import domain.Lotto; +import domain.NumberListGenerator; +import domain.RandomNumberListGenerator; +import view.InputView; +import view.OutputView; + +public class Application { + + public static final int TICKET_LENGTH = 6; + + public static void main(String[] args) { + InputView inputView = new InputView(); + OutputView outputView = new OutputView(); + NumberListGenerator numberListGenerator = new RandomNumberListGenerator(TICKET_LENGTH); + Cashier cashier = new Cashier(numberListGenerator); + + int price = inputView.inputPrice(); + Lotto lotto = cashier.generateTickets(price); + outputView.showNumberOfTickets(lotto.getNumberOfTickets()); + outputView.showLottoTickets(lotto); + + } +} diff --git a/src/main/java/domain/Cashier.java b/src/main/java/domain/Cashier.java new file mode 100644 index 00000000..3eb5d339 --- /dev/null +++ b/src/main/java/domain/Cashier.java @@ -0,0 +1,39 @@ +package domain; + +import java.util.ArrayList; +import java.util.List; + +public class Cashier { + private final NumberListGenerator numberListGenerator; + + public Cashier(NumberListGenerator numberListGenerator) { + this.numberListGenerator = numberListGenerator; + } + + public Lotto generateTickets(int price) { + validatePrice(price); + int numberOfTickets = calculateNumberOfTickets(price); + List generatedTickets = new ArrayList<>(); + for (int i = 0; i < numberOfTickets; i++) { + generatedTickets.add(new LottoTicket(numberListGenerator.generate())); + } + + return new Lotto(generatedTickets); + } + + private void validatePrice(int price) { + if (price < 0) { + throw new IllegalArgumentException("잘못된 입력입니다."); + } + if (price < 1000) { + throw new IllegalArgumentException("돈이 부족합니다."); + } + if (price % 1000 != 0) { + throw new IllegalArgumentException("1000원 단위로 입력해주세요."); + } + } + + private int calculateNumberOfTickets(int price) { + return price / 1000; + } +} diff --git a/src/main/java/domain/Lotto.java b/src/main/java/domain/Lotto.java new file mode 100644 index 00000000..4ea5a4ba --- /dev/null +++ b/src/main/java/domain/Lotto.java @@ -0,0 +1,19 @@ +package domain; + +import java.util.List; + +public class Lotto { + private final List tickets; + + public Lotto(List tickets) { + this.tickets = tickets; + } + + public List getTickets() { + return tickets; + } + + public int getNumberOfTickets() { + return tickets.size(); + } +} diff --git a/src/main/java/domain/LottoTicket.java b/src/main/java/domain/LottoTicket.java new file mode 100644 index 00000000..8502c425 --- /dev/null +++ b/src/main/java/domain/LottoTicket.java @@ -0,0 +1,29 @@ +package domain; + +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +public class LottoTicket { + private final List ticket; + + public LottoTicket(List ticket) { + validate(ticket); + ticket.sort(Comparator.naturalOrder()); + this.ticket = ticket; + } + + static private void validate(List ticket) { + int length = ticket.size(); + Set ticketSet = new HashSet<>(ticket); + if (ticketSet.size() != length) { + throw new RuntimeException(); + } + } + + public List getTicket() { + return ticket; + } +} diff --git a/src/main/java/domain/NumberListGenerator.java b/src/main/java/domain/NumberListGenerator.java new file mode 100644 index 00000000..7d5c3143 --- /dev/null +++ b/src/main/java/domain/NumberListGenerator.java @@ -0,0 +1,7 @@ +package domain; + +import java.util.List; + +public interface NumberListGenerator { + List generate(); +} diff --git a/src/main/java/domain/RandomNumberListGenerator.java b/src/main/java/domain/RandomNumberListGenerator.java new file mode 100644 index 00000000..caa823fa --- /dev/null +++ b/src/main/java/domain/RandomNumberListGenerator.java @@ -0,0 +1,24 @@ +package domain; + +import java.util.*; + +public class RandomNumberListGenerator implements NumberListGenerator { + private static final int UPPER_BOUND = 46; + private static final int LOWER_BOUND = 1; + + private final int length; + + public RandomNumberListGenerator(final int length) { + this.length = length; + } + + @Override + public List generate() { + List numberList = new ArrayList<>(); + for (int i = LOWER_BOUND; i < UPPER_BOUND; i++) { + numberList.add(i); + } + Collections.shuffle(numberList); + return numberList.subList(0, length); + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 00000000..2254c1c3 --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,11 @@ +package view; + +import java.util.Scanner; + +public class InputView { + public int inputPrice() { + Scanner scanner = new Scanner(System.in); + System.out.println("구입 금액을 입력해 주세요."); + return scanner.nextInt(); + } +} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 00000000..f60a5a5c --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,23 @@ +package view; + +import domain.Lotto; +import domain.LottoTicket; + +import java.util.List; + +public class OutputView { + public void showNumberOfTickets(int numberOfTickets) { + System.out.println(numberOfTickets + "개를 구매했습니다."); + } + + public void showLottoTickets(Lotto lotto) { + for (LottoTicket lottoTicket: lotto.getTickets()) { + showLottoTicket(lottoTicket); + } + } + + private void showLottoTicket(LottoTicket lottoTicket) { + List ticket = lottoTicket.getTicket(); + System.out.println(ticket); + } +} From 993062df0cee3cef54b91c75baaa65fc52007988 Mon Sep 17 00:00:00 2001 From: monsaumon Date: Wed, 1 Apr 2026 15:58:57 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=202=EB=8B=A8=EA=B3=84=20=EB=A1=9C?= =?UTF-8?q?=EB=98=90=20=EB=8B=B9=EC=B2=A8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 권희준 <2390kwon@g.skku.edu> --- src/main/java/Application.java | 11 ++++-- src/main/java/domain/Cashier.java | 34 ++++++++++++++--- src/main/java/domain/Lotto.java | 9 +++++ src/main/java/domain/LottoResult.java | 36 ++++++++++++++++++ src/main/java/domain/LottoTicket.java | 12 +++++- .../domain/RandomNumberListGenerator.java | 10 ++--- src/main/java/view/InputView.java | 20 ++++++++-- src/main/java/view/OutputView.java | 38 ++++++++++++++++--- 8 files changed, 145 insertions(+), 25 deletions(-) create mode 100644 src/main/java/domain/LottoResult.java diff --git a/src/main/java/Application.java b/src/main/java/Application.java index d96dc137..f4ca619b 100644 --- a/src/main/java/Application.java +++ b/src/main/java/Application.java @@ -1,13 +1,14 @@ import domain.Cashier; import domain.Lotto; +import domain.LottoResult; +import domain.LottoTicket; import domain.NumberListGenerator; import domain.RandomNumberListGenerator; import view.InputView; import view.OutputView; public class Application { - - public static final int TICKET_LENGTH = 6; + public static final Integer TICKET_LENGTH = 6; public static void main(String[] args) { InputView inputView = new InputView(); @@ -15,10 +16,12 @@ public static void main(String[] args) { NumberListGenerator numberListGenerator = new RandomNumberListGenerator(TICKET_LENGTH); Cashier cashier = new Cashier(numberListGenerator); - int price = inputView.inputPrice(); + Integer price = inputView.inputPrice(); Lotto lotto = cashier.generateTickets(price); - outputView.showNumberOfTickets(lotto.getNumberOfTickets()); outputView.showLottoTickets(lotto); + LottoTicket winnerTicket = inputView.getWinnerTicket(); + LottoResult result = cashier.getResults(lotto, winnerTicket); + outputView.showLottoResults(result, cashier.getProfitRate(result, price)); } } diff --git a/src/main/java/domain/Cashier.java b/src/main/java/domain/Cashier.java index 3eb5d339..b0eb936b 100644 --- a/src/main/java/domain/Cashier.java +++ b/src/main/java/domain/Cashier.java @@ -1,27 +1,51 @@ package domain; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class Cashier { + public static final Integer THREE_CORRECT = 3; + public static final Integer FOUR_CORRECT = 4; + public static final Integer FIVE_CORRECT = 5; + public static final Integer SIX_CORRECT = 6; private final NumberListGenerator numberListGenerator; public Cashier(NumberListGenerator numberListGenerator) { this.numberListGenerator = numberListGenerator; } - public Lotto generateTickets(int price) { + public Lotto generateTickets(Integer price) { validatePrice(price); - int numberOfTickets = calculateNumberOfTickets(price); + Integer numberOfTickets = calculateNumberOfTickets(price); List generatedTickets = new ArrayList<>(); - for (int i = 0; i < numberOfTickets; i++) { + for (Integer i = 0; i < numberOfTickets; i++) { generatedTickets.add(new LottoTicket(numberListGenerator.generate())); } return new Lotto(generatedTickets); } - private void validatePrice(int price) { + public LottoResult getResults(Lotto lotto, LottoTicket winnerTicket) { + List results = lotto.getResults(winnerTicket); + return new LottoResult( + Collections.frequency(results, THREE_CORRECT), + Collections.frequency(results, FOUR_CORRECT), + Collections.frequency(results, FIVE_CORRECT), + Collections.frequency(results, SIX_CORRECT) + ); + } + + public Double getProfitRate(LottoResult result, Integer price) { + Integer totalProfit = 5000 * result.getThreeCorrectCount() + + 50000 * result.getFourCorrectCount() + + 1500000 * result.getFiveCorrectCount() + + 2000000000 * result.getSixCorrectCount(); + + return totalProfit.doubleValue() / price; + } + + private void validatePrice(Integer price) { if (price < 0) { throw new IllegalArgumentException("잘못된 입력입니다."); } @@ -33,7 +57,7 @@ private void validatePrice(int price) { } } - private int calculateNumberOfTickets(int price) { + private Integer calculateNumberOfTickets(Integer price) { return price / 1000; } } diff --git a/src/main/java/domain/Lotto.java b/src/main/java/domain/Lotto.java index 4ea5a4ba..da4c277d 100644 --- a/src/main/java/domain/Lotto.java +++ b/src/main/java/domain/Lotto.java @@ -1,5 +1,6 @@ package domain; +import java.util.ArrayList; import java.util.List; public class Lotto { @@ -9,6 +10,14 @@ public Lotto(List tickets) { this.tickets = tickets; } + public List getResults(LottoTicket winnerTicket) { + List results = new ArrayList<>(); + for (LottoTicket ticket : tickets) { + results.add(ticket.getResult(winnerTicket)); + } + return results; + } + public List getTickets() { return tickets; } diff --git a/src/main/java/domain/LottoResult.java b/src/main/java/domain/LottoResult.java new file mode 100644 index 00000000..fe88c737 --- /dev/null +++ b/src/main/java/domain/LottoResult.java @@ -0,0 +1,36 @@ +package domain; + +public class LottoResult { + private final Integer threeCorrectCount; + private final Integer fourCorrectCount; + private final Integer fiveCorrectCount; + private final Integer sixCorrectCount; + + + public LottoResult(Integer threeCorrectCount, + Integer fourCorrectCount, + Integer fiveCorrectCount, + Integer sixCorrectCount) { + this.threeCorrectCount = threeCorrectCount; + this.fourCorrectCount = fourCorrectCount; + this.fiveCorrectCount = fiveCorrectCount; + this.sixCorrectCount = sixCorrectCount; + } + + + public Integer getThreeCorrectCount() { + return threeCorrectCount; + } + + public Integer getFourCorrectCount() { + return fourCorrectCount; + } + + public Integer getFiveCorrectCount() { + return fiveCorrectCount; + } + + public Integer getSixCorrectCount() { + return sixCorrectCount; + } +} diff --git a/src/main/java/domain/LottoTicket.java b/src/main/java/domain/LottoTicket.java index 8502c425..9cd20ca5 100644 --- a/src/main/java/domain/LottoTicket.java +++ b/src/main/java/domain/LottoTicket.java @@ -1,6 +1,6 @@ package domain; -import java.util.Comparator; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -11,7 +11,7 @@ public class LottoTicket { public LottoTicket(List ticket) { validate(ticket); - ticket.sort(Comparator.naturalOrder()); + Collections.sort(ticket); this.ticket = ticket; } @@ -23,6 +23,14 @@ static private void validate(List ticket) { } } + public Integer getResult(LottoTicket winnerTicket) { + Integer count = 0; + for (Integer number : winnerTicket.getTicket()) { + count += Boolean.compare(ticket.contains(number), false); + } + return count; + } + public List getTicket() { return ticket; } diff --git a/src/main/java/domain/RandomNumberListGenerator.java b/src/main/java/domain/RandomNumberListGenerator.java index caa823fa..b286801c 100644 --- a/src/main/java/domain/RandomNumberListGenerator.java +++ b/src/main/java/domain/RandomNumberListGenerator.java @@ -3,19 +3,19 @@ import java.util.*; public class RandomNumberListGenerator implements NumberListGenerator { - private static final int UPPER_BOUND = 46; - private static final int LOWER_BOUND = 1; + private static final Integer UPPER_BOUND = 46; + private static final Integer LOWER_BOUND = 1; - private final int length; + private final Integer length; - public RandomNumberListGenerator(final int length) { + public RandomNumberListGenerator(final Integer length) { this.length = length; } @Override public List generate() { List numberList = new ArrayList<>(); - for (int i = LOWER_BOUND; i < UPPER_BOUND; i++) { + for (Integer i = LOWER_BOUND; i < UPPER_BOUND; i++) { numberList.add(i); } Collections.shuffle(numberList); diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 2254c1c3..dd903d57 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -1,11 +1,25 @@ package view; +import domain.LottoTicket; +import java.util.Arrays; import java.util.Scanner; +import java.util.stream.Collectors; public class InputView { - public int inputPrice() { - Scanner scanner = new Scanner(System.in); + private final Scanner scanner; + + public InputView() { + scanner = new Scanner(System.in); + } + + public Integer inputPrice() { System.out.println("구입 금액을 입력해 주세요."); - return scanner.nextInt(); + return Integer.valueOf(scanner.nextLine()); + } + + public LottoTicket getWinnerTicket() { + System.out.println("지난 주 당첨 번호를 입력해 주세요."); + return new LottoTicket( + Arrays.stream(scanner.nextLine().split(", ")).map(Integer::valueOf).collect(Collectors.toList())); } } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index f60a5a5c..326f6069 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -1,21 +1,47 @@ package view; import domain.Lotto; +import domain.LottoResult; import domain.LottoTicket; - import java.util.List; public class OutputView { - public void showNumberOfTickets(int numberOfTickets) { - System.out.println(numberOfTickets + "개를 구매했습니다."); - } - public void showLottoTickets(Lotto lotto) { - for (LottoTicket lottoTicket: lotto.getTickets()) { + System.out.println(); + System.out.println(lotto.getNumberOfTickets() + "개를 구매했습니다."); + for (LottoTicket lottoTicket : lotto.getTickets()) { showLottoTicket(lottoTicket); } } + public void showLottoResults(LottoResult result, Double profitRate) { + showLottoStatistics(result); + showProfitRate(profitRate); + } + + public void showLottoStatistics(LottoResult result) { + System.out.println("\n당첨 통계\n---------"); + System.out.println("3개 일치 (5000원)- " + result.getThreeCorrectCount() + "개"); + System.out.println("4개 일치 (50000원)- " + result.getFourCorrectCount() + "개"); + System.out.println("5개 일치 (1500000원)- " + result.getFiveCorrectCount() + "개"); + System.out.println("6개 일치 (2000000000원)- " + result.getSixCorrectCount() + "개"); + } + + public void showProfitRate(Double profitRate) { + System.out.printf("총 수익률은 %.2f입니다.", profitRate); + if (profitRate > 1) { + System.out.print("(기준이 1이기 때문에 결과적으로 이득이라는 의미임)"); + return; + } + + if (profitRate == 1) { + System.out.print("(기준이 1이기 때문에 결과적으로 본전이라는 의미임)"); + return; + } + + System.out.print("(기준이 1이기 때문에 결과적으로 손해라는 의미임)"); + } + private void showLottoTicket(LottoTicket lottoTicket) { List ticket = lottoTicket.getTicket(); System.out.println(ticket); From 3d57fd318703fc63388502ab1d73af879bbcdce1 Mon Sep 17 00:00:00 2001 From: CHOI YEONU <75886700+monsaumon@users.noreply.github.com> Date: Wed, 1 Apr 2026 16:03:27 +0900 Subject: [PATCH 3/4] =?UTF-8?q?docs:=20README.md=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..4e6a8c17 --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +# 1단계 기능 요구사항 +-[X] 로또 구입 금액을 입력하면 구입 금액에 해당하는 로또를 발급해야 한다. +-[X] 로또 1장의 가격은 1000원이다. +-[X] 새로운 프로그래밍 요구사항 +-[X] 배열 대신 컬렉션을 사용한다. +-[X] 줄여 쓰지 않는다(축약 금지). +-[X] 함수(또는 메서드)의 길이가 10라인을 넘어가지 않도록 구현한다. +-[X] 함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라. + +# 2단계 기능 요구사항 +-[X] 로또 당첨 번호를 받아 일치한 번호 수에 따라 당첨 결과를 보여준다. + +## 새로운 프로그래밍 요구사항 +모든 원시 값과 문자열을 포장한다. +일급 컬렉션을 쓴다. + +## 기존 프로그래밍 요구사항 +자바 코드 컨벤션을 지키면서 프로그래밍한다. +기본적으로 Java Style Guide을 원칙으로 한다. +indent(인덴트, 들여쓰기) depth를 2를 넘지 않도록 구현한다. 1까지만 허용한다. +예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다. +힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다. +3항 연산자를 쓰지 않는다. +else 예약어를 쓰지 않는다. +else 예약어를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다. +힌트: if문에서 값을 반환하는 방식으로 구현하면 else 예약어를 사용하지 않아도 된다. From 3399121575cb62183c3dafc4f3781bcd860e3e2e Mon Sep 17 00:00:00 2001 From: CHOI YEONU <75886700+monsaumon@users.noreply.github.com> Date: Wed, 1 Apr 2026 16:04:07 +0900 Subject: [PATCH 4/4] docs: Update README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 4e6a8c17..bc974a25 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ # 1단계 기능 요구사항 --[X] 로또 구입 금액을 입력하면 구입 금액에 해당하는 로또를 발급해야 한다. --[X] 로또 1장의 가격은 1000원이다. --[X] 새로운 프로그래밍 요구사항 --[X] 배열 대신 컬렉션을 사용한다. --[X] 줄여 쓰지 않는다(축약 금지). --[X] 함수(또는 메서드)의 길이가 10라인을 넘어가지 않도록 구현한다. --[X] 함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라. +- [X] 로또 구입 금액을 입력하면 구입 금액에 해당하는 로또를 발급해야 한다. +- [X] 로또 1장의 가격은 1000원이다. +- [X] 새로운 프로그래밍 요구사항 +- [X] 배열 대신 컬렉션을 사용한다. +- [X] 줄여 쓰지 않는다(축약 금지). +- [X] 함수(또는 메서드)의 길이가 10라인을 넘어가지 않도록 구현한다. +- [X] 함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라. # 2단계 기능 요구사항 --[X] 로또 당첨 번호를 받아 일치한 번호 수에 따라 당첨 결과를 보여준다. +- [X] 로또 당첨 번호를 받아 일치한 번호 수에 따라 당첨 결과를 보여준다. ## 새로운 프로그래밍 요구사항 모든 원시 값과 문자열을 포장한다.