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) 이

위의 방법을 사용합니다.


Posted by 잇힝2012
,