brunch

You can make anything
by writing

C.S.Lewis

by Cylogic May 12. 2018

로또 1등 확률 계산법-코딩수업#4

두 번째 문제

다음 이야기는 고등학교 때 배운 순열과 조합 공식을 사용하면 간단하지만, 수학을 공식으로 풀기보다는 사고에 의해 풀어가는 게 이 수업의 원칙이라고 생각하여 논리적인 이야기로 먼저 풀어 보도록 하자.


생각 #1


만일 로또 번호가 6개의 숫자를 뽑을 뿐 아니라 그 순서까지 따져서 일등을 정한다고 가정해 보자.


로또 숫자는 45개 이므로 특정 숫자 하나를 45개의 숫자 중에 뽑을 확률은

1/45


남은 숫자는 44개 이므로 여기서 숫자 하나를 뽑을 확률은

1/44


여기서 다시 숫자 하나를 뽑을 확률은 

1/43


이렇게 세 번 더 뽑으면

1/ 42, 1/41, 1/40 의 확률에 의하여 각각 한 개의 숫자가 뽑히게 된다.


따라서 이 확률 모두를 곱하게 되면


1 나누기 (45 X 44 X 43 X 42 X 41 X 40)의 확률이 로또 1등에 당첨될 확률이다.


이를 단순히 계산해 보니 1 나누기 5,864,443,200 이 된다. 5십8억6천5백만 분의 일 정도가 된다는 얘기다.

그런데 이 확률은 숫자 공이 뽑히는 순서까지를 계산한 것으로 실제 로또 1등의 당첨 확률이 아니다.


고등학교에서 배운 순열 수업이 떠오르지 않으시는가?^^


이제 순서에 상관없이 6개의 공만 뽑는다는 조건으로 다시 한번 정답을 찾아보자.

생각 #2


첫 번째 확률은 45개 숫자 중 6 당첨 숫자 중 하나를 뽑을 확률이니 아까의 확률에서 6을 곱해주자.

(1/45) X 6


두 번째 확률은 44개 숫자 중 5 당첨 숫자 중 하나를 뽑을 확률이니  같은 요령으로...

(1/44) X 5


세 번째 확률은 43개 숫자 중 4 당첨 숫자 중 하나이니 같은 요령으로...

(1/43) X4


이렇게 세 번 더 뽑으면

(1/42)X3, (1/41)X2, (1/40)X1 의 확률에 의하여 각각 한 개의 숫자가 뽑히게 된다.


이렇다면 아까 계산한 5,864,443,200을 (6X5X4X3X2X1)로 나누어 주어야 하고,

이 값은 8,145,060 이 된다. 


분자는 어차피 1이니(1등 숫자) 분모의 크기만 구해지면 된다.


이런 풀이가 가능하다면 2등, 3등, 4등의 당첨 확률을 계산하거나 로또 업체에 따라 다른 숫자 공의 개수 등과 상관없는 계산 공식을 만들어 가는 것이 가능하게 된다.


문제를 풀 때 특정 상황에서 풀어진 문제의 해법을 일반화하는 과정을 거치는 경우가 있는데, 코딩에서도 같은 형태롤 문제를 풀어나갈 수 있다.


이를 코딩으로 해결하는 방법을 함께 생각해 보자.

물론 컴퓨터 프로그램 언어의 라이브러리에 따라 이러한 계산이 하나의 함수로 만들어져 있는 경우도 있지만, 우리는 공부하는 입장이니 단순 무식하게 처리해 보는 것이다.


1. 정답이 들어갈 변수 NumProb를 미리 정의하고 1이라는 숫자를 넣어두자.(NumProb=1로 대입)


2. 로또에서 숫자 볼의 개수를 저장할 수 있는 변수를 NumPool이라고 정하자.

     우리나라 로또의 경우 45가 될 것이다. (NumPool=45로 대입)


3. 1등 당첨에 필요한 숫자의 개수를 저장할 수 있는 변수를 NumFirst라고 정하자.

     우리나라 로또에서는 6이 될 것이다. (NumFirst=6으로 대입)


4. 이중에 처음에는 6개로 시작하여 마지막 1개를 뽑는 것을 반복적으로 수행하며 각각의 확률을 계산하여 이를 곱한다. 조금 복잡하겠지만 이러한 반복을 정리해 보자면...

NumPool과 NumFirst를 초기의 값에서 한 단계를 지나면 1씩 빼고 각 확률을 계산하며, NumFirst가 0이 될 때까지 이를 반복하면 된다.


이를 도식화해보자


코딩수업#1과 같이 코딩으로 표현해 보자.

단, 분자는 1이므로 그 분모의 값을 구하는 프로그램을 만드는 것이 유용할 것이다.

아래에 NumProb를 구하는 부분이 위의 그림과는 달리 그 분모만을 구하는 형식으로 만들어본 코드이다.

var NumProb=1;
var NumPool=45;
var NumFirst=6;
 
for ( x=1; x <= 6; x++) {
    NumProb=NumProb*NumPool/NumFirst; // 분모만을 구하는 방식.
    NumPool=NumPool-1;
    NumFirst=NumFirst-1;
}
document.writeln(NumProb);


앞선 수업과 다를 바 없는 코드가 나왔다.

일반화하지 않은 코드여서 확장성은 없지만 일단은 눈에 보이는 그대로 풀어본 것이다.

왼쪽에 8145060이라는 정답이 출력되었다.



아직은 코드 부분은 이해할 필요 없다. '어떻게 문제를 풀어가는가' 하는 과정이 중요하다.

그리고 말로 설명하면 쉬울 것이 글로 정리하여 어려운 것일 수도 있을 것이니 이해를 부탁드린다.


다음 이야기에서 현재의 방법을 일반화하는 방법을 생각해 보자.

매거진의 이전글 조건 비교 맛보기-코딩수업#3
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari