NetBeans 는 훌륭한 PHP IDE 이다.

NetBeans 에서 그누보드 또는 기존의 PHP 소스를 프로젝트로 가져오는 방법은 아래와 같다.


1. File 메뉴

2. New Project

3. PHP: PHP Application with Existing Sources 에서 그누보드 디렉토리를 선택하면 된다.


Posted by 잇힝2012
,


안드로이드 프로젝트를 새로 만들면 위와 같은 오류를 만나게 된다.

에러 내용은 대충 아래와 같다.

[2015-12-06 15:26:15 - SampleActivityNew003_detect3g] Found 2 versions of android-support-v4.jar in the dependency list,

[2015-12-06 15:26:15 - SampleActivityNew003_detect3g] but not all the versions are identical (check is based on SHA-1 only at this time).

[2015-12-06 15:26:15 - SampleActivityNew003_detect3g] All versions of the libraries must be the same at this time.

[2015-12-06 15:26:15 - SampleActivityNew003_detect3g] Versions found are:

[2015-12-06 15:26:15 - SampleActivityNew003_detect3g] Path: C:\Users\m\workspace_empty2\appcompat_v7\libs\android-support-v4.jar

[2015-12-06 15:26:15 - SampleActivityNew003_detect3g]  Length: 1157388

[2015-12-06 15:26:15 - SampleActivityNew003_detect3g]  SHA-1: 605c447c20ca216b5556af9f215af5d4bba1b117

[2015-12-06 15:26:15 - SampleActivityNew003_detect3g] Path: C:\Users\m\workspace_empty2\SampleActivityNew003_detect3g\libs\android-support-v4.jar

[2015-12-06 15:26:15 - SampleActivityNew003_detect3g]  Length: 1364299

[2015-12-06 15:26:15 - SampleActivityNew003_detect3g]  SHA-1: b6c138ba72ce38beda559df33d369856854fd6f5

[2015-12-06 15:26:15 - SampleActivityNew003_detect3g] Jar mismatch! Fix your dependencies

[2015-12-06 15:26:18 - SampleActivityNew003_detect3g] ERROR: In <declare-styleable> MenuView, unable to find attribute android:preserveIconSpacing

[2015-12-06 15:26:23 - SampleActivityNew003_detect3g] ERROR: In <declare-styleable> MenuView, unable to find attribute android:preserveIconSpacing

[2015-12-06 15:28:44 - SampleActivityNew003_detect3g] ERROR: In <declare-styleable> MenuView, unable to find attribute android:preserveIconSpacing

[2015-12-06 15:28:47 - SampleActivityNew003_detect3g] ERROR: In <declare-styleable> MenuView, unable to find attribute android:preserveIconSpacing


원인은 새 프로젝트를 만들면, 그 프로젝트는 appcompat_v7 라이브러리를 참조하게되며, 더불어 최신 android-support-v4.jar 라이브러를 포함하게 된다.

그런데, appcompat_v7 프로젝트는 이미 (과거버전의) android-support-v4.jar 라이브러를 갖고 있는데, 그렇기 때문에 버전 충돌 문제가 발생하는 것이다.



어찌되었건, 이 두개의 라이버리를 동일하게 맞춰주거나, 둘중 하나를 삭제하거나 하면 되는 것이다.


appcompat_v7 프로젝트의 android-support-v4.jar 라이브러리를 최신버전으로 변경하도록 하자.

위 폴더 이미지에서 최신버전이라 생각되는 2015.12.6 에 수정(생성)된 android-support-v4.jar 파일을 그냥 복사하는 방법도 있겠지만, 이클립스 eclipse 에서 제공하는 방법을 이용하자



위와 같이 appcompat_v7 프로젝트를 마우스로 우클릭하여 Android Tools - Add Support Library 를 해주면 된다

그런데 아마 이것만으로 문제가 해결되지는 않을 것이다 (이클립스 이런 문제는 왜 안 고쳐지는지...)


이제, 여전히 오류상태로 x표시가 되어 있는 나의 프로젝트를 선택하여

Add Support Library -> Project Close -> Project Open -> Project Clean 의 과정을 거쳐줘야 한다.








위의 방법이 제대로 방법인지는 알 수 없으나,

아무튼 나는 위와 같은 방법으로 문제를 해결하였다.


Posted by 잇힝2012
,

