6수로 이루어진 로또번호를 랜덤하게 출력 합니다.
단순히 1~45 사이의 수 6개를 랜덤하게 생성하는 방법은 이전 포스팅에서 해 보았고 (http://sociallottowork.tistory.com/35)
여기서는 1~8145060 사이의 수 1개를 랜덤 생성한 후, 이 번호를 로또번호로 변환하는 방법을 사용합니다.
1~8145060 이라는 큰수 랜덤을 효과적으로 생성하기 위해 WELL Random (http://sociallottowork.tistory.com/36) 을 사용하고,
이렇게 생성된 번호를 로또번호로 변환하기 위해 getLottoNumberByOrderNumber 함수 (http://sociallottowork.tistory.com/33) 를 사용할 것입니다.
이 방법을 사용하면, 로또 시뮬레이터를 구현할때, 랜덤 생성 과정을 현격히 줄여, 고속 시뮬레이터 구현이 가능하게 됩니다.
또한 여러 로또 조합에 대한 정렬 및 차집합 계산 등에 있어서도 유리합니다.
즉, 로또프로그램 내부에서 로또번호조합이 아닌, 정수(1~8145060)로만 취급하게 됨으로써 연산에 있어 여러가지 이점을 얻을 수 있습니다.
아래는 그 내용을 담고 있는 소스코드 입니다.
WELL1024a.cpp
/* ***************************************************************************** */
/* Copyright: Francois Panneton and Pierre L'Ecuyer, University of Montreal */
/* Makoto Matsumoto, Hiroshima University */
/* Notice: This code can be used freely for personal, academic, */
/* or non-commercial purposes. For commercial purposes, */
/* please contact P. L'Ecuyer at: lecuyer@iro.UMontreal.ca */
/* ***************************************************************************** */
#define W 32
#define R 32
#define M1 3
#define M2 24
#define M3 10
#define MAT0POS(t,v) (v^(v>>t))
#define MAT0NEG(t,v) (v^(v<<(-(t))))
#define Identity(v) (v)
#define V0 STATE[state_i ]
#define VM1 STATE[(state_i+M1) & 0x0000001fU]
#define VM2 STATE[(state_i+M2) & 0x0000001fU]
#define VM3 STATE[(state_i+M3) & 0x0000001fU]
#define VRm1 STATE[(state_i+31) & 0x0000001fU]
#define newV0 STATE[(state_i+31) & 0x0000001fU]
#define newV1 STATE[state_i ]
#define FACT 2.32830643653869628906e-10
static unsigned int state_i = 0;
static unsigned int STATE[R];
static unsigned int z0, z1, z2;
void InitWELLRNG1024a (unsigned int *init){
int j;
state_i = 0;
for (j = 0; j < R; j++)
STATE[j] = init[j];
}
double WELLRNG1024a (void){
z0 = VRm1;
z1 = Identity(V0) ^ MAT0POS (8, VM1);
z2 = MAT0NEG (-19, VM2) ^ MAT0NEG(-14,VM3);
newV1 = z1 ^ z2;
newV0 = MAT0NEG (-11,z0) ^ MAT0NEG(-7,z1) ^ MAT0NEG(-13,z2) ;
state_i = (state_i + 31) & 0x0000001fU;
return ((double) STATE[state_i] * FACT);
}
WELL1024a.h
/* ***************************************************************************** */
/* Copyright: Francois Panneton and Pierre L'Ecuyer, University of Montreal */
/* Makoto Matsumoto, Hiroshima University */
/* Notice: This code can be used freely for personal, academic, */
/* or non-commercial purposes. For commercial purposes, */
/* please contact P. L'Ecuyer at: lecuyer@iro.UMontreal.ca */
/* ***************************************************************************** */
void InitWELLRNG1024a (unsigned int *init);
double WELLRNG1024a (void);
main.cpp
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <iostream> /* cout, endl */
#include <time.h> /* time */
#include "WELL1024a.h" // WELL Random number generator http://www.iro.umontreal.ca/~panneton/WELLRNG.html
using namespace std;
// 로또조합 순서값(1~8145060)으로 로또조합 알아내기
void getLottoNumberByOrderNumber(int o, int *r)
{
int sum=0,nn=0,a=0,b=0,c=0,d=0,e=0,f=0;
for(a=1; a<=40; a++) {
nn = ((45-a)*(45-a-1)*(45-a-2)*(45-a-3)*(45-a-4)) / (5*4*3*2*1);
if(sum+nn>=o) break;
sum += nn;
}
for(b=a+1; b<=41; b++) {
nn = ((45-b)*(45-b-1)*(45-b-2)*(45-b-3)) / (4*3*2*1);
if(sum+nn>=o) break;
sum += nn;
}
for(c=b+1; c<=42; c++) {
nn = ((45-c)*(45-c-1)*(45-c-2)) / (3*2*1);
if(sum+nn>=o) break;
sum += nn;
}
for(d=c+1; d<=43; d++) {
nn = ((45-d)*(45-d-1)) / (2*1);
if(sum+nn>=o) break;
sum += nn;
}
for(e=d+1; e<=44; e++) {
nn = ((45-e)) / (1);
if(sum+nn>=o) break;
sum += nn;
}
for(f=e+1; f<=45; f++) {
nn = 1;
if(sum+nn>=o) break;
sum += nn;
}
sum++;
r[0] = a;
r[1] = b;
r[2] = c;
r[3] = d;
r[4] = e;
r[5] = f;
}
int main(int argc, char *argv[])
{
srand((unsigned)time(NULL));
unsigned int init[32];
for(int i=0; i<32; i++) {
init[i] = rand()<<16 | rand();
// WELL Random 을 초기화 하기 위해, C 표준 rand() 함수를 이용하여 init 값을 생성합니다
}
InitWELLRNG1024a(init); // WELL Random 초기화
for(int i=0; i<10; i++) {
int rnd = (int)((double)WELLRNG1024a() * (8145060-1+1)) + 1; // 1~8145060 정수 랜덤 생성
int r1[6]={0,}; // 로또번호를 저장할 배열
getLottoNumberByOrderNumber(rnd, r1); // 로또 순서 rnd 번에 해당하는 로또번호를 r1 배열에 저장
printf("%02d,%02d,%02d,%02d,%02d,%02d\n", r1[0],r1[1],r1[2],r1[3],r1[4],r1[5]);
}
printf("\n");
getchar();
return 0;
}
위 소스코드를 응용하면 로또 고속시뮬레이터등을 구현 할 수 있습니다.
소셜로또워크(http://www.sociallottowork.com/bbs/board.php?bo_table=download) 의 시뮬레이터와
소셜로또워크 시뮬레이터 안드로이드 앱(http://www.sociallottowork.com/bbs/board.php?bo_table=download&wr_id=68) 이
위의 방법을 사용합니다.
'프로그래밍' 카테고리의 다른 글
로또 당첨 등수 확인 하기 (c/c++)(로또함수) (0) | 2014.08.06 |
---|---|
1등 당첨번호+보너스번호를 이용하며 모든 1~5등 조합 생성하기 (c/c++)(로또함수) (0) | 2014.08.04 |
random, rand(), 큰수 랜덤, WELL 랜덤 (c/c++) (0) | 2014.08.04 |
로또번호 자동 생성 (랜덤, random)(c/c++)(로또함수) (0) | 2014.08.04 |
순서번호로 로또 조합 알아내기 (c/c++)(로또함수) (0) | 2014.08.03 |