로또 번호 만들기
<조건>
- 랜덤숫자 만들어, 배열에 추가하기
- for문을 이용해 6번 반복
let numbers = []; function addNumber() { const num = Math.ceil(Math.random() * 45); if (num > 0) { numbers.push(num); } // else {}, 0이 나올 경우 다시 숫자를 만들어야 하는데 어떻게 해야 할지 모르겠음 } for (let i = 0; i < 6; i++) { addNumber(); } console.log(numbers);
- 문제 : 랜덤숫자가 0이 나올 경우 배열에 추가하지 않도록 함. 그래서 고정적으로 6번을 반복하게 할 경우, 랜덤숫자로 0이 나온 경우의 수만큼 숫자가 부족하게 됨.
- [1/30] 해결 : 아래 "랜덤숫자의 생성과 범위" 참고.
- while문을 이용해 배열에 숫자가 6번 추가될 때까지 반복
let numbers = []; function addNumber() { const num = Math.ceil(Math.random() * 45); if (num > 0) { numbers.push(num); } } let i = numbers.length; while (i < 6) { addNumber(); i = numbers.length; } // while문을 이용해서 배열의 길이가 6이 될 때까지(숫자가 6개 찰 때까지) 숫자를 추가해줌. console.log(numbers);
- 문제 해결됨.
- [참고] https://curryyou.tistory.com/202
- for문 응용해서 위 while문 구현
let numbers = []; function addNumber() { const num = Math.ceil(Math.random() * 45); if (num > 0) { numbers.push(num); } } for (let i = numbers.length; i < 6; i = numbers.length) { addNumber(); } console.log(numbers);
- while문 보다 짧고 간결함.
- for문을 이용해 6번 반복
- 중복 걸러내기
let numbers = []; function makeNumber() { const randomNum = Math.ceil(Math.random() * 45); if (randomNum > 0) { return randomNum; } } // 1~45의 숫자를 만드는 함수. 0이 만들어질 경우 값을 리턴하지 않는다. function addNumber() { for (let i = numbers.length; i < 6; i = numbers.length) { let num = makeNumber(); for (let i = 0; i < numbers.length; i++) { if (num === numbers[i]) { console.log("중복 발생 " + num); num = makeNumber(); console.log("새로운 숫자 생성" + num); i = 0; // 중복 확인할 숫자가 새로 생성되었으므로 배열의 첫번째 요소부터 확인하기 위해 i를 0으로 바꿈. } } numbers.push(num); } } addNumber(); console.log(numbers);
- 랜덤숫자를 생성하는 makeNumber 함수와, 랜덤숫자를 기존 배열의 요소들과 비교하여 중복되지 않을 때 배열에 추가하는 addNumber 함수로 나눔.
- makeNumber : 0~45 사이의 숫자를 랜덤으로 생성 후 0이 아닐 때만 값을 리턴함.
- addNumber : makeNumber() 함수로 랜덤숫자 생성. for문 안의 for문에서 랜덤숫자가 배열의 모든 요소와 비교하여 값이 같은 경우(중복 발생) 새로운 랜덤숫자를 생성함.
- 확인 결과
- 두번째 숫자가 첫번째 숫자인 7로 중복되어 44로 대체됨. 그리고 6번째 숫자가 다시 세번째 숫자인 16으로 중복되어 42로 대체됨.
- 랜덤숫자의 생성과 범위
- Math.random() : 난수 생성 함수. 0~1 사이의 실수를 랜덤으로 생성함. 보통 응용하여 원하는 범위만큼 곱해서 사용.
- 예) Math.random() * 10 : 0~10 사이의 난수가 생성됨.
- Math.ceil(), Math.floor(), Math.round() : 받은 숫자를 올림/내림/반올림 함.
- Math.floor(Math.random() * 45)
- 0~45 사이의 난수가 생성되면 내림하므로 0~0.9999는 0, 1~1.99999는 1이 되는 방식으로 44~44.9999는 44가 되고, 45일 때(Math.random()의 결과가 1일 때)만 45가 나옴.
- 문제 : 제시된 조건에서 1~45가 랜덤번호의 범위. 0이 나오면 안 됨.
- 해결 1) Math.floor(Math.random() * 44) + 1 : 0~44 사이의 정수가 생성된 뒤 1이 더해져, 결과적으로 1~45 사이의 정수가 나옴. 하지만 45가 나올 경우는 오직 Math.random()의 결과가 1일 때만이기 때문에 사실상 로또번호로 45가 나오기 힘듦.
- [1/30] 잘못 알고 있어서 괜히 고생함. 좀 찾아볼 걸;; 알고 보니 Math.random()의 값은 0.0000부터 0.99999까지로, 1이 포함되지 않음. 따라서 그냥 Math.floor(Math.random() * 45) + 1 하면 됨.
- 해결 2) 0이 나온 경우를 체크하여 로또번호(배열)에 저장하지 않음. 이 경우, 6번으로 정해두고 for문을 돌리면 로또 추첨 결과가 5개 숫자로 끝나는 오류가 날 수 있음. for문의 i(카운터변수)가 반복할 실행문 종료 후 배열의 길이(저장된 로또번호의 수)가 되도록 함. 즉, 증감식에 i++이 아니라 i=numbers.length를 씀.
- Math.random() : 난수 생성 함수. 0~1 사이의 실수를 랜덤으로 생성함. 보통 응용하여 원하는 범위만큼 곱해서 사용.
- 공부할 것
- 콜백함수의 개념
- 배열 중복 제거 : https://hianna.tistory.com/422 Set 객체, filter(), indexOf() 등
'TIL' 카테고리의 다른 글
[TIL-88] 위코드 사전스터디 자바스크립트 01~05 (0) | 2022.01.05 |
---|---|
[TIL-86~87] 위코드 사전스터디 3주차 : 가위바위보 (0) | 2022.01.01 |
[TIL-84] 위코드 사전스터디 1주차 과제: 자기소개 페이지 만들기 (0) | 2021.12.20 |
[TIL-83] 노마드코더 유튜브 클론코딩 #6.17~#6.19 (0) | 2021.12.16 |
[TIL-81~82] 노마드코더 유튜브 클론코딩 #6.14~#6.16 (0) | 2021.12.14 |