이클립스에서 개발중 실행할 때는 문제 없이 정상적으로 실행 되던 앱이

Export Signed Apllication Package 하여 구글플레이에 APK 업로드한 후 다운로드한후 실행해보니,

아래 이미지 처럼 "로또관리(이)가 중지되었습니다. 확인/신고" 라는 에러 메시지와 함께 중지되어 버리는 경우가 발생함.



PC에 연결하여 이클립스 logcat 에러 메세지를 보니, 아래와 같은 빨간색 에러메시지가 뜸.

02-15 13:44:58.790: E/AndroidRuntime(9412): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo

{com.sociallottowork.sociallottowork_m/com.sociallottowork.sociallottowork_m.MainActivity}:

 java.lang.ClassNotFoundException: com.sociallottowork.sociallottowork_m.MainActivity


원인(추정): Export Signed Apllication Package 명령에 의해 SampleActivityNew000.apk 파일이 빌드되면서, 무언가 꼬여 버림.

해결책:
1. 재빌드하여 새버전으로 업로드.
2. 프로젝트 clean 먹인후 재빌드하여 새버전으로 업로드.
3. AndroidManifest.xml 파일 내용을 아무곳이나 일부 수정하여 저장한 후, 원래대로 복구하여 다시 저장하여 재빌드하여 새버전으로 업로드.


추가: 

이클립스 Help 메뉴 - Installation Details - Installation History 탭 을 확인해보니,

2015.1.13 에 (Android Development Tools) ADT 23.0.4.1468518  가 업데이트 된 것으로 확인.

위의 오류를 경험 한 날이 2015.1.15 이므로, ADT 23.0.4 업데이트 와 관련이 있지 않을까 생각 중.




Posted by 잇힝2012
,

lotto006.cpp

#include <stdio.h>      /* printf, scanf, puts, NULL */

#include <stdlib.h>     /* srand, rand */

#include <time.h>       /* time */

#include <algorithm>    // std::sort, std::find, std::copy

#include <vector>       // std::vector


void getRandomLottoWin(int *r) // 당첨번호+보너스번호(7수) 랜덤 생성 

{

std::vector<int> vv; // vector vv 선언(중복검사, 정렬 등의 작업이 편하다) 

while(true) {

int temp = rand()%45 + 1; // 1~45 사이의 랜덤값 추출

if(std::find(vv.begin(), vv.end(), temp)==vv.end()) { // 벡터 vv 에 temp 값이 없다면 

vv.push_back(temp); // 벡터 vv 에 temp 값을 추가 

if(vv.size()==7) break; // 7수 모두를 얻었다면 while 루프를 빠져 나감 

}

}

std::sort(vv.begin(), vv.begin()+6); // 정렬(보너스번호 빼고) 

std::copy(vv.begin(), vv.end(), r); // 복사 

}


void getRandomLotto(int *r) // 로또번호(6수) 랜덤 생성 

{

std::vector<int> vv; // vector vv 선언(중복검사, 정렬 등의 작업이 편하다) 

while(true) {

int temp = rand()%45 + 1; // 1~45 사이의 랜덤값 추출

if(std::find(vv.begin(), vv.end(), temp)==vv.end()) { // 벡터 vv 에 temp 값이 없다면

vv.push_back(temp); // 벡터 vv 에 temp 값을 추가 

if(vv.size()==6) break; // 6수 모두를 얻었다면 while 루프를 빠져 나감

}

}

std::sort(vv.begin(), vv.end()); // 정렬

std::copy(vv.begin(), vv.end(), r); // 복사

}


int checkWin(int *r1, int *r2)

{

for(int i=0; i<7; i++) {

if(r1[i]<1 || 45<r1[i]) return 0; // 로또번호+보너스볼의 무결성 체크 #1

if(i==6) break;

for(int j=i+1; j<7; j++) {

if(r1[i]==r1[j]) return 0; // 로또번호+보너스볼의 무결성 체크 #2

}

}

for(int i=0; i<6; i++) {

if(r2[i]<1 || 45<r2[i]) return 0; // 로또번호의 무결성 체크 #1

if(i==5) break;

for(int j=i+1; j<6; j++) {

if(r2[i]==r2[j]) return 0; // 로또번호의 무결성 체크 #2

}

}

// 등수 확인

int smallCount=0, bonusCount=0;

for(int i=0;i<7;i++) {

for(int j=0;j<6;j++) {

if(r1[i]==r2[j]) {

if(i==6) bonusCount++;

else smallCount++;

}

}

}

int winLevel=0;

if(smallCount<3) {

winLevel=0;

} else if(smallCount==3) {

winLevel = 5;

} else if(smallCount==4) {

winLevel = 4;

} else if(smallCount==5 && bonusCount==1) {

winLevel = 2;

} else if(smallCount==5 && bonusCount!=1) {

winLevel = 3;

} else if(smallCount==6) {

winLevel = 1;

}

return winLevel;

}


