🍒 로또 알고리즘의 논리 구조
모두가 당첨되길 원하는 로또의 번호 생성 구조를 한 번 살펴보자. 로또는 1부터 45까지 수로 6가지의 랜덤 숫자를 뽑아서 모든 숫자를 맞추게 되면 1등이 된다. 그리고 로또는 중복되는 숫자가 없이 모든 요소가 유일한 값이다. 그렇다면 이런 논리 구조로 정리 해볼 수 있겠다.
- 6개의 랜덤 숫자를 추출
- 6개의 숫자는 중복되는 수가 있어서는 안됨
- 첫 번째 회전에서는 어떤 숫자든 배열[0]에 대입 가능
- 두 번째 회전부터는 랜덤 수가 이미 대입된 배열 값 이랑 중복되는지 비교해야됨.
자 그럼 하나 씩 만들어 가보자.
🥐 첫 번째 미션 : 기본 구조 만들기
첫 번째 배열 값의 기본 구조
- 로또 번호를 담을 6공간의 배열을 생성하고
Math.random()
을 이용하여 45까지의 난수를 생성하는 코드 작성
- 첫 번째 배열은 어떤 값이 되든 상관없으므로 일단 하나 넣었다.
- 그리고
for-each
구문을 쓰지 않고 배열을 출력하는 코드를 배워서Arrays.toString(배열
)을 사용하였다.
for-each
구문보다Arrays.toString()
명령어가 더 깔끔하다는 걸 깨달았다. 자주 써먹어야지
배열 출력 구문
System.out.println(Arrays.toString(arr)); // for each 없이 배열을 출력할 때, // Arrays.toString(배열이름)으로 출력이 가능하다.
🍅 두 번째 미션 : 뭐라해야되나.. 틀 만들기?
논리구조 1. 두 번째 열에 대입하기 전 첫 번째 배열이랑 중복되지 않는지 체크, 1번 비교하게 된다. 2. 세 번째 열에 대입하기 전 첫 번째/두 번째 배열이랑 중복되지 않는지 체크, 2번 비교하게 된다. 3. 네 번째 열에 대입 하기전 첫/두/세 번째 배열이랑 중복되지 않는지 체크, 3번 비교하게 된다. 4. 다섯 번째 열에 대입 하기전 첫/두/세/네 번째 배열이랑 중복되지 않는 지 체크
- 논리적으로는 매번 랜덤 값을 생성해서 각 배열의 자리를 대입하는 모습이 이렇게 나온다.
- 이 반복 중에 규칙성이 보이는 것 같다.
arr[]
는 매 회전 마다 인덱스 값의 증가와 비교 횟수가 동일하게 증가한다.- 매번 랜덤 함수 생성하는 것.
- 대입해야 되는 인덱스 값 또한 순차적 증가가 이루어 진다.
- ?! 결과는 그냥 나왔다. 작동은 잘 되는 것 같다
- 하지만 내가 원하는 것은 알고리즘이기에 이제 부터 함수화가 가능한 부분은 최대한 줄여나가 볼 것이다.
- 근데 0은 왜 나왔을까???
- 고민해보니,
Math.random()
함수가0.0부터 1.0까지의 난수
이기 때문에 나온 것 같다. 여기서+1
을 해준다면 말끔히 해결될 것 같다.
- 따라서 난수 함수를
int rand = (int)((Math.
random
()*45)+1);
로 교체해 주었다.
🍑 세 번째 미션 : 함수화 하기
함수화 작업 1차 매 저장되는 난수의 배열은 순차적 증가가 이루어 진다.
- 각 배열 자리에 랜덤 값을 넣는 기능을 for구문으로 함수 적용 하였다.
- 내가 원했던 변수는 제일 마지막 줄
arr[i]=rand;
에 순차적 증가 적용이었다.
- 일단 결과 값은 잘 나오는 함수 이지만,
- 많이 시도할 수록 중복된 숫자가 찍힐 가능성이 있다.
- 이제는 비교하는 기능을 함수화 해야 된다.
함수화 작업 2차 매 회전이 늘어날 때마다 비교 횟수도 비례 증가한다.
- 비교 기능을 함수에서는 배정된 난수가 바뀌면 안되므로 난수 아래에
for 구문
을 배치하였다.
- 그러나 이 코드 만으로는 중복 값이 나온다. 어떻게 된 일일까???
- 고민을 해보니, 중복 값을 발견하게 되면 다시 난수를 새로 받아서 재 회전하는 기능이 없었기 때문인 것 같다.
디버깅..
- 디버깅을 해보니, 같은 수가 나와서
break
를 하게 되더라도 함수를 업데이트하고 회전하는 바람에 중복 감시 기능 소용이 없었던 것 같다.
해결
- 난수를 먼저 업데이트하고 중복 비교 기능을 하기로 하고, 그 후에 같은 값이 나오면 다시 난수를 받는 식으로 순서를 변경해주었다.
- 수차례 돌려보니 더 이상 중복 수는 안 나오는 것 같다.
- 성공한 것 같은데, 아니면 몇 번 돌리는 지 카운트 하기로 하고 중복값 나올 때까지 돌리는 데 무한으로 돈다면은 성공한 게 아닐까 싶기도 하다.
🍏 결과 : 로또 알고리즘 완성
로또 알고리즘 완성
package ex03; import java.util.Arrays; import java.util.Random; public class Lottery { public static void main(String[] args) { int[] arr = new int[6]; int rand = (int)((Math.random()*45)+1); arr[0] = rand; for (int i = 1; i <6; i++) { rand = (int)((Math.random()*45)+1); arr[i]=rand; for (int j = 0; j < i; j++) { if (arr[j] == rand){ i--; break; } } } System.out.println(Arrays.toString(arr)); } }
- 무식하게 나열했던 코드가 군더더기 없이 깔끔하게 정리가 되었다.
- 좀 더 욕심을 부린다면, 몇 번 시도해야 (얼마를 써야) 로또를 맞출 확률이 있는 지 이런 거 계산해 보는 것도 재미있을 것 같다.
Share article