코딩 수업이 아니라 로또 수업이냐는 비난이 나올 수도 있겠지만 ^^...
다양한 독자층의 관심을 위하여 로또 이야기를 좀 더 이어 가겠다.
그리고 다음 수업에서 지금까지 배운 내용을 1차로 정리하는 시간을 가져 보려 한다.
45개 숫자에서 6개의 숫자를 고르는 것이 로또의 기본 룰이니 45개의 공이 마구 뒤섞이며 하나씩 밖으로 튀어나오는 것을 코딩으로 시뮬레이션해보는 것이 이번 수업의 내용이다.
원칙을 단순화 하자.
1. 45개의 숫자에서 1개를 고른다. (물론 어떤 숫자가 튀어나올지는 모른다.)
2. 한번 나온 숫자는 다시 나올 수 없다.
3. 이러한 과정을 6번에 걸쳐 진행한다.
순서도로 해당 사항을 살펴보면 다음과 같다.
프로그램 명령어에는 random이라는 명령어(또는 함수)가 있다.
무작위로 숫자를 뽑는 일을 수행한다.
물론 언어에 따라 사용의 방법은 다르지만, java script를 기반으로 설명해 보겠다.
먼저 공을 뽑아보자.
Math.random();
이라고 하면 0부터 1 사이의 실수가 무작위로 하나 생성된다.
Math.random()*45;
라고 하면 0부터 45 사이의 실수가 나오게 되는데,
우리가 필요한 것은 실수가 아니고 정수이다.
Math.floor(Math.random() * 45);
이렇게 하면 소수점 아래의 작은 숫자를 그냥 날려버린다.
반올림 같은 거 무시하고 묻지도 따지지도 않고 날린다.^^
그런데 이럴 경우 로또 번호로 필요 없는 0은 나오고 45는 나오지 않게 된다.
따라서 거기에 1을 더해 준다.
var num=Math.floor(Math.random() * 45) +1;
이렇게 하면 1,2,3,....., 43,44,45 중의 한 개의 숫자가 생성되어 num이라는 변수에 대입된다.
뽑은 공이 사용 가능한지 살펴보자.
6개의 공을 뽑을 예정이므로 방을 6개 만들자.
변수를 만들기 위하여
var result;
와 같이 변수를 선언할 수 있다.
그런데 같은 이름으로 호실만 다르게 6개의 방을 만들고 싶다.
각 방에는 우리가 필요하지 않은 숫자 0 이 들어가 있다고 가정하자.
var result={ 0 , 0 , 0 , 0 , 0 , 0 };
이렇게 하면 된다.
이제 result는 6개의 방으로 구성되어 있고
각 방의 이름은 result에 호실명이 [0],[1],[2],[3],[4],[5]와 같이 붙을 것이다.
시작을 0부터 한다는 것에 주의 하자.
뽑은 공의 숫자를 각 방에 집어넣을 것인데, 뽑힌 공이 사용이 불가능한 경우는 이미 뽑힌 공이 다시 뽑힌 경우뿐이다.
이전에 조건 비교를 했을 때를 생각하고 비교해 보자면
num에 새로운 숫자가 생성되고 이를 첫 번째 방의 숫자와 비교해 본다면 다음과 같을 것이다.
아래에서는 num이 1이므로 당연히 "다르다"가 출력된다.
var result={ 0 , 0 , 0 , 0 , 0 , 0 };
var num=1;
if (num==result[0]) document.write("같다");
else document.write("다르다");
num을 0으로 변경시키면 "같다"가 출력된다.
이제 우리의 문제 풀이 순서도를 코드로 만들어 보자.
앞서 보셨겠지만
// 뒤에 들어가는 말은 코드의 설명이고 실제 프로그램의 수행에는 어떤 영향도 끼치지 않는다.
var result=[ 0 , 0 , 0 , 0 , 0 , 0 ]; // 6개의 숫자가 들어갈 방(변수)을 만든다.
var num; // 새로 뽑히는 숫자가 들어갈 변수
var i=0; // 방의 위치 -
// 6개의 숫자가 다 뽑혔는지를 확인하기 위한 변수로도 쓰인다.
do{ // 여기서부터 아래에 나오는 While까지를 반복하게 된다.
num=Math.floor(Math.random() * 45) +1; // 1부터 45까지의 임의의 숫자를 뽑는다.
for (var j=0;j<=i;j++){ // 뽑힌 숫자가 이미 뽑힌 숫자와 같은지를 확인한다.
if (num==result[j]) break; // 만일 같다면 비교를 중단하라.
} // 여기까지가 뽑힌 숫자가 같은지를 확인하는 부분의 끝
if (j<i) continue; // 같아서 중단됐다면 다시 숫자를 뽑기 위하여 do 위치로.
result[i]=num; // 새로 뽑힌 숫자를 숫자의 방에 넣는다.
i++; // 다음 방을 위하여 방의 번호를 하나 증가시킨다.
}while(i<6) // 앞의 Do부터 반복하게 되는 부분의 끝
for (var i=0;i<6;i++) document.write(result[i]+","); // 방의 내용을 인쇄한다. 중간에 ","를 인쇄한다.
document.write("<br>"); // 다시 처리할 때 인쇄되는 내용을 구분하기 위하여 줄을 바꾼다.
설명은 자세히 한 듯 보이나 좀 어려워 보인다.
뭔가 그림 하나라도 더 붙여서 황당함을 해소해 보자.
위에 보는 바와 같이 두 가지 반복의 방법이 있음을 알 수 있다.
do ~~~ while 의 방법
for ~~~ 의 방법
물론 더 많은 방법으로 같은 코드를 반복할 수 있지만 위의 방법의 2가지 형식의 전형을 보여준다.
for의 경우는 반복의 횟수를 미리 정하고 반복하는 것이고
do의 경우는 반복의 조건을 맞출 때까지 반복하는 것이다.
이 내용은 다음 수업에 다시 정리하려고 한다.
굳이 이러한 내용을 미리 말하고자 하는 것은,
동일한 결과를 도출하는 방법이 무척 다양하다는 것을 알리려고 한 것이다.
조건을 통한 분기의 방법도 마찬가지다.
앞서 이야기 한 if라는 명령어를 사용할 수도 있고, switch라는 명령어를 사용할 수 있다.
이러한 다양한 방법에 대해 이해하고, 다음 수업에서 다시 정리해 보자.
앞서 보여준 코드를 여러 번 개발도구에서 실행해 보았다.
각 줄마다 6개의 숫자가 인쇄됨을 보여준다.
이 프로그램이 제시한 숫자가 1등에 당첨될 확률이 있냐고 물으신다면...
앞선 수업의 1등 확률을 보시면 답이 있으니 참조하시길^^