int main(int argc, char *argv[])

srand((unsigned)time(NULL));


int r1[7]; // 랜덤으로 생성된 로또번호+보너스번호 를 저장할 배열 

int r2[6]; // 랜덤으로 생성된 로또번호를 저장할 배열 

for(int i=0; i<100; i++) {

getRandomLottoWin(r1);

getRandomLotto(r2);

int winLevel = checkWin(r1, r2);

printf("%02d,%02d,%02d,%02d,%02d,%02d / %02d", r1[0],r1[1],r1[2],r1[3],r1[4],r1[5],r1[6]);

printf("   :::   %02d,%02d,%02d,%02d,%02d,%02d", r2[0],r2[1],r2[2],r2[3],r2[4],r2[5]);

if(1<=winLevel && winLevel<=5)

printf("   ===   %d", winLevel);

printf("\n");

}

printf("\n");


getchar();

return 0;

}


당첨번호+보너스번호(7수)를 랜덤으로 생성한 후

구매번호(6수)를 랜덤으로 생성하여

이를 비교하여 등수를 계산하여 출력하는 소스코드입니다.


Posted by 잇힝2012
,

lotto005.cpp

#include <stdio.h>      /* printf, scanf, puts, NULL */

#include <stdlib.h>     /* srand, rand */

#include <time.h>       /* time */

#include <iostream> /* cout, endl */

#include <algorithm>    // std::sort, std::find, std::copy

#include <vector>       // std::vector


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;

}


// 로또 조합이 8145060 조합중 몇번째 조합인지 알아내기

int getOrderNumber(int r[])

{

int sum=0,nn=0,a=0,b=0,c=0,d=0,e=0,f=0;


for(a=1; a<r[0]; a++) {

nn = ((45-a)*(45-a-1)*(45-a-2)*(45-a-3)*(45-a-4)) / (5*4*3*2*1);

sum += nn;

}


for(b=a+1; b<r[1]; b++) {

nn = ((45-b)*(45-b-1)*(45-b-2)*(45-b-3)) / (4*3*2*1);

sum += nn;

}


for(c=b+1; c<r[2]; c++) {

nn = ((45-c)*(45-c-1)*(45-c-2)) / (3*2*1);

sum += nn;

}


for(d=c+1; d<r[3]; d++) {

nn = ((45-d)*(45-d-1)) / (2*1);

sum += nn;

}


for(e=d+1; e<r[4]; e++) {

nn = ((45-e)) / (1);

sum += nn;

}


for(f=e+1; f<r[5]; f++) {

nn = 1;

sum += nn;

}

sum++;

return sum;

}


// 1등 당첨번호+보너스번호를 이용하며 모든 1~5등 조합 생성하기

