JAVA 로또 알고리즘 구성 과정

#JAVA007 #알고리즘 #로또 #함수화작업
Dec 19, 2023
JAVA 로또 알고리즘 구성 과정
 

🍒 로또 알고리즘의 논리 구조

모두가 당첨되길 원하는 로또의 번호 생성 구조를 한 번 살펴보자. 로또는 1부터 45까지 수로 6가지의 랜덤 숫자를 뽑아서 모든 숫자를 맞추게 되면 1등이 된다. 그리고 로또는 중복되는 숫자가 없이 모든 요소가 유일한 값이다. 그렇다면 이런 논리 구조로 정리 해볼 수 있겠다.
 
  • 6개의 랜덤 숫자를 추출
  • 6개의 숫자는 중복되는 수가 있어서는 안됨
  • 첫 번째 회전에서는 어떤 숫자든 배열[0]에 대입 가능
  • 두 번째 회전부터는 랜덤 수가 이미 대입된 배열 값 이랑 중복되는지 비교해야됨.
 
자 그럼 하나 씩 만들어 가보자.
 
 
 

🥐 첫 번째 미션 : 기본 구조 만들기

첫 번째 배열 값의 기본 구조
notion image
  • 로또 번호를 담을 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. 다섯 번째 열에 대입 하기전 첫/두/세/네 번째 배열이랑 중복되지 않는 지 체크
notion image
  • 논리적으로는 매번 랜덤 값을 생성해서 각 배열의 자리를 대입하는 모습이 이렇게 나온다.
  • 이 반복 중에 규칙성이 보이는 것 같다.
    • arr[]는 매 회전 마다 인덱스 값의 증가와 비교 횟수가 동일하게 증가한다.
    • 매번 랜덤 함수 생성하는 것.
    • 대입해야 되는 인덱스 값 또한 순차적 증가가 이루어 진다.
 
 
결과값
결과값
  • ?! 결과는 그냥 나왔다. 작동은 잘 되는 것 같다
  • 하지만 내가 원하는 것은 알고리즘이기에 이제 부터 함수화가 가능한 부분은 최대한 줄여나가 볼 것이다.
 
 
notion image
  • 근데 0은 왜 나왔을까???
  • 고민해보니, Math.random() 함수가 0.0부터 1.0까지의 난수이기 때문에 나온 것 같다. 여기서 +1을 해준다면 말끔히 해결될 것 같다.
  • 따라서 난수 함수를 int rand = (int)((Math.random()*45)+1); 로 교체해 주었다.
 
 
 

🍑 세 번째 미션 : 함수화 하기

함수화 작업 1차 매 저장되는 난수의 배열은 순차적 증가가 이루어 진다.
notion image
  • 각 배열 자리에 랜덤 값을 넣는 기능을 for구문으로 함수 적용 하였다.
  • 내가 원했던 변수는 제일 마지막 줄 arr[i]=rand; 에 순차적 증가 적용이었다.
 
 
결과값
결과값
  • 일단 결과 값은 잘 나오는 함수 이지만,
  • 많이 시도할 수록 중복된 숫자가 찍힐 가능성이 있다.
  • 이제는 비교하는 기능을 함수화 해야 된다.
 
 
함수화 작업 2차 매 회전이 늘어날 때마다 비교 횟수도 비례 증가한다.
notion image
  • 비교 기능을 함수에서는 배정된 난수가 바뀌면 안되므로 난수 아래에 for 구문을 배치하였다.
 
 
 
결과값
결과값
  • 그러나 이 코드 만으로는 중복 값이 나온다. 어떻게 된 일일까???
  • 고민을 해보니, 중복 값을 발견하게 되면 다시 난수를 새로 받아서 재 회전하는 기능이 없었기 때문인 것 같다.
 
 
디버깅..
notion image
  • 디버깅을 해보니, 같은 수가 나와서 break를 하게 되더라도 함수를 업데이트하고 회전하는 바람에 중복 감시 기능 소용이 없었던 것 같다.
 
 
해결
notion image
  • 난수를 먼저 업데이트하고 중복 비교 기능을 하기로 하고, 그 후에 같은 값이 나오면 다시 난수를 받는 식으로 순서를 변경해주었다.
 
 
결과값
결과값
  • 수차례 돌려보니 더 이상 중복 수는 안 나오는 것 같다.
  • 성공한 것 같은데, 아니면 몇 번 돌리는 지 카운트 하기로 하고 중복값 나올 때까지 돌리는 데 무한으로 돈다면은 성공한 게 아닐까 싶기도 하다.
 
 
 

🍏 결과 : 로또 알고리즘 완성

로또 알고리즘 완성
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

AI_Nomads