From 160ed128d5c92093ed675476b7c1f689e0380976 Mon Sep 17 00:00:00 2001 From: User Date: Wed, 19 Feb 2025 02:33:50 +0900 Subject: [PATCH 1/6] =?UTF-8?q?docs(README):=20README.md=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index 15bb106..6a114a2 100644 --- a/README.md +++ b/README.md @@ -1 +1,26 @@ # javascript-lotto-precourse +## 기능 목록 +# 로또 금액 사용자 입력 +1. 사용자액입력 처리 : 1000원 단위로 금액을 입력 받는다. (오류x) +2. 사용자 입력 처외 처리(오류1) : 1000단위 미만의 값을 입력 받으면 오류 메세지('[ERROR]')를 띄운다. +3. 사용자 입력 예외 처리(오류2) : 0원 이하의 값을 받으면 오류 메세지('[ERROR]')를 띄운다. +# 당첨 번호 사용자 입력 +4. 로또 수량 추출 : 사력자가 구매한 금액으로 부터 로또 수량을 추출한다. +5. 로또 뽑기 기능 구현 : 중복되지 않는 숫자 6개 set을 수량만큼 만든다.(1~45사이 숫자 랜덤 추출) +6. 사용자 입력 처리 : 당첨 번호 6개를 입력 받는다. +. 사용자 입력 예외 처리 : 구분자 , 가 아니면 오류 메세지를 띄운다. +. 사용자 입력 예외 처리 : 당첨번호가 6개가 아니면 오류 메세지를 띄운다. +. 사용자 입력 예외 처리 : 당첨번호 숫자 1~45 사이의 숫자가 아니면 오류메세지를 띄운다. +. 사용자 입력 처리 : 보너스 번호를 1개를 입력받는다. +. 사용자 입력 예외처리 : 보너스 번호가 1개가 아니고, ',' 구분자자 들어가 있으면 오류메세지를 띄운다. +. 사용자 입력 예외처리 : 보너스 번호 숫자 1~45 사이의 숫자가 아니면 오류메세지를 띄운다. +# 로또 수량 및 번호 출력 +1. 수량 출력 : 추출한 로또 수량을 출력한다. +2. 로또 번호 출력 : 로또 번호를 수량만큼 오름차순으로 출력한다. +3. 당첨 내역 출력 : 당첨 번호와 비교하여 번호 일치 개수를 추출한다. +4. 당첨 내역 출력 : 번호 일치 개수 만큼 분류하여 당첨 수량을 추출한다. + +# 수익률 계산 및 출력 +1. 수익률을 계산 : (당첨 금액/구매 금액) * 100 수식을 이용하여 수익률(%)을 구하고고소수 둘째 자리에서 반올림한다. +2. 수익률 출력 + From d1f92d80089c0967ccdd540a1f10474cbb38a831 Mon Sep 17 00:00:00 2001 From: Guemzu Date: Wed, 19 Feb 2025 02:52:45 +0900 Subject: [PATCH 2/6] =?UTF-8?q?docs(REAME):=20=EB=A6=AC=EB=93=9C=EB=AF=B8?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 6a114a2..488181f 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,26 @@ # javascript-lotto-precourse ## 기능 목록 -# 로또 금액 사용자 입력 -1. 사용자액입력 처리 : 1000원 단위로 금액을 입력 받는다. (오류x) +### 로또 금액 사용자 입력 +1. 사용자 금액 입력 처리 : 1000원 단위로 금액을 입력 받는다. (오류x) 2. 사용자 입력 처외 처리(오류1) : 1000단위 미만의 값을 입력 받으면 오류 메세지('[ERROR]')를 띄운다. 3. 사용자 입력 예외 처리(오류2) : 0원 이하의 값을 받으면 오류 메세지('[ERROR]')를 띄운다. -# 당첨 번호 사용자 입력 -4. 로또 수량 추출 : 사력자가 구매한 금액으로 부터 로또 수량을 추출한다. -5. 로또 뽑기 기능 구현 : 중복되지 않는 숫자 6개 set을 수량만큼 만든다.(1~45사이 숫자 랜덤 추출) -6. 사용자 입력 처리 : 당첨 번호 6개를 입력 받는다. -. 사용자 입력 예외 처리 : 구분자 , 가 아니면 오류 메세지를 띄운다. -. 사용자 입력 예외 처리 : 당첨번호가 6개가 아니면 오류 메세지를 띄운다. -. 사용자 입력 예외 처리 : 당첨번호 숫자 1~45 사이의 숫자가 아니면 오류메세지를 띄운다. -. 사용자 입력 처리 : 보너스 번호를 1개를 입력받는다. -. 사용자 입력 예외처리 : 보너스 번호가 1개가 아니고, ',' 구분자자 들어가 있으면 오류메세지를 띄운다. -. 사용자 입력 예외처리 : 보너스 번호 숫자 1~45 사이의 숫자가 아니면 오류메세지를 띄운다. -# 로또 수량 및 번호 출력 +### 당첨 번호 사용자 입력 +1. 로또 수량 추출 : 사력자가 구매한 금액으로 부터 로또 수량을 추출한다. +2. 로또 뽑기 기능 구현 : 중복되지 않는 숫자 6개 set을 수량만큼 만든다.(1~45사이 숫자 랜덤 추출) +3. 사용자 입력 처리 : 당첨 번호 6개를 입력 받는다. +4. 사용자 입력 예외 처리 : 구분자 , 가 아니면 오류 메세지를 띄운다. +5. 사용자 입력 예외 처리 : 당첨번호가 6개가 아니면 오류 메세지를 띄운다. +6. 사용자 입력 예외 처리 : 당첨번호 숫자 1~45 사이의 숫자가 아니면 오류메세지를 띄운다. +7. 사용자 입력 처리 : 보너스 번호를 1개를 입력받는다. +8. 사용자 입력 예외처리 : 보너스 번호가 1개가 아니고, ',' 구분자자 들어가 있으면 오류메세지를 띄운다. +9. 사용자 입력 예외처리 : 보너스 번호 숫자 1~45 사이의 숫자가 아니면 오류메세지를 띄운다. +### 로또 수량 및 번호 출력 1. 수량 출력 : 추출한 로또 수량을 출력한다. 2. 로또 번호 출력 : 로또 번호를 수량만큼 오름차순으로 출력한다. 3. 당첨 내역 출력 : 당첨 번호와 비교하여 번호 일치 개수를 추출한다. 4. 당첨 내역 출력 : 번호 일치 개수 만큼 분류하여 당첨 수량을 추출한다. -# 수익률 계산 및 출력 +### 수익률 계산 및 출력 1. 수익률을 계산 : (당첨 금액/구매 금액) * 100 수식을 이용하여 수익률(%)을 구하고고소수 둘째 자리에서 반올림한다. 2. 수익률 출력 From 294a4a1cd2d86d8e5c4be9fddc668af4751fa1a2 Mon Sep 17 00:00:00 2001 From: Guemzu Date: Fri, 21 Feb 2025 07:18:04 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat(src)=20:=20=EB=A1=9C=EB=98=90=20?= =?UTF-8?q?=EA=B8=88=EC=95=A1=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 39 ++++++++++++++++++++++++++++++++++++++- src/Lotto.js | 7 ++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/App.js b/src/App.js index 091aa0a..9877dd4 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,42 @@ +import { Console, Random } from "@woowacourse/mission-utils"; +import Lotto from "./Lotto"; + class App { - async run() {} + async run() { + const money = await new Promise(function(resolve) { + Console.readLineAsync('로또 구입 금액을 입력해주세요.\n', function(input){ + resolve(Number(input)); + }); + }); + + // 0원 이하 또는 1000원 단위가 아닐 경우 에러 처리 + if (money <= 0 || money % 1000 !== 0) { + Console.print('[ERROR] 금액의 최소 구입 단위는 1000원입니다. 1000원 단위로 입력해주세요.') + Console.close(); + return; + } + + // 입력 금액과 구매한 로또 수 출력 + Console.print('구입 금액 :' + money + '원'); + const ticketCount = money / 1000; + Console.print(ticketCount + '개의 로또를 구매했습니다.'); + + // 로또 티켓 생성 + const lottoTickets = []; + for (let i = 0; i < ticketCount; i++){ + const numbers = Random.pickUniqueNumbersInRange(1,45,6); + numbers.sort(function(a, b){ + return a - b; + }) + const lotto = new Lotto(numbers); + lottoTickets.push(lotto); + } + // 생성된 로또 티켓 출력 + lottoTickets.forEach(function(ticket){ + Console.print(ticket.toString()); + }); + + } } export default App; diff --git a/src/Lotto.js b/src/Lotto.js index cb0b152..4bf573c 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -10,9 +10,14 @@ class Lotto { if (numbers.length !== 6) { throw new Error("[ERROR] 로또 번호는 6개여야 합니다."); } + 환 + + // 로또 번호 배열 반환 + getNumners(){ + } - // TODO: 추가 기능 구현 + // 로또 번호를 문자열로 반환 } export default Lotto; From e6849fcbbd3595af57e9f80afff6994d7981c1a0 Mon Sep 17 00:00:00 2001 From: Guemzu Date: Fri, 21 Feb 2025 07:26:08 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feat(src)=20:=20=EB=A1=9C=EB=98=90=20?= =?UTF-8?q?=EA=B8=88=EC=95=A1=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 2 ++ src/Lotto.js | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/App.js b/src/App.js index 9877dd4..2e8f344 100644 --- a/src/App.js +++ b/src/App.js @@ -36,6 +36,8 @@ class App { Console.print(ticket.toString()); }); + Console.close() + } } diff --git a/src/Lotto.js b/src/Lotto.js index 4bf573c..5c395b2 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -13,11 +13,17 @@ class Lotto { 환 // 로또 번호 배열 반환 - getNumners(){ - + getNumbers(){ + return this.#numbers; } // 로또 번호를 문자열로 반환 + toString(){ + return "[" +this.#numbers.join(', ') + "]"; + } + + +} } export default Lotto; From dc450f387c9a2ee37dd7e88cb109e9a0b3635bbc Mon Sep 17 00:00:00 2001 From: Guemzu Date: Fri, 21 Feb 2025 21:07:21 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feat(src)=20:=20=EB=8B=B9=EC=B2=A8=20?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5,=20=EB=A1=9C=EB=98=90=20=EA=B2=B0=EA=B3=BC=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 52 ++++++++++++++++++----------------------------- src/Lotto.js | 13 ++---------- src/LottoGame.js | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 43 deletions(-) create mode 100644 src/LottoGame.js diff --git a/src/App.js b/src/App.js index 2e8f344..ca6a52f 100644 --- a/src/App.js +++ b/src/App.js @@ -1,44 +1,32 @@ import { Console, Random } from "@woowacourse/mission-utils"; -import Lotto from "./Lotto"; +import { getTicketCount, generateLottoTickets, parseWinningNumbers, parseBonusNumber } from "./LottoGame.js"; class App { async run() { - const money = await new Promise(function(resolve) { - Console.readLineAsync('로또 구입 금액을 입력해주세요.\n', function(input){ - resolve(Number(input)); - }); - }); - // 0원 이하 또는 1000원 단위가 아닐 경우 에러 처리 - if (money <= 0 || money % 1000 !== 0) { - Console.print('[ERROR] 금액의 최소 구입 단위는 1000원입니다. 1000원 단위로 입력해주세요.') - Console.close(); - return; - } + try{ + const moneyInput = await Console.readLineAsync('로또 구입 금액을 입력해주세요.\n'); + const ticketCount = getTicketCount(Number(moneyInput)); + Console.print(ticketCount + '개의 로또를 구입했습니다.'); - // 입력 금액과 구매한 로또 수 출력 - Console.print('구입 금액 :' + money + '원'); - const ticketCount = money / 1000; - Console.print(ticketCount + '개의 로또를 구매했습니다.'); - - // 로또 티켓 생성 - const lottoTickets = []; - for (let i = 0; i < ticketCount; i++){ - const numbers = Random.pickUniqueNumbersInRange(1,45,6); - numbers.sort(function(a, b){ - return a - b; - }) - const lotto = new Lotto(numbers); - lottoTickets.push(lotto); - } - // 생성된 로또 티켓 출력 - lottoTickets.forEach(function(ticket){ - Console.print(ticket.toString()); - }); + const tickets = generateLottoTickets(ticketCount); + tickets.forEach(function(ticket){ + Console.print (ticket.toString()); + }); - Console.close() + const winningInput = await Console.readLineAsync('당첨 번호를 입력해주세요.\n'); + const winningNumbers = parseWinningNumbers(winningInput); + Console.print('당첨 번호 : ' + winningNumbers.join(', ')); + const bonusInput = await Console.readLineAsync('보너스 번호를 입력해주세요.\n'); + const bonusNumber = parseBonusNumber(bonusInput); + Console.print('보너스 번호 : ' + bonusNumber); + } catch (error) { + Console.print([error.message]); + } } } +const app = new App(); +app.run(); export default App; diff --git a/src/Lotto.js b/src/Lotto.js index 5c395b2..98fbf06 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -10,20 +10,11 @@ class Lotto { if (numbers.length !== 6) { throw new Error("[ERROR] 로또 번호는 6개여야 합니다."); } - 환 - - // 로또 번호 배열 반환 - getNumbers(){ - return this.#numbers; } - - // 로또 번호를 문자열로 반환 - toString(){ + + toString(){ return "[" +this.#numbers.join(', ') + "]"; } - - -} } export default Lotto; diff --git a/src/LottoGame.js b/src/LottoGame.js new file mode 100644 index 0000000..e6812b4 --- /dev/null +++ b/src/LottoGame.js @@ -0,0 +1,53 @@ +import { Random } from '@woowacourse/mission-utils'; +import Lotto from './Lotto.js'; +function getTicketCount(money) { + // 0원 이하 또는 1000원 단위가 아닐 경우 에러 처리 + if (money <= 0) throw new Error('[Error] 금액의 최소 구입 단위는 1000원 입니다.'); + if (money % 1000 !== 0) throw new Error('[Error] 1000원 단위로만 구입 가능합니다.'); + return money / 1000; +} + +function createLottoTicket() { + const numbers = Random.pickUniqueNumbersInRange(1, 45, 6); + numbers.sort(function(a, b){ return a -b; }); + return new Lotto(numbers); +} + +function generateLottoTickets(count){ + const tickets = []; + for (let i = 0; i < count; i++){ + tickets.push(createLottoTicket()); + } + return tickets; +} + +function parseWinningNumbers(input) { + if (input.indexOf(',') === -1) throw new Error('[Error] 구분자는 ,만 사용 가능합니다.'); + const parts = input.split(','); + if (parts.length !== 6) throw new Error('[Error] 로또 당첨 번호는 6개입니다.'); + const numbers = []; + for (let i = 0; i < parts.length; i++) { + const num = Number(parts[i].trim()); + if (isNaN(num) || num < 1 || num > 45) throw new Error ('[Error] 번호는 1 이상 45이하 범위의 숫자여야 합니다.'); + numbers.push(num); + } + numbers.sort(function(a,b) {return a - b ;}); + return numbers; +} + +function parseBonusNumber(input) { + if (input.indexOf(',') !== -1) throw new Error('[Error] 번호는 하나만 입력 가능합니다.'); + const num = Number(input.trim()); + if (isNaN(num) || num < 1 || num > 45) throw new Error('[Error] 번호는 1 이상 45이하 범위의 숫자여야 합니다.'); + return num; +} + +export { + getTicketCount, + createLottoTicket, + generateLottoTickets, + parseWinningNumbers, + parseBonusNumber +}; + + From 8ef376ddca11a2930c00f08757863a5dc7a775cf Mon Sep 17 00:00:00 2001 From: Guemzu Date: Fri, 21 Feb 2025 22:20:42 +0900 Subject: [PATCH 6/6] =?UTF-8?q?feat(src)=20:=20=EC=88=98=EC=9D=B5=EB=A5=A0?= =?UTF-8?q?=20=EA=B3=84=EC=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 9 ++++-- src/Lotto.js | 7 ++++- src/LottoResult.js | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 src/LottoResult.js diff --git a/src/App.js b/src/App.js index ca6a52f..434670b 100644 --- a/src/App.js +++ b/src/App.js @@ -1,12 +1,13 @@ import { Console, Random } from "@woowacourse/mission-utils"; import { getTicketCount, generateLottoTickets, parseWinningNumbers, parseBonusNumber } from "./LottoGame.js"; - +import { calculateWinningCounts, printWinningStatistics } from "./LottoResult.js"; class App { async run() { try{ const moneyInput = await Console.readLineAsync('로또 구입 금액을 입력해주세요.\n'); - const ticketCount = getTicketCount(Number(moneyInput)); + const purchaseAmount = Number(moneyInput) + const ticketCount = getTicketCount(purchaseAmount); Console.print(ticketCount + '개의 로또를 구입했습니다.'); const tickets = generateLottoTickets(ticketCount); @@ -21,6 +22,10 @@ class App { const bonusInput = await Console.readLineAsync('보너스 번호를 입력해주세요.\n'); const bonusNumber = parseBonusNumber(bonusInput); Console.print('보너스 번호 : ' + bonusNumber); + + const winningCounts = calculateWinningCounts(tickets, winningNumbers, bonusNumber); + printWinningStatistics(winningCounts, purchaseAmount); + } catch (error) { Console.print([error.message]); } diff --git a/src/Lotto.js b/src/Lotto.js index 98fbf06..7af5118 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -11,10 +11,15 @@ class Lotto { throw new Error("[ERROR] 로또 번호는 6개여야 합니다."); } } - + toString(){ return "[" +this.#numbers.join(', ') + "]"; } + + // 당첨 계산에 사용될 로또 번호 배열 반환 + getNumbers() { + return this.#numbers; + } } export default Lotto; diff --git a/src/LottoResult.js b/src/LottoResult.js new file mode 100644 index 0000000..6b7067e --- /dev/null +++ b/src/LottoResult.js @@ -0,0 +1,72 @@ +import { Console } from '@woowacourse/mission-utils'; + +function calculateWinningCounts(tickets, winningNumbers, bonusNumber) { + // 당첨 번호 일치 개수 추출 + const counts = {}; + for (const ticket of tickets) { + + const numbers = ticket.getNumbers(); + const matchCount = numbers.filter(num => winningNumbers.includes(num)).length; + //Console.print(`티켓: [${numbers.join(', ')}], 일치 개수: ${matchCount}`); + + if (matchCount === 6) { + counts.six = (counts.six || 0) + 1; + continue; + } + if (matchCount === 5) { + if (numbers.includes(bonusNumber)) { + counts.bonus = (counts.bonus || 0) + 1; + } else { + counts.five = (counts.five || 0) + 1; + } + continue; + } + if (matchCount ===4 ) { + counts.four = (counts.four || 0) + 1; + continue; + } + if (matchCount ===3 ) { + counts.three = (counts.three || 0) +1; + } + } + return counts; +} + +function calculateTotalWinning(winningCounts) { +// 총 당첨 금액 계산 + const PRIZE_THREE = 5000; + const PRIZE_FOUR = 50000; + const PRIZE_FIVE = 1500000; + const PRIZE_BONUS = 30000000; + const PRIZE_SIX = 2000000000; + return ((winningCounts.three || 0) * PRIZE_THREE ) + + ((winningCounts.four || 0) * PRIZE_FOUR ) + + ((winningCounts.five || 0) * PRIZE_FIVE ) + + ( (winningCounts.bonus || 0) * PRIZE_BONUS ) + + ( (winningCounts.six || 0) * PRIZE_SIX ); +} + +function calculateYield(totalWinning, purchaseAmount){ + //수익률 계산 + return Math.round((totalWinning / purchaseAmount) * 1000) / 10; +} + +function printWinningStatistics(winningCounts, purchaseAmount) { + const three = winningCounts.three || 0; + const four = winningCounts.four || 0; + const five = winningCounts.five || 0; + const bonus = winningCounts.bonus || 0; + const six = winningCounts.six || 0; + const totalWinning = calculateTotalWinning(winningCounts); + const yieldRate = calculateYield(totalWinning, purchaseAmount); + Console.print('당첨 통계'); + Console.print('---') + Console.print(`3개 일치 (5,000원) - ${three}개`) + Console.print(`4개 일치 (50,000원) - ${four}개`) + Console.print(`5개 일치 (1,500,000원) - ${five}개`) + Console.print(`5개 일치, 보너스 볼 일치 (30,000,000원) - ${bonus}개`) + Console.print(`6개 일치 (2,000,000,000원) - ${six}개`) + Console.print(`총 수익률은 ${yieldRate}%입니다.`) +} + +export { calculateWinningCounts, calculateTotalWinning, calculateYield, printWinningStatistics }; \ No newline at end of file