void make1to5ByWinLotto(int *r, std::vector<int> *v) {


v->clear(); // 결과를 저장할 벡터 변수 clear

for(int i=0; i<7; i++) {

if(r[i]<1 || 45<r[i]) return; // 1등 로또번호+보너스볼의 무결성 체크 #1

if(i==6) break;

for(int j=i+1; j<7; j++) {

if(r[i]==r[j]) return; // 1등 로또번호+보너스볼의 무결성 체크 #2

}

}


int count=0; 


int y[6] = {0};

std::vector<int> vv;



// 1등 1개

memcpy(y, r, 6*sizeof(int));

vv.clear();

vv.assign(y, y+6); // 1등 로또 번호에서 6수만 vv 벡터로 복사 

std::sort(vv.begin(), vv.end()); // 정렬

std::copy(vv.begin(), vv.end(), y); // 복사 

int ordernumber = getOrderNumber(y);

v->push_back(ordernumber);

count++;

// for(int i=0; i<vv.size(); i++)

// cout << " " << vv[i];

// cout << endl;


cout << "count = " << count << endl; // 1 = 1



// 2등 6개

for(int i=0; i<6; i++) {

memcpy(y, r, 6*sizeof(int));

y[i] = r[6]; // 보너스볼

vv.clear();

vv.assign(y, y+6); // 1등 로또 번호에서 6수만 vv 벡터로 복사 

std::sort(vv.begin(), vv.end()); // 정렬

std::copy(vv.begin(), vv.end(), y); // 복사 

int ordernumber = getOrderNumber(y);

v->push_back(ordernumber);

count++;

// for(int i=0; i<vv.size(); i++)

// cout << " " << vv[i];

// cout << endl;

}

cout << "count = " << count << endl; // 1 + 6 = 7



//  3등 228개 ( 6 * (45-7) = 6*38 = 228 )

for(int i=0; i<6; i++) {

for(int j=1; j<=45; j++) {

if(r[0]==j || r[1]==j || r[2]==j || r[3]==j || r[4]==j || r[5]==j || r[6]==j) continue;

memcpy(y, r, 6*sizeof(int));

y[i] = j; // 당첨번호,보너스번호가 아닌 수를 입력 

vv.clear();

vv.assign(y, y+6); // 1등 로또 번호에서 6수만 vv 벡터로 복사 

std::sort(vv.begin(), vv.end()); // 정렬

std::copy(vv.begin(), vv.end(), y); // 복사 

int ordernumber = getOrderNumber(y);

v->push_back(ordernumber);

count++;

}

}

cout << "count = " << count << endl; // 1 + 6 + 228 = 235



// 4등 11,115개 // 6수중2수를 빼고 + 39수중2수를 뽑는다.

for(int i=0; i<5; i++) {

for(int j=i+1; j<6; j++) { // 6수중 2수를 제거


for(int k=1; k<=44; k++) {

if(r[0]==k || r[1]==k || r[2]==k || r[3]==k || r[4]==k || r[5]==k) continue;

for(int l=k+1; l<=45; l++) {

if(r[0]==l || r[1]==l || r[2]==l || r[3]==l || r[4]==l || r[5]==l) continue;

memcpy(y, r, 6*sizeof(int));

y[i] = k;

y[j] = l;

vv.clear();

vv.assign(y, y+6); // 1등 로또 번호에서 6수만 vv 벡터로 복사 

std::sort(vv.begin(), vv.end()); // 정렬

std::copy(vv.begin(), vv.end(), y); // 복사 

int ordernumber = getOrderNumber(y);

v->push_back(ordernumber);

count++;

}

}

}

}

cout << "count = " << count << endl; // 1 + 6 + 228 + 11115 = 11350


// 5등 182,780개 // 6수중3수를 빼고 + 39수중3수를 뽑는다.

for(int i=0; i<4; i++) {

for(int j=i+1; j<5; j++) {

for(int k=j+1; k<6; k++) { // 6수중 3수를 제거


for(int l=1; l<=43; l++) {

if(r[0]==l || r[1]==l || r[2]==l || r[3]==l || r[4]==l || r[5]==l) continue;

for(int m=l+1; m<=44; m++) {

if(r[0]==m || r[1]==m || r[2]==m || r[3]==m || r[4]==m || r[5]==m) continue;

for(int n=m+1; n<=45; n++) {

if(r[0]==n || r[1]==n || r[2]==n || r[3]==n || r[4]==n || r[5]==n) continue;

memcpy(y, r, 6*sizeof(int));

y[i] = l;

y[j] = m;

y[k] = n;

vv.clear();

vv.assign(y, y+6); // 1등 로또 번호에서 6수만 vv 벡터로 복사 

std::sort(vv.begin(), vv.end()); // 정렬

std::copy(vv.begin(), vv.end(), y); // 복사 

int ordernumber = getOrderNumber(y);

v->push_back(ordernumber);

count++;

}

}

}

}

}

}

cout << "count = " << count << endl; // 1 + 6 + 228 + 11115 + 182780 = 194130



std::sort(v->begin(), v->end()); // 정렬

vector<int>::iterator last = std::unique(v->begin(), v->end()); // 중복제거

v->erase(last, v->end()); // 중복제거후 완전히 삭제되지 않은 것들 삭제

//v->erase(std::unique(v->begin(), v->end()), v->end()); // 중복제거 + 찌꺼기삭제 통합


}


