Source code for LotteryLoser - experiment in analysing norwegian lottery-number entries, and churning out less similar entries. Severly outdated.
LOTTERY.HPP
/* LOTTERY.HPP - The basic structures and methods that are NOT specific to either DOS or WINDOWS. (No specific external output functions..???) Meaning that some functions are DECLARED(prototyped) here, but not DEFINED(no code) Separated from LOTTERY.CPP 08.02.97. LEntry class: UNdefined: friend ostream& operator << (ostream&, LEntry&); friend istream& operator >> (istream&, LEntry&); LDrawResult class: UNdefined: void EnterResult(); friend ostream& operator << (ostream&, LDrawResult&); friend istream& operator >> (istream&, LDrawResult&); DTDBase class : building block for: DTDAlpha class: keeps prize statistics DTDOmega class: keeps complete result statistics (num. Correct and Additional) AN EVEN-WORSE MESS!!!! */ #include <time.h> //Due to RANDOMIZE() #include <stdlib.h> #include <iomanip.h> #include <iostream.h> #include <fstream.h> #include <string.h> //Mathematical probability precalc'ed values... #define MAX_ENTRY_COMBS 5379616 // 34!/(34-7)!/7! = 34C7 #define MAX_ADDITIONAL_COMBS 351 #define MAX_DRAW_COMBS (MAX_ENTRY_COMBS*MAX_ADDITIONAL_COMBS) //#define NUM_COMBS_1ST_PRIZE 1 //Are these correct???? Don't kno' fer sure... //#define NUM_COMBS_2ND_PRIZE 14 // 7C6*2C1*25C0 //#define NUM_COMBS_3RD_PRIZE 175 // 7C6*2C0*25C1 //#define NUM_COMBS_4TH_PRIZE 7371 // 7C5*(2C2*25C0+2C1*25C1+2C0*25C2) //#define NUM_COMBS_5TH_PRIZE 21875 // 7C4*(2C2*25C1+2C1*25C2) //#define NUM_COMBS_NO_PRIZE 5350180 // #define MAX_NUMBER 34 #define MAX_SELECTED 7 #define MAX_ADDITIONAL 2 #define Entry_Sel_t unsigned char long NumCombs_Prize[6] = { 5350180L, 1, 14, 175, 7371, 21875 }; // LEntry class class LEntry { protected: Entry_Sel_t Num[MAX_SELECTED]; public: LEntry(); int Sort(); //Returns a NEGATIVE result on garbage int Contains(Entry_Sel_t); int CompareTo(LEntry); void Randomize(); void ResetAsCounter(); int operator ++ (void); friend ostream& operator << (ostream&, LEntry&); friend istream& operator >> (istream&, LEntry&); }; LEntry::LEntry() { for(int i=0;i<MAX_SELECTED;i++) Num[i]=0; } int LEntry::Contains(Entry_Sel_t s) { for(int i=0;i<MAX_SELECTED;i++) if(Num[i]==s) return 1; return 0; } int LEntry::Sort() { int i,j; Entry_Sel_t Es; do{ j=0; for(i=0;i<MAX_SELECTED-1;i++) if(Num[i]>Num[i+1]) { Es=Num[i]; Num[i]=Num[i+1]; Num[i+1]=Es; j=1; } }while(j!=0); for(i=0;i<MAX_SELECTED-1;i++) if(Num[i]-Num[i+1]==0) return -1; for(i=0;i<MAX_SELECTED;i++) if((Num[i]<1) || (Num[i]>MAX_NUMBER)) return -2; return 0; } int LEntry::CompareTo(LEntry Other) { int i,j=0; for(i=0;i<MAX_SELECTED;i++) if(Other.Contains(Num[i])) j++; return j; } void LEntry::Randomize() //Randomize the entries values... { int i,j; do{ for(i=0;i<MAX_SELECTED;i++) Num[i]=0; for(i=0;i<MAX_SELECTED;i++) { do{ j=random(34)+1; //if(!(Is >> (unsigned int) j )) i=MAX_SELECTED+1; }while( (j<1 || j>MAX_NUMBER || Contains(j))); Num[i]=j; } //if(i>MAX_SELECTED) for(j=0;j<MAX_SELECTED;j++) LE.Num[i]=0; }while(Sort()<0); } int LEntry::operator ++ () //Counter function... for statistics { int i,finish=0,d=MAX_SELECTED-1; do{ i=Num[d]; do{ i++; }while((Contains(i))); if(i<=MAX_NUMBER-6+d){ Num[d]=i; finish=1; } if(!finish){ if(!d) return 0; Num[d]=0; d--; } //Num[d]=0; Num[d-1]++; Num[d]=Num[d-1]+1 }while(!finish); if(d<MAX_SELECTED-1) for(i=d+1;i<=MAX_SELECTED-1;i++)Num[i]=Num[i-1]+1; return 1; } void LEntry::ResetAsCounter() //Reset for statistical purposes... { for(int i=0;i<MAX_SELECTED;i++) Num[i]=i+1; } //End of LEntry class // class LDrawResult class LDrawResult { public: LEntry WEntry;//Winning entry Entry_Sel_t ANum[MAX_ADDITIONAL]; //The additional numbers public: LDrawResult(); //Constructor void Randomize(); void EnterResult(); int Compare(LEntry); int CompareAdditional(LEntry); int PrizeTest(LEntry); void ResetAsCounter(); int operator ++ (void); //Inc.(for when counting) friend ostream& operator << (ostream&, LDrawResult&); friend istream& operator >> (istream&, LDrawResult&); }; LDrawResult::LDrawResult() { for(int i=0;i<MAX_ADDITIONAL;i++) ANum[i]=0; } void LDrawResult::Randomize() //Randomize the entries values... { int i,j; WEntry.Randomize(); ANum[0]=0; for(i=0;i<MAX_ADDITIONAL;i++) { do{ j=random(34)+1; //if(!(Is >> (unsigned int) j )) i=MAX_SELECTED+1; }while( (j<1 || j>MAX_NUMBER || WEntry.Contains(j))||ANum[0]==j); ANum[i]=j; } //if(i>MAX_SELECTED) for(j=0;j<MAX_SELECTED;j++) LE.Num[i]=0; if(ANum[0]>ANum[1]) { j=ANum[0]; ANum[0]=ANum[1]; ANum[1]=j; } } int LDrawResult::Compare(LEntry LE) { return WEntry.CompareTo(LE); } int LDrawResult::CompareAdditional(LEntry LE) { int i,j=0; for(i=0;i<MAX_ADDITIONAL;i++) if(LE.Contains(ANum[i])) j++; return j; } int LDrawResult::PrizeTest(LEntry LE) //Return prize number { int Correct, Additional; Correct=Compare(LE); if(Correct>3){ if(Correct==5) return 4; //Attempt to speed things up... if(Correct==7) return 1; Additional=CompareAdditional(LE); //if(Correct==6 && Additional==1) return 2; if(Correct==6) return 3; if(Correct==4 && Additional>0) return 5; if(Correct==6) if(Additional){ return 2; } else{ return 3;}; } return 0; } int LDrawResult::operator ++ () //Counter function... for statistics { do{ANum[1]++;}while((ANum[1]==ANum[0])||(WEntry.Contains(ANum[1]))); if(ANum[1]>MAX_NUMBER) { do{ANum[0]++;}while((WEntry.Contains(ANum[0]))); ANum[1]=ANum[0]; do{ANum[1]++;}while((WEntry.Contains(ANum[1]))); if(ANum[1]>MAX_NUMBER) { if(++WEntry){ ANum[0]=0; do{ANum[0]++;}while((WEntry.Contains(ANum[0]))); ANum[1]=ANum[0]; do{ANum[1]++;}while((WEntry.Contains(ANum[1]))); return 1; } else return 0; } } return 1; }; int PrizeFor(int C, int A) { if(C>3){ if(C==5) return 4; //Attempt to speed things up... if(C==7) return 1; if(C==4 && A>0) return 5; if(C==6) if(A){ return 2; } else{ return 3;}; } return 0; } /* The counter system is SLOW... manages about 850 000 ticks per second, but we have 1 888 245 216 of the bligthers... Thats a 2222 seconds = 37 minutes just for counting through every possible LDrawResult Imagine if we were to check 2 lists of 50 LEntries each against them... */ void LDrawResult::ResetAsCounter() { WEntry.ResetAsCounter(); ANum[0]=0; do{ANum[0]++;}while((WEntry.Contains(ANum[0]))); ANum[1]=ANum[0]; do{ANum[1]++;}while((WEntry.Contains(ANum[1]))); } //End of LDrawResult class // FileName class #define MAX_FILENAME_LENGTH 64 class FileNameClass { public: char FileName[MAX_FILENAME_LENGTH]; FileNameClass(); FileNameClass(char*); void SetFileName(char*); }; FileNameClass::FileNameClass() { FileName[0]=0; } void FileNameClass::SetFileName(char* N) { strncpy(FileName, N, MAX_FILENAME_LENGTH); FileName[MAX_FILENAME_LENGTH-1]=0; } FileNameClass::FileNameClass(char* N) { SetFileName(N); } //FileName class end... // LEList class #define MAX_ENTRIES_PR_LIST 512 class LEList : public FileNameClass { public: LEntry *LEs; unsigned long numLEs, maxLEs; //char FileName[MAX_FILENAME_LENGTH]; LEList(); //void SetFileName(char*); int LoadFile(); int SaveFile(); }; LEList::LEList() : FileNameClass() { numLEs=0; maxLEs=MAX_ENTRIES_PR_LIST; } //End LEList //DTD - classes... enum DTDTypeIDs { ID_DTDBase=0, ID_DTDAlpha=1, ID_DTDOmega=2, NumOf_DTDTypeIDs}; char DTDTypeDescription[NumOf_DTDTypeIDs][16] = { "(Base:N.A.)", "Alpha: Prizes", "Omega: C./A." }; enum TestingModes { RANDOM=0, FULL=1, NumOf_TestingModes}; char TestingModesDescription[NumOf_TestingModes][20] = { "Simulate draws", "Count thru draws" }; class DTDBase : public FileNameClass//Base class for DTD info { protected: TestingModes TDMode; DTDTypeIDs DTD_ID; long numLDRs; LDrawResult TestDraw; public: LEList *TDLEL[2]; public: DTDBase(); //Ctor DTDBase(LEList&, LEList&, TestingModes); void SaveDTDFile(); void LoadDTDFile(); /**/ void Load(char*); virtual void Report(ostream&)=0; virtual int ProcessDraw()=0; virtual DTDTypeIDs IsA(); virtual SaveIndividualDTD(ofstream&) =0; virtual LoadIndividualDTD(ifstream&) =0; int DTDBase::operator ++ (); friend ostream& operator << (ostream&, DTDBase&); }; DTDBase::DTDBase() : FileNameClass() //Ctor { numLDRs=0; TDMode=RANDOM; DTD_ID=ID_DTDBase; randomize(); } DTDBase::DTDBase(LEList& L1, LEList& L2, TestingModes M) : FileNameClass() //Ctor { numLDRs=0; DTD_ID=ID_DTDBase; TDMode=M; if(TDMode==RANDOM) randomize(); if(TDMode==FULL) TestDraw.ResetAsCounter(); TDLEL[0]=&L1; TDLEL[1]=&L2; } DTDTypeIDs DTDBase::IsA(){ return DTD_ID; } int DTDBase::operator ++ () { if(ProcessDraw()) { numLDRs++; return 1; }else return 0; } /*int DTDBase::ProcessDraw(){ return 1; } */ void DTDBase::SaveDTDFile() { ofstream OutFile; int i,j; OutFile.open(FileName); //OutFile << IsA() << "\n"; OutFile <<" "<<int(DTD_ID)<<"\n"; OutFile <<" "<<int(TDMode)<<" "<< numLDRs <<" "<<TestDraw<<"\n"; OutFile<<"\n\n"; SaveIndividualDTD(OutFile); //LELists... OutFile<<" "<< TDLEL[0]->numLEs <<" "<<TDLEL[1]->numLEs<<"\n"; OutFile<<TDLEL[0]->FileName<<"\n"<<TDLEL[1]->FileName<<"\n"; for(i=0;i<2;i++) { for(j=0;j<TDLEL[i]->numLEs;j++) { OutFile<<" "<< TDLEL[i]->LEs[j]<<" "; } OutFile<<"\n"; } OutFile.close(); cout<<"\nSaved DTD "<<FileName; } //Needs to be linked to LELists for storage... void DTDBase::LoadDTDFile() { ifstream InFile; int i,j; InFile.open(FileName); //InFile >> IsA() >> "\n"; InFile >>int(DTD_ID); //if(DTDTypeIDs(i)!=DTD_ID) // If the file isn't of the correct DTD format..abort //{ cout<<"\n Invalid DTD_ID!\n"; return; } //DTD_ID = DTDTypeIDs(i); InFile >> int(TDMode) >> numLDRs >> TestDraw; LoadIndividualDTD(InFile); //LELists... InFile>> TDLEL[0]->numLEs >> TDLEL[1]->numLEs; InFile>> TDLEL[0]->FileName >> TDLEL[1]->FileName; for(i=0;i<2;i++) { for(j=0;j<TDLEL[i]->numLEs;j++) { InFile >> TDLEL[i]->LEs[j]; } } InFile.close(); if(TDMode==RANDOM) randomize(); } void DTDBase::Load(char* N) { SetFileName(N); LoadDTDFile(); } ostream& operator << (ostream& Out, DTDBase& D) { Out<<"\n\n"<<setfill(' '); if(D.TDMode==RANDOM) Out<<"RANDOM DTD: "; if(D.TDMode==FULL) Out<<"FULL DTD: "; Out<<D.numLDRs<<" - Draw:"<<D.TestDraw<<"\n"; Out<<setw(20)<<D.TDLEL[0]->FileName<<' '; Out<<setw(20)<<D.TDLEL[1]->FileName; D.Report(Out); return Out; } ////////// class DTDAlpha : public DTDBase { protected: unsigned long Prizes[2][6], MaxPrizes[2][6]; public: DTDAlpha(); DTDAlpha( LEList&, LEList&, TestingModes); virtual SaveIndividualDTD(ofstream&); virtual LoadIndividualDTD(ifstream&); virtual int ProcessDraw(); virtual void Report(ostream&); }; DTDAlpha::DTDAlpha() : DTDBase() //Ctor { for(int i=0;i<2;i++) for(int j=0;j<6;j++) { Prizes[i][j]=0; MaxPrizes[i][j]=0; } DTD_ID=ID_DTDAlpha; } DTDAlpha::DTDAlpha( LEList& L1, LEList& L2, TestingModes M) : DTDBase(L1,L2,M) { //DTDAlpha::DTDAlpha(); for(int i=0;i<2;i++) for(int j=0;j<6;j++) { Prizes[i][j]=0; MaxPrizes[i][j]=0; } DTD_ID=ID_DTDAlpha; } DTDAlpha::SaveIndividualDTD(ofstream& Out) { for(int i=0;i<6;i++) { for(int j=0;j<2;j++) { Out <<" "<<Prizes[j][i]<<" "<<MaxPrizes[j][i]<<" "; } Out <<"\n"; } Out<<"\n\n"; return 1; } DTDAlpha::LoadIndividualDTD(ifstream& In) { for(int i=0;i<6;i++) { for(int j=0;j<2;j++) { In >>Prizes[j][i]>>MaxPrizes[j][i]; } } return 1; } int DTDAlpha::ProcessDraw() { int maxPrize1=999, prize1; for(int j=0;j<2;j++) { maxPrize1=999; for(int i=0;i<TDLEL[j]->numLEs;i++) { //cout<<"\n!!!!!"; //prize1=T.TestDraw.PrizeTest(LEL[j].LEs[i]); prize1=TestDraw.PrizeTest(TDLEL[j]->LEs[i]); Prizes[j][prize1]++; if(prize1) if(prize1<maxPrize1) maxPrize1=prize1; } if(maxPrize1>5)maxPrize1=0; MaxPrizes[j][maxPrize1]++; } if(TDMode==FULL) { if(!(++TestDraw)) return 0; } else if(TDMode==RANDOM) { TestDraw.Randomize(); } return 1; } void DTDAlpha::Report(ostream& Out) { for(int i=0;i<6;i++) { Out<<"\n"<<i<<".:"; for(int j=0;j<2;j++) { Out<<setw(10)<<Prizes[j][i]<<" "<<setw(10)<<MaxPrizes[j][i]; Out <<"|"; } } } ////////////// class ResultFrequency { protected: unsigned long Results[MAX_SELECTED+1][MAX_ADDITIONAL+1]; public: ResultFrequency(); void Accept(int, int); unsigned long GetFreq(int, int); void SetFreq(int, int, unsigned long); }; ResultFrequency::ResultFrequency() { for(int i=0;i<MAX_SELECTED+1;i++) for(int j=0;j<MAX_ADDITIONAL+1;j++) Results[i][j]=0; } void ResultFrequency::Accept(int C, int A) { if(C>=0 && A>=0 && C<=MAX_SELECTED && A<=MAX_ADDITIONAL) Results[C][A]++; } unsigned long ResultFrequency::GetFreq(int C, int A) { if(C>=0 && A>=0 && C<=MAX_SELECTED && A<=MAX_ADDITIONAL) return Results[C][A]; else return 0; } void ResultFrequency::SetFreq(int C, int A, unsigned long L) { if(C>=0 && A>=0 && C<=MAX_SELECTED && A<=MAX_ADDITIONAL) Results[C][A]=L; } ////////// //New DTDOmega class for detailed info... class DTDOmega : public DTDBase { protected: ResultFrequency Result[2], MaxResult[2]; public: DTDOmega(); DTDOmega( LEList&, LEList&, TestingModes); virtual SaveIndividualDTD(ofstream&); virtual LoadIndividualDTD(ifstream&); virtual int ProcessDraw(); virtual void Report(ostream&); }; DTDOmega::DTDOmega() : DTDBase() //Ctor { //for(int i=0;i<2;i++) DTD_ID=ID_DTDOmega; } DTDOmega::DTDOmega( LEList& L1, LEList& L2, TestingModes M) : DTDBase(L1,L2,M) { // DTDOmega::DTDOmega(); DTD_ID=ID_DTDOmega; } DTDOmega::SaveIndividualDTD(ofstream& Out) { for(int i=0;i<MAX_SELECTED+1;i++) { for(int j=0;j<MAX_ADDITIONAL+1;j++) { for(int k=0;k<2;k++) { Out <<" "<<Result[k].GetFreq(i,j) <<" "<<MaxResult[k].GetFreq(i,j)<<" "; } Out <<"\n"; } } Out<<"\n\n"; return 1; } DTDOmega::LoadIndividualDTD(ifstream& In) { for(int i=0;i<MAX_SELECTED+1;i++) { for(int j=0;j<MAX_ADDITIONAL+1;j++) { for(int k=0;k<2;k++) { unsigned long l; In >> l; Result[k].SetFreq(i,j,l); In >> l; MaxResult[k].SetFreq(i,j,l); } } } return 1; } int DTDOmega::ProcessDraw() { int C, A, mC=0, mA=0; for(int j=0;j<2;j++) { mC=0; mA=0; for(int i=0;i<TDLEL[j]->numLEs;i++) { //cout<<"\n!!!!!"; //prize1=T.TestDraw.PrizeTest(LEL[j].LEs[i]); //prize1=TestDraw.PrizeTest(TDLEL[j]->LEs[i]); C=TestDraw.Compare(TDLEL[j]->LEs[i]); A=TestDraw.CompareAdditional(TDLEL[j]->LEs[i]); Result[j].Accept(C,A); if((C>mC) || (C==mC && A>mA)) { mC=C; mA=A; } } //if(maxPrize1>5)maxPrize1=0; MaxResult[j].Accept(mC,mA); //[j][maxPrize1]++; } if(TDMode==FULL) { if(!(++TestDraw)) return 0; } else if(TDMode==RANDOM) { TestDraw.Randomize(); } return 1; } void DTDOmega::Report(ostream& Out) { for(int i=0;i<MAX_SELECTED+1;i++) for(int j=0;j<MAX_ADDITIONAL+1;j++) { if(!(i==7 && j>0) && !(i==6 && j>1)) { Out<<"\n"<<i<<"-"<<j<<":"; for(int k=0;k<2;k++) { Out<<setw(10)<<Result[k].GetFreq(i,j) <<" "<<setw(10)<<MaxResult[k].GetFreq(i,j); Out <<"|"; } } } } ////////////// //DTDClassAlpha: for use with LargeScaleDrawTesting(TestingModes) // OLD /* class DTDClassAlpha : DTDBase //Keeps testing data... { protected: unsigned long Prizes[2][6],MaxPrizes[2][6]; public: DTDClassAlpha(); //Ctor virtual char* IsA(); ostream& PrintReport1To(ostream&); ostream& PrintReport2To(ostream&); friend void LargeScaleDrawTesting(TestingModes, int, int); SaveToFile(char *); LoadFromFile(char *); virtual void Report(ostream&); virtual SaveIndividualDTD(ofstream&); virtual LoadIndividualDTD(ifstream&); }; DTDClassAlpha::DTDClassAlpha() : DTDBase() { for(int i=0;i<6;i++){ Prizes[0][i]=0;Prizes[1][i]=0; MaxPrizes[0][i]=0;MaxPrizes[1][i]=0; } } char* DTDClassAlpha::IsA(){ return "DTDClassAlpha"; } DTDClassAlpha::SaveToFile(char *FileName) { ofstream OutFile; int i,j; OutFile.open(FileName); OutFile <<" "<<TDMode<<" "<< numLDRs <<" "<<TestDraw<<"\n"; //Prizes for(i=0;i<6;i++) { for(j=0;j<2;j++) { OutFile <<" "<<Prizes[j][i]<<" "<<MaxPrizes[j][i]<<" "; } OutFile <<"\n"; } OutFile<<"\n\n"; //LELists... OutFile<<" "<< TDLEL[0]->numLEs <<" "<<TDLEL[1]->numLEs<<"\n"; OutFile<<TDLEL[0]->FileName<<"\n"<<TDLEL[1]->FileName<<"\n"; for(i=0;i<2;i++) { for(j=0;j<TDLEL[i]->numLEs;j++) { OutFile<<" "<< TDLEL[i]->LEs[j]<<" "; } OutFile<<"\n"; } OutFile.close(); } DTDClassAlpha::LoadFromFile(char *FileName) { ifstream InFile; int i,j; InFile.open(FileName); InFile >>int(TDMode)>>numLDRs>>TestDraw; //Prizes for(i=0;i<6;i++) { for(j=0;j<2;j++) { InFile >>Prizes[j][i]>>MaxPrizes[j][i]; } //InFile >>"\n"; } //InFile>>"\n\n"; //LELists... InFile>> TDLEL[0]->numLEs >>TDLEL[1]->numLEs; InFile>>TDLEL[0]->FileName; InFile>>TDLEL[1]->FileName; for(i=0;i<2;i++) { for(j=0;j<TDLEL[i]->numLEs;j++) { InFile >> TDLEL[i]->LEs[j]; } //InFile>>"\n"; } InFile.close(); } void DTDClassAlpha::Report(ostream& Out) { } DTDClassAlpha::SaveIndividualDTD(ofstream& O) { } DTDClassAlpha::LoadIndividualDTD(ifstream& I) { } */
End of Lottery.hpp
LOTTERY.CPP
// LOTTERY LOSER - Prog. for analyzing statistics of lottery entries... /* MenThals first real work with O.O.P.!!!!! Start: 5.Oct.1996 Latest update:*/ #define VERSION_DATE "26.02.1997" /* For other information on the process of my analesys of the norwegian LOTTERY system, please see file: C:\DOKUMENT\KENT\SKOLE\MATTE\LOTTO.TXT Also note the file LOTTERY.HPP containing the IMPORTANT stuff... Norwegian lottery rules... bet on 7 numbers, 1-34, excluding. 7 numbers drawn + 2 additional numbers 1. 7 number 2. 6 + 1 additional 3. 6 4. 5 5. 4 + 1 additional 07.02.1997 - PrizeTest speed up... Fixed bug that took the LOWEST prize as the MAX prize in the Sim and AllDraws-tests... 08.02 - Split out the most basic classes and functions... Decided to make a LEList class, that encapsulates the list data... DTDClass split out - a mess.... 24.02 - Two DTD classes DTDAlpha and DTDOmega - seems to work... Dynamic loading routine that figures out which sort of object to create... really delicate, may boom. As may the Create New DTD command ... */ #include <stdio.h> #include <lottery.hpp> //******* IMPORTANT ********* #include <dos.h> #include <conio.h> #include <math.h> #include <ctype.h> #define DEBUG #define COMPILE_FOR DOS //I.e. - windows without GUI stuff... #define MAX_ENTRIES 2048 #define MAX_RESULTS 100 #define MAX_NUM_LELISTS 4 //LEntry class: The more platform-specific methods ostream& operator << (ostream& Os, LEntry& LE) // WRITING an entry { for(int i=0;i<MAX_SELECTED;i++) Os << setw(3)<<setfill(' ') << (unsigned int) LE.Num[i]; return Os; } istream& operator >> (istream& Is, LEntry& LE) // READING an entry { int i,j; for(i=0;i<MAX_SELECTED;i++) LE.Num[i]=0; for(i=0;i<MAX_SELECTED;i++) { do{ if(!(Is >> (unsigned int) j )) i=MAX_SELECTED+1; }while( (j<1 || j>MAX_NUMBER || LE.Contains(j)) && i<=MAX_SELECTED); LE.Num[i]=j; } if(i>MAX_SELECTED) for(j=0;j<MAX_SELECTED;j++) LE.Num[i]=0; LE.Sort(); return Is; } // End of LEntry class //LDrawResult class: The more platform-specific methods ostream& operator << (ostream& Os, LDrawResult& LD) { Os << LD.WEntry << " "; for(int i=0;i<MAX_ADDITIONAL;i++) Os << setw(3)<<setfill(' ') << (unsigned int) LD.ANum[i]; return Os; } void LDrawResult::EnterResult() { cout << "\nEnter the lucky numbers:\n"; cin >> WEntry; cout << "\nEnter additional numbers:\n"; int i,j; for(i=0;i<MAX_ADDITIONAL;i++) { do{cin >> (unsigned int) j; cin.ignore(); }while((j<1 || j>MAX_NUMBER)|| WEntry.Contains(j)); ANum[i]=j; } } istream& operator >> (istream& Is, LDrawResult& LD) { int i,j; if(Is >> LD.WEntry) for(i=0;i<MAX_ADDITIONAL;i++) { do{ Is >> (unsigned int) j; }while((j<1 || j>MAX_NUMBER) || LD.WEntry.Contains(j) || (j==LD.ANum[i-1] && i>0)); LD.ANum[i]=j; } return Is; } // End of LDrawResult class LEntry LEntries[MAX_ENTRIES]; LDrawResult LResults[MAX_RESULTS]; unsigned long NumLEntries, NumLResults; unsigned char LEI[MAX_ENTRIES_PR_LIST]; unsigned long LNI[MAX_NUMBER+1]; int SecondaryListPresent = 0; enum LEListListIndex { PrimLEL=0, SecLEL=1 }; LEList LEL[MAX_NUM_LELISTS]; /*char LEFileName[50] = "Lottery.lot"; char SecondaryLEFileName[50]; */ #ifdef DEBUG clock_t clockStart, clockEnd; float testSeconds; float clockSeconds(clock_t t){return(float(t)/CLK_TCK);} #endif int LEList::LoadFile() //Loads ASCII file containing 7 number entries ->LEList { ifstream InFile; //LEntry LE; numLEs=0; InFile.open(FileName); if(InFile.rdstate()) { cout <<"\nUnknown file stream state occured...\nAborting LEFile loading for safety...\n"; return 0;} while (InFile >> LEs[numLEs], !InFile.eof()) numLEs++; InFile.close(); cout <<"\n Lottery entry file: " << FileName << " loaded.\n"; cout << " " << numLEs << " entries found.\n"; return 1; } int LEList::SaveFile() //Saves ASCII file containing 7 number entries ->LEList { ofstream OutFile; //LEntry LE; OutFile.open(FileName); if(OutFile.rdstate()) { cout <<"\nUnknown file stream state occured...\nAborting LEFile saving for safety...\n"; return 0;} for(int i=0;i<numLEs;i++) { OutFile << LEs[i] <<"\n"; } OutFile.close(); cout <<"\n Lottery entry file: " << FileName << " saved.\n"; cout << " " << numLEs << " entries written.\n"; return 1; } void GetLNI_NumberOccurenceFrequency(void) { int i, j; for(i=1;i<=MAX_NUMBER;i++) { LNI[i]=0; for(j=0;j<LEL[PrimLEL].numLEs;j++) { if(LEL[PrimLEL].LEs[j].Contains(i)) LNI[i]++; } } } void GetLEI_CompareAllToAll() { unsigned char c; //Compare all to all for(int i=0;i<LEL[PrimLEL].numLEs;i++) { LEI[i]=0; for(int j=0;j<LEL[PrimLEL].numLEs;j++) if(j!=i) { c=LEntries[i].CompareTo(LEL[PrimLEL].LEs[j]); if(c>LEI[i]) LEI[i]=c; //if(c>LEI[j]) LEI[j]=c; } } } void TestCrunchAlpha() //Attempt on a routine that lessens entry similarity and increases the probability of winnning... { int MaxEq,OldMaxEq,i,numAttempts=0; char ch; randomize(); GetLEI_CompareAllToAll(); MaxEq=0; for(i=0;i<LEL[PrimLEL].numLEs;i++)if(LEI[i]>MaxEq)MaxEq=LEI[i]; OldMaxEq=MaxEq; cout << "CrunchAlpha: Randomized entries:\n"; do{ for(i=0;i<LEL[PrimLEL].numLEs;i++) if(LEI[i]==MaxEq) { LEL[PrimLEL].LEs[i].Randomize(); cout << setw(4) <<setfill(' ')<<i; i=LEL[PrimLEL].numLEs; } GetLEI_CompareAllToAll(); MaxEq=0; for(i=0;i<LEL[PrimLEL].numLEs;i++)if(LEI[i]>MaxEq)MaxEq=LEI[i]; numAttempts++; /*if(numAttempts>90){ cout <<"\n MaxEq: "<<MaxEq << " (Old):"<<OldMaxEq; ch=0; cin >> ch; if(ch==32) numAttempts=0; } */ }while((MaxEq>=OldMaxEq) && (numAttempts<100)); cout <<"\n MaxEq: "<<MaxEq << " (Old):"<<OldMaxEq; } DTDBase *CreateNewDTD(DTDTypeIDs T, LEList &L1, LEList &L2, TestingModes M) //Allocates new object of type T... { DTDBase* tmp=NULL; switch (T) { case ID_DTDAlpha : tmp = (DTDBase *)new DTDAlpha(L1, L2, M); break; case ID_DTDOmega : tmp = (DTDBase *)new DTDOmega(L1, L2, M); break; default : tmp = (DTDBase *) new DTDAlpha(L1, L2, M); break; }//End switch if(tmp==NULL) cout<<"ERROR: Pointer==null"; //if(tmp->IsA()!=T) cout<<"Invalid DTD_ID after spawning!\n"; //Booms...? return tmp; } DTDBase *CreateNewDTD(DTDTypeIDs T) { return CreateNewDTD(T, LEL[PrimLEL], LEL[SecLEL], FULL); } DTDBase *LoadAnyDTD(char* FName) //Dynamic loader of DTD files... { ifstream In; DTDTypeIDs I; int i; DTDBase *TmpDTD; In.open(FName); //Lets get the DTD_ID of the file... In>>i; In.close(); I = DTDTypeIDs(i); TmpDTD = CreateNewDTD(I); //Set up a correct object for the data TmpDTD->SetFileName(FName); TmpDTD->LoadDTDFile(); //and load it in.... return TmpDTD; } void RunDTDTest(DTDBase& T) //Generalized Testing procedure... { char ch, cont; #ifdef DEBUG long XCounter=0; float XTime; long SaveLim=1, incSaveLim=1; #endif cout<<"\n************ TESTING INITIATED ****************" <<"\n******* YOU MAY MINIMIZE THIS WINDOW *********" <<"\n**** BUT REMEMBER TO PRESS 'ESC' TO CLOSE *****"; #ifdef DEBUG clockStart=clock(); #endif do{ cont=T++; #ifdef DEBUG XCounter++; if((XCounter&255) && ((clockSeconds(clock()-clockStart)/60)>SaveLim) ) { SaveLim+=incSaveLim; T.SaveDTDFile(); } #endif if(kbhit()) { ch=getch(); if(ch==27)cont=0; cout<<T; if(ch=='s' || ch=='S') T.SaveDTDFile(); #ifdef DEBUG XTime = clockSeconds(clock()-clockStart); cout<<setfill(' ')<<"\nTime:"<<setw(8)<<XTime; if(XTime!=0) cout<<" Speed:"<<setw(8)<<XCounter/XTime <<" TotTime:"<<setw(8)<<int(MAX_DRAW_COMBS*XTime/XCounter/60); #endif } }while(cont); } void ContinueProcessingDTD(char* FName) { DTDBase* T; T = LoadAnyDTD(FName); cout <<" File:'"<<T->FileName<<"' DTD_ID:'"<<int(T->IsA())<<"'\n"; RunDTDTest(*T); T->SaveDTDFile(); delete T; } void main(int argc, char *argv[]) { int i,j; char ch; int MenuChoice; cout << setw(40) << setfill('*') << '*'; cout << "\n\n LOTTERY LOSER - lottery entry analyzer\n"; cout << " - only 7 numbers/entry - version date: "<<VERSION_DATE<<"\n"; cout << "A 'MenThal' (Kent Dahl) program product...\n"; LEL[PrimLEL].LEs = &LEntries[0]; //Set up pointers to the old buffer LEL[SecLEL].LEs = &LEntries[MAX_ENTRIES]; //strcpy(LEL[PrimLEL].FileName,"Lottery.Lot"); LEL[PrimLEL].SetFileName("Lottery.lot"); LEL[PrimLEL].LoadFile(); LEntry A,B; LDrawResult Win; //LoadLEFile(LEFileName); if(argc) //Command line arguments interpreting... for(i=1;i<argc;i++) { cout<<"\n"<<i<<".: '"<<argv[i]<<"'"; if(argv[i][0]=='-') //Command/switch... { switch (toupper(argv[i][1])) { case 'W': { cout<<"\n -W:"<<argv[i]; ContinueProcessingDTD(argv[++i]); /*DTDBase* T; T = LoadAnyDTD(argv[++i]); cout <<" File:'"<<T->FileName<<"' DTD_ID:'"<<int(T->IsA())<<"'\n"; RunDTDTest(*T); T->SaveDTDFile(); delete T; */ break; } case 'L': // Load LEfile { LEL[PrimLEL].SetFileName(argv[++i]); LEL[PrimLEL].LoadFile(); break;} } //End case } } do{ cout <<"\n'"<<LEL[PrimLEL].FileName<<"', "<<LEL[PrimLEL].numLEs<<" entries."; cout <<"\n -+*> Lottery loser <*+-\n"; cout <<" 1. List lottery entries\n"; cout <<" 2. Compare to winning draw\n"; cout <<" 3. LE statistics\n"; cout <<" 4. Save LE's back to file\n"; cout <<" 5. CrunchAlpha...Make entries less similar!\n"; cout <<" 6. Copy current entries to secondary list.\n"; cout <<" 7. Create New DTD file\n"; cout <<" 8. Load new LE file...\n"; cout <<" 9. Load DTD file\n"; cout <<" 0. EXIT\n ->"; // LEL[PrimLEL].numLEs = NumLEntries; //ARG!! MenuChoice=0; do{cin >> MenuChoice; }while(MenuChoice>9 || MenuChoice<0); switch (MenuChoice) { case 1: cout << "\n Lottery entries from " << LEL[PrimLEL].FileName << " file.\n"; cout << "Num. of entries: " <<LEL[PrimLEL].numLEs<<"\n"; for(i=0;i<LEL[PrimLEL].numLEs;i++) { cout << "\n"<<setw(2)<<setfill(' ')<<i<<".:"<< LEL[PrimLEL].LEs[i];//<< LEntries[i]; if((i+1)%20==0) if(getch()==27){cout <<" <Break> "; break;} }; break; //End case 1 case 2: { //Win.EnterResult(); cout << "\n Enter winning draw\n-> "; if(cin >> Win) cout << "\nWinning entry: " << Win << "\n"; /*B = LEntries[0]; cout <<"\nB: "<< B;*/ for(i=0;i<LEL[PrimLEL].numLEs;i++) { j = Win.PrizeTest(LEL[PrimLEL].LEs[i]); cout << "\nEntry "<<setw(2) <<i; j ? cout <<" wins " << j << ". prize!!" : cout <<" "; cout << " C/A: "<<Win.WEntry.CompareTo(LEL[PrimLEL].LEs[i])<< "/" <<Win.CompareAdditional(LEL[PrimLEL].LEs[i]) << " -*-"<< LEL[PrimLEL].LEs[i]; if((i+1)%20==0) if(getch()==27){cout <<" <Break> "; break;} } cout << "\n"; }; break; //End case 2 case 3: //LE Statistics { GetLEI_CompareAllToAll(); for(i=0;i<LEL[PrimLEL].numLEs;i++) { cout <<"\n"<<setw(2)<< i<<".: MaxEqual:"<< (int) LEI[i]; if((i+1)%20==0) if(getch()==27){cout <<" <Break> "; break;} } /*int Max=0,Min=7; for(i=0;i<NumLEntries;i++) { if(LEI[i]>Max) Max=LEI[i]; if(LEI[i]<Min) Min=LEI[i]; } cout << "\n" << "Maximum equal for all:" << Max << "\n" << "Minimum equal for all:" << Min; */ cout << "\n\nSIMILARITY FREQUENCIES: These values might be twice their actual size!!!"; for(i=0;i<8;i++) { int k=0; for(j=0;j<LEL[PrimLEL].numLEs;j++) { if(LEI[j]==i) k++; } if(k)cout <<"\n"<< setw(3) << setfill(' ') << i << " equal, times " << setw(3) << k << " " << setw(k) << setfill('*') << '*'; if(k%2) cout <<" Wot??? "<<k; } getch(); GetLNI_NumberOccurenceFrequency(); cout << "\n\nNUMBER OCCURENCE FREQUENCIES:"; for(i=1;i<=MAX_NUMBER;i++) { cout <<"\n"<< setw(2) << setfill(' ') << i << ": f=" << setw(4) << LNI[i] << " "; if(LNI[i]) cout << setw(LNI[i]) << setfill('#') << '#'; if((i+1)%20==0) if(getch()==27){cout <<" <Break> "; break;} } getch(); }; break; //End case 3 case 4: { cout << "\n Do you really want to save over "<<LEL[PrimLEL].FileName<<"?(Y/N)\n"; ch=getch(); if(ch=='Y' || ch=='y') { cout<<"Saving "<<LEL[PrimLEL].FileName; LEL[PrimLEL].SaveFile(); } else if(ch=='R' || ch=='r') { cout<<"\nEnter new filename:"; cin>>LEL[PrimLEL].FileName; LEL[PrimLEL].SaveFile();} break; } case 5: TestCrunchAlpha(); break; case 6: { cout << "\nCopying entries to secondary list..."; for(i=0;i<LEL[PrimLEL].numLEs;i++) LEL[SecLEL].LEs[i]=LEL[PrimLEL].LEs[i]; SecondaryListPresent=1; LEL[SecLEL].numLEs=LEL[PrimLEL].numLEs; LEL[SecLEL].SetFileName(LEL[PrimLEL].FileName); //strcpy(LEL[SecLEL].FileName,LEL[PrimLEL].FileName); cout << LEL[SecLEL].FileName<<"..Done\n"; break;} case 7: { //LargeScaleDrawTesting(RANDOM,PrimLEL,SecLEL); break; //TestSimulateMultipleDrawsOnBoth(); break; DTDBase* T; char str[80]; TestingModes M; DTDTypeIDs TId; cout<<"\n NEW DTD FILE\nEnter filename:"; cin >> str; cout<<"\n\nSelect DTD type:"; for(i=1;i<NumOf_DTDTypeIDs;i++) cout<<"\n "<<i<<".:"<<DTDTypeDescription[i]; cout<<"\n->"; cin >> int(TId); cout<<"\n\nSelect DTD MODE:"; for(i=0;i<NumOf_TestingModes;i++) cout<<"\n "<<i<<".:"<<TestingModesDescription[i]; cout<<"\n->"; cin >> int(M); T = CreateNewDTD(TId, LEL[PrimLEL], LEL[SecLEL], M); T->SetFileName(str); cout <<" File:'"<<T->FileName<<"' DTD_ID:"<<int(T->IsA())<<" TM:"<<int(M)<<"\n"; RunDTDTest(*T); T->SaveDTDFile(); delete T; /*DTDAlpha T(LEL[PrimLEL], LEL[SecLEL], RANDOM); RunDTDTest(T); */ break;} case 8: { cout <<"\n\n Enter new LE file to load: "; cin >> LEL[PrimLEL].FileName; LEL[PrimLEL].LoadFile(); break; }//Case 8 case 9: { char str[80]; cout<<"\n\n Contine processing DTD file\nEnter filename:->"; cin >>str; ContinueProcessingDTD(str); /*DTDAlpha T(LEL[PrimLEL], LEL[SecLEL], FULL); T.Load("c:/temp/x.dtd"); //T.SetFileName("c:/temp/x.dtd"); RunDTDTest(T); T.SaveDTDFile(); */ break;} // LargeScaleDrawTesting(FULL,PrimLEL,SecLEL); break; case 10: { DTDBase *T; T = CreateNewDTD(ID_DTDOmega, LEL[PrimLEL], LEL[SecLEL], FULL); T->SetFileName("c:/temp/z.dtd"); cout << *T; RunDTDTest(*T); T->SaveDTDFile(); break;}//Case10 } //End all cases }while(MenuChoice!=0); //SaveLEFile(LEFileName); #ifdef DEBUG long l; /*DTDBase *T; T = CreateNewDTD(ID_DTDOmega); T->SetFileName("Ogga Bogga"); cout <<"\n"<< T->FileName<<" "<<int(T->IsA()); T->Report(cout); delete T; //Deletes the contents... */ #endif } //End of MAIN /**/ /* Here follows the brute force method for calc. the probabilities... its the same as the simulation, but goes through EVERY possible DRAWRESULT... Testing X.LOT and LOTTERY.LOT, 2 lists of 50 entries each, program manages ca. 1600 draws per second on the P100... Thats a wooping 19547 minutes = 326 hours = 13.6 days to go through the complete 34C7*(34-7)C2 =1 888 245 216 possible draws.... This method is obviosly NO GOOD!!!!!! - 2 LEntries in two lists - 4900drraws/second => 6423 min = 107 h = 4.46 days ... speed up? 25000 draws/second after PrizeTest retuning.. 07.02.97 ??? 07.02.97 - 50 entry lists X.lot/Lottery.lot - manages 2100 draws/sec ostream& DTDClassAlpha::PrintReport1To(ostream& Os) { if(TDMode==FULL) Os << "\nCounter: "<<TestDraw; //LDRCounter; Os << "\nList: "<<setw(20)<<TDLEL[0]->FileName<<" || "<<setw(20)<<TDLEL[1]->FileName; Os <<"\nPrize.: Cur.(All/Max) || Old.\n"; for(int i=0;i<6;i++){ Os << setfill(' ')<<setw(4)<<i<<".:"; for(int j=0;j<2;j++) { Os << " " << setw(8)<<Prizes[j][i]; Os << ", " <<setw(8)<<MaxPrizes[j][i]<<" ||"; } //if(i==0) Os << " Num. draws that result in NO prizes...\n"; Os << "\n"; } Os <<"P(Any win):"<<float (numLDRs-MaxPrizes[0][0])/numLDRs <<" || "; //if(SecondaryListPresent) Os << float (numLDRs-MaxPrizes[1][0])/numLDRs; Os <<"\nTot:"<<numLDRs<<"\n"; return Os; } ostream& DTDClassAlpha::PrintReport2To(ostream& Os) {if(numLDRs && (TDLEL[0]->numLEs || TDLEL[1]->numLEs)) for(int i=0;i<6;i++){ Os << setfill(' ')<<setw(4)<<i<<".:"; for(int j=0;j<2;j++) { Os << " " << setw(12); if(TDLEL[j]->numLEs) Os <<float(Prizes[j][i])/(numLDRs*TDLEL[j]->numLEs); else Os<<"..."; Os << ", " <<setw(12)<<float(MaxPrizes[j][i])/numLDRs<<" ||"; } Os << "\n"; } return Os; } void LargeScaleDrawTesting(TestingModes DMode, int SelLEL0, int SelLEL1) // Simulated statistical data creation { //unsigned long Prizes[2][6],MaxPrizes[2][6]; //long numLDRs=0; //LDrawResult TestDraw; DTDClassAlpha T; float f1; int prize1, maxPrize1; //, maxPrize2, prize2; int i, j, cont=1; char ch; #ifdef DEBUG long startNumLDRs=0; long SaveLim=1, incSaveLim=1; #endif T.TDMode=DMode; T.TDLEL[0]=&LEL[SelLEL0]; T.TDLEL[1]=&LEL[SelLEL1]; if(DMode==LOAD_WORKFILE) { T.LoadFromFile("C:\\TEMP\\LOT.dtd"); startNumLDRs=T.numLDRs; cout<<"\n**** MINIMIZE THIS WINDOW AND LET THE PROGRAM WORK!!!!!!!"; cout<<"\n******* Press Escape to stop it before quitting ********\n"; } else if(T.TDMode==FULL)T.TestDraw.ResetAsCounter(); if(T.TDMode==RANDOM){ randomize(); T.TestDraw.Randomize(); } if(T.TDMode==FULL) cout <<"\n\n EXTENSIVE TESTING: Press any key for report, Esc to abort!"; if(T.TDMode==RANDOM) cout <<"\n\n SIMULATED DRAW - TESTING: Esc aborts, any other reports..."; #ifdef DEBUG clockStart=clock(); //startNumLDRs=T.numLDRs; #endif do{ T.numLDRs++; maxPrize1=999; for(j=0;j<2;j++) { maxPrize1=999; for(i=0;i<T.TDLEL[j]->numLEs;i++) { //cout<<"\n!!!!!"; //prize1=T.TestDraw.PrizeTest(LEL[j].LEs[i]); prize1=T.TestDraw.PrizeTest(T.TDLEL[j]->LEs[i]); T.Prizes[j][prize1]++; if(prize1) if(prize1<maxPrize1) maxPrize1=prize1; } if(maxPrize1>5)maxPrize1=0; T.MaxPrizes[j][maxPrize1]++; } if(T.TDMode==FULL) { if(!(++T.TestDraw)) cont=0; } else if(T.TDMode==RANDOM) { T.TestDraw.Randomize(); } #ifdef DEBUG if(T.numLDRs%255==0) if( clockSeconds(clock()-clockStart)/60>SaveLim ) { T.SaveToFile("C:\\TEMP\\LOTT.DTD"); cout<<"\nSaved to Lott.dtd\n"; SaveLim+=incSaveLim; } #endif if(kbhit()) { ch=getch(); if(ch=='s' || ch=='S'){ T.SaveToFile("C:\\TEMP\\LOT.dtd"); cout<<"\n DTD file saved. \n"; } if(ch=='l' || ch=='L'){ T.LoadFromFile("C:\\TEMP\\LOT.dtd"); cout <<"\n DTD file loaded. \n"; startNumLDRs=T.numLDRs; clockStart=clock(); } T.PrintReport1To(cout); #ifdef DEBUG clockEnd=clock(); testSeconds=clockSeconds(clockEnd-clockStart); cout << " Total/Time: "<<T.numLDRs-startNumLDRs<<" / "<<testSeconds; if(T.numLDRs-startNumLDRs) cout << " = " << float(T.numLDRs-startNumLDRs)/testSeconds<<" per second."; if(T.TDMode==FULL){ f1=float(T.numLDRs)/MAX_DRAW_COMBS; cout <<"\nPercent done: "<<setw(10)<<f1*100<<"%"; if(T.numLDRs-startNumLDRs) { f1=(MAX_DRAW_COMBS)*testSeconds/(T.numLDRs-startNumLDRs); cout << "\nTotal draw test time approx.: "<<int(f1/3600)<<"h "<<long(f1/60)%60<<"min"; } } #endif cout <<"\n---------------------------------------\n"; if(ch==27)cont=0; } }while(cont); cout << "\nList: "<<setw(20)<<T.TDLEL[0]->FileName<<" || "<<setw(20)<<T.TDLEL[1]->FileName; if(T.TDMode==FULL) cout <<"\nExtTest"; else if(T.TDMode==RANDOM) cout <<"\nSim Test"; cout <<"\nPrize.: Cur.(All/Ent, High/Draw) || Old.\n"; T.PrintReport2To(cout); if(DMode==LOAD_WORKFILE) { T.SaveToFile("C:\\TEMP\\LOT.dtd"); cout<<"\n DTD work file saved. \n"; }; cout << "\n(Press a key)"; ch=getch(); if(DMode!=LOAD_WORKFILE && (ch=='s' || ch=='S')){ T.SaveToFile("C:\\TEMP\\LOT.dtd"); cout<<"\n DTD file saved. \n"; } } */