int main(int argc, char *argv[])

{

int r[7] = {1,2,3,4,5,6,7}; // 1등 당첨번호 + 보너스번호 

std::vector<int> v; // 1등 당첨번호를 기준으로 1~5등에 해당하는 모든 조합을 저장할 벡터 변수 


make1to5ByWinLotto(r, &v);

// r=당첨번호+보너스볼=7수 를 이용하여,

// 모든 당첨번호(1~5등)의 orderNumber 를 v 벡터에 저장한다.

// (1등+2등+3등+4등+5등 = 1+6+228+11115+182780 = 194,130)


printf("\n");

printf("%02d,%02d,%02d,%02d,%02d,%02d / %02d\n", r[0],r[1],r[2],r[3],r[4],r[5],r[6]); // 1등 당첨번호+보너스번호 출력 

printf("\n");

int r2[6]={0,}; // 로또번호를 저장할 배열 

for(int i=0; i<v.size(); i++) {

getLottoNumberByOrderNumber(v[i], r2);

printf("%02d,%02d,%02d,%02d,%02d,%02d\n", r2[0],r2[1],r2[2],r2[3],r2[4],r2[5]);

// 1~5등에 해당하는 모든 조합 출력 (194,130개) 

}

printf("\n");


getchar();

return 0;

}


1등 당첨번호+보너스번호를 이용하며 모든 1~5등 조합을 생성하는 소스코드 입니다.


로또 1등 당첨번호+보너스번호를 기준으로 8145060 로또조합 중

1등은 1개

2등은 6개

3등은 228개

4등은 11,115개

5등은 182,780개 가 존재하게 됩니다.






Posted by 잇힝2012
,

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
,


C/C++ 에서 rand() 의 기본 사용법은 다음과 같습니다.


random0.cpp

#include <stdio.h>      /* printf, scanf, puts, NULL */

#include <stdlib.h>     /* srand, rand */

#include <time.h>       /* time */


int main(int argc, char *argv[])

{

srand((unsigned)time(NULL)); // 랜덤 씨드 초기화


printf("RAND_MAX = %d\n\n", RAND_MAX); // 32767 = 0x7FFFF = 0111 1111 1111 1111


for(int i=0; i<10; i++)

printf("%d\n", rand()); // 0~32767 랜덤 발생 (0~RAND_MAX) 

printf("\n");

for(int i=0; i<10; i++)

printf("%d\n", rand()%10); // 0~9 랜덤 발생

printf("\n");


for(int i=0; i<10; i++)

printf("%d\n", rand()%10 + 5); // 5~14 랜덤 발생

printf("\n");

getchar();

return 0;

}


하지만 C 표준 rand() 함수는 생성 범위가 제한적이기 때문에 큰수 랜덤 생성에 적합하지 않습니다.

이를 해결하기 위해 많은 방법들이 있지만,

여기서는 WELL Random number generator 를 C/C++ 에서 사용하는 방법에 대해 알아보겠습니다.


(WELL Random 은 메르센 트위스터를 만든 사람이 개선한 것이랍니다)

메르센 트위스터

위키백과, 우리 모두의 백과사전.

메르센 트위스터(Mersenne Twister)는 1997년에 마츠모토 마코토(松本 眞)와 니시무라 다쿠지(西村 拓士)가 개발한 유사난수 생성기이다.[1] 메르센 트위스터는 동일한 저자들이 개발한 TT800 생성기의 개선판으로, 기존 생성기들의 문제점들을 피하면서 매우 질이 좋은 난수를 빠르게 생성할 수 있도록 설계되었다.

메르센 트위스터의 이름은 난수의 반복 주기가 메르센 소수인 데에서 유래했다. 메르센 트위스터는 그 속도와 난수의 품질 때문에 점점 많은 곳에서 채택되고 있으며, 흔히 주기가 2^{19937}-1인 MT19937을 사용한다. MT19937과 같으나 생성해 내는 난수가 32비트가 아닌 64비트인 MT19937-64도 쓰이며, 2006년에 동일한 저자들이 발표한 SIMD 기반 메르센 트위스터는 MT19937에 비해 대략 두 배 정도 빠른 것으로 알려져 있다.

난수의 품질에도 불구하고, 메르센 트위스터는 암호학적으로 안전한 유사난수 생성기가 아니다. 즉 난수의 특성(주기, 난수 범위)을 알고 있을 때 유한한 수의 난수(이 경우 624개)만으로 현재 생성기의 상태를 알아 낼 수 있으며, 그 뒤에 나올 난수를 예측해 낼 수 있다. 암호학적으로 안전한 유사난수 생성기를 얻기 위해서는 해시 함수를 사용해야 하지만 난수의 생성 속도가 낮아진다. 또는 블룸 블룸 슙(BBS)과 같이 암호학적으로 안전하게 설계된 생성기를 쓸 수도 있다.


출처: http://ko.wikipedia.org/wiki/메르센_트위스터


WELL Random number generator 소스는 http://www.iro.umontreal.ca/~panneton/WELLRNG.html 에서 구할 수 있습니다.

512, 1024, 19937, 44497 의 4종류가 보이는데, 적당히 1024 를 사용하기로 합니다.


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;


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 초기화

// 기본 사용법 

// double x = (double)WELLRNG1024a(); // 0.0 <= x < 1.0  실수 랜덤 생성


for(int i=0; i<10; i++)

printf("%f\n", (double)WELLRNG1024a()); // 0.0 <= x < 1.0  실수 랜덤 생성

printf("\n");

for(int i=0; i<10; i++)

printf("%d\n", (int)((double)WELLRNG1024a() * 1000001) ); // 0~1,000,000 정수 랜덤 생성

printf("\n");


for(int i=0; i<10; i++)

printf("%d\n", (int)((double)WELLRNG1024a() * 1000001) + 5 ); // 5~1,000,005 정수 랜덤 생성

printf("\n");


getchar();

return 0;

}


기본적인 사용법은

InitWELLRNG1024a(init); 으로 최초 1회 초기화 해준 후,

(double)WELLRNG1024a(); 로 랜덤값(실수, double, 0.0 <= x < 1.0 )을 가져오면 됩니다.


리턴값이 실수(double)이기 때문에, 특정 범위의 정수 값으로 변환하기 위해선 아래와 같은 방법을 사용합니다.

int rnd = (int)((double)WELLRNG1024a() * (max-min+1)) + min; // min~max 정수 랜덤 생성


(틀린 내용이 있다면 알려주세요)


Posted by 잇힝2012
,

lotto003.cpp

#include <stdio.h>      /* printf, scanf, puts, NULL */

#include <stdlib.h>     /* srand, rand */

#include <time.h>       /* time */

#include <algorithm>    // std::sort, std::find, std::copy

#include <vector>       // std::vector


void getRandomLottoWin(int *r) // 당첨번호+보너스번호(7수) 랜덤 생성 

{

std::vector<int> vv; // vector vv 선언(중복검사, 정렬 등의 작업이 편하다) 

while(true) {

int temp = rand()%45 + 1; // 1~45 사이의 랜덤값 추출

if(std::find(vv.begin(), vv.end(), temp)==vv.end()) { // 벡터 vv 에 temp 값이 없다면 

vv.push_back(temp); // 벡터 vv 에 temp 값을 추가 

if(vv.size()==7) break; // 7수 모두를 얻었다면 while 루프를 빠져 나감 

}

}

std::sort(vv.begin(), vv.begin()+6); // 정렬(보너스번호 빼고) 

std::copy(vv.begin(), vv.end(), r); // 복사 

}


void getRandomLotto(int *r) // 로또번호(6수) 랜덤 생성 

{

std::vector<int> vv; // vector vv 선언(중복검사, 정렬 등의 작업이 편하다) 

while(true) {

int temp = rand()%45 + 1; // 1~45 사이의 랜덤값 추출

if(std::find(vv.begin(), vv.end(), temp)==vv.end()) { // 벡터 vv 에 temp 값이 없다면

vv.push_back(temp); // 벡터 vv 에 temp 값을 추가 

if(vv.size()==6) break; // 6수 모두를 얻었다면 while 루프를 빠져 나감

}

}

std::sort(vv.begin(), vv.end()); // 정렬

std::copy(vv.begin(), vv.end(), r); // 복사

}


int main(int argc, char *argv[])

srand((unsigned)time(NULL));

int r1[7]; // 랜덤으로 생성된 로또번호+보너스번호 를 저장할 배열 

for(int i=0; i<10; i++) {

getRandomLottoWin(r1);

printf("%02d,%02d,%02d,%02d,%02d,%02d / %02d\n", r1[0],r1[1],r1[2],r1[3],r1[4],r1[5],r1[6]);

}

printf("\n");


int r2[6]; // 랜덤으로 생성된 로또번호를 저장할 배열 

for(int i=0; i<10; i++) {

getRandomLotto(r2);

printf("%02d,%02d,%02d,%02d,%02d,%02d\n", r2[0],r2[1],r2[2],r2[3],r2[4],r2[5]);

}

getchar();

return 0;

}


랜덤으로 로또 번호를 생성하는 함수입니다.

getRandomLottoWin() 은 보너스볼까지 총 7수가 랜덤 생성되며

getRandomLotto() 은 총 6수가 랜덤 생성됩니다.


C 표준 랜덤함수 rand() 의 분포가 좋지 않다고는 하지만,

1~45 사이의 랜덤을 구하는 용도로는 큰 문제가 되지 않을것입니다.

(그래도 마음에 들지 않다면, 다른 랜덤 함수를 사용하면 되겠죠?)


Posted by 잇힝2012
,

lotto002.cpp

#include <stdio.h>


// 로또조합 순서값(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[])

{

int r1[6]={0,}; // 로또번호를 저장할 배열 

getLottoNumberByOrderNumber(1, r1); // 로또 순서 1번에 해당하는 로또번호를 r1 배열에 저장

int r2[6]={0,}; // 로또번호를 저장할 배열 

getLottoNumberByOrderNumber(8145060, r2); // 로또 순서 8145060번에 해당하는 로또번호를 r2 배열에 저장


printf("1 ==> %d,%d,%d,%d,%d,%d\n", r1[0],r1[1],r1[2],r1[3],r1[4],r1[5]); // 결과: 1,2,3,4,5,6

printf("8145060 ==> %d,%d,%d,%d,%d,%d\n", r2[0],r2[1],r2[2],r2[3],r2[4],r2[5]); // 결과: 40,41,42,43,44,45

getchar();

 

return 0;

}


조합 순서 번호를 이용하여 로또조합을 구하는 함수입니다.


1 을 입력하면 1,2,3,4,5,6 조합을 얻을 수 있고

8145060 을 입력하면 40,41,42,43,44,45 조합을 얻을 수 있습니다.


Posted by 잇힝2012
,

lotto001.cpp

#include <stdio.h>


// 로또 조합이 8145060 조합중 몇번째 조합인지 알아내기

int getOrderNumber(int r[])

{

int sum=0,nn=0,a=0,b=0,c=0,d=0,e=0,f=0;


for(a=1; a<r[0]; a++) {

nn = ((45-a)*(45-a-1)*(45-a-2)*(45-a-3)*(45-a-4)) / (5*4*3*2*1);

sum += nn;

}


for(b=a+1; b<r[1]; b++) {

nn = ((45-b)*(45-b-1)*(45-b-2)*(45-b-3)) / (4*3*2*1);

sum += nn;

}


for(c=b+1; c<r[2]; c++) {

nn = ((45-c)*(45-c-1)*(45-c-2)) / (3*2*1);

sum += nn;

}


for(d=c+1; d<r[3]; d++) {

nn = ((45-d)*(45-d-1)) / (2*1);

sum += nn;

}


for(e=d+1; e<r[4]; e++) {

nn = ((45-e)) / (1);

sum += nn;

}


for(f=e+1; f<r[5]; f++) {

nn = 1;

sum += nn;

}

sum++;

return sum;

}

 

int main(int argc, char *argv[])

{

int r1[6]={1,2,3,4,5,6};

int r2[6]={40,41,42,43,44,45};

printf("1,2,3,4,5,6 ==> %d\n", getOrderNumber(r1)); // 결과: 1

printf("40,41,42,43,44,45 ==> %d\n", getOrderNumber(r2)); // 결과: 8145060

getchar();

 

return 0;

}


로또번호로 몇번째 조합인지를 구하는 함수 입니다.


1,2,3,4,5,6 은 첫번째 조합

1,2,3,4,5,7 은 두번째 조합

....

40,41,42,43,44,45 은 마지막 8145060 번째 조합 입니다.



Posted by 잇힝2012
,