IBM

Compiling xlC with C++11 support - Page 1

So, I write in C# every day at work, but thought to myself a few weeks back I'd try and get back to C/C++ that I studied back around the late 1990s (but never used).
I followed a few examples and got carried away on one on factorials, which I turned into a lotto draw program to try and predict the most common numbers drawn and in actual fact, by the time I'd finished, the factorials part had gone lol. I doubt it will ever produce the correct numbers but it was a fun exercise.

This program works fine when compiled and run with Visual Studio 2013 on Windows Intel but I wanted it to compile and run on IBM AIX xlC 13.0. Programming in Windows is pretty easy in that all I worry about is the .net version I'm building in and the relevant references.

In the program I reference stoi which I know is a C++11 standard and by rights the version of xlC should support, if I compile with the correct arguments. Alas it doesn't or more probable, I'm doing something wrong.

I'm trying xlC -qlanglvl=extended0x \lotto.cpp
It returns "lotto.cpp", line 47.15: 1540-0130 (S) "std::stoi" is not declared.

Ideas? and thanks for your time in what is probably a simple thing to many of you.
-----------------------------------------------------------------------
Hey Ho! Pip & Dandy!
MyDungeon() << :Fuel: :Octane2: :Octane2: :Octane2: :Octane: :Indy: MyLoft() << :540: :Octane: MyWork() << :Indy: :Indy: :O2: :O2: :O2: :Indigo: :Indigo:
Sounds like an issue with the standard library? Are you not including the right header?
smit happens.

:Fuel: bigred , 900MHz R16K, 4GB RAM, V12 DCD, 6.5.30
:Indy: indy , 150MHz R4400SC, 256MB RAM, XL24, 6.5.10
:Indigo2IMP: purplehaze , 175MHz R10000, Solid IMPACT
probably posted from Image bruce , Quad 2.5GHz PowerPC 970MP, 16GB RAM, Mac OS X 10.4.11
plus IBM POWER6 p520 * Apple Network Server 500 * HP C8000 * BeBox * Solbourne S3000 * Commodore 128 * many more...
well grep through your includes and check for stoi
r-a-c.de
a bit OT, about including-troubles (what have I to include <WTF?>? have I included <What.The.Frog> I need? -> so boring to care about!) I am working on a special tool that automagically produces inter-module-dependencies

Pros and cons, a shortening of the Latin expression "pro et contra" (for and against)
  • PROs : you can forget these troubles, it will automagically generate interfaces, dependencies, so you can be focused on the project
  • CONs : it requires the project to be written in a specific way, strictly compliant with { MISRA && DO178A && MIL-STD &&MY(2) } (1)

If I will ever design a SafeC compiler these features will be included by default (can I ask for funds on Kickstarter :oops: :oops: :oops: ?)


(1) because I am too lazy to support whatever can be written with the full C grammar :lol:
(2) MY, my way, I have other directives and rules that need to be applied, early discussed here , LOL
bye. I am not a warez guy. respect.
ClassicHasClass wrote: Sounds like an issue with the standard library? Are you not including the right header?


stoi is a function introduced with C++11.

I don't know the options the OP is passing to the compiler. But I believe xlC needs the "–qlanglvl=extc1x" flag to activate the C++11 features in the compiler. But I don't know if stoi is supported, since last I checked xlC only had partial coverage for the C++11 standard (I could be wrong). If that is the case, the OP can still use atoi or stringstream which do not depend on C++11.
"Was it a dream where you see yourself standing in sort of sun-god robes on a
pyramid with thousand naked women screaming and throwing little pickles at you?"
Instead of blowing against the wind, I changed my super lotto program to work on IRIX, AIX & Windows using ostringstream to convert the INTs to Strings.

First off the board was the random seeding issue. which I had implemented wrong in the first place but it did leave me wondering..
Basically the program:
Generates as many random lottery draws of 6 numbers as inputted by the user.
Adds a count of each number drawn.
Calculates the highest drawn 6 & the lowest drawn 6.
At first this was done through a loop which went through the list sequentially, but that proved to be biased towards the end numbers in the loop, so say number 1,4,5,6,7,8,10 had been drawn 100 times, number 1 would always be pushed off the list. To counter this, each number taken from the list index was also a random number, so 10 could be checked first and maybe 1 last.
Each time a random number was obtained, a new seed was created and this was my mistake.
The IRIX, AIX compile would always get stuck finding the last 2 entries in the list index whilst sorting, yet the windows always worked fine, this had me scratching my head with possible timing issues. I had a loop to delay the time for the new seed by 1 second, and yet it was never able to sort the last 2 numbers.
I changed this to produce a single seed at the beginning, all was well and I was able to remove any sleeps, pauses or loops. To speed things up further, I may remove each entry checked from the list and reduce the random number for the list index sorting.

The AIX can produce a 10,000 lotto sample in about 4 mins, as does the windows machine which is an i7 - Quite impressive I thought. The SGI (300MHz Octane2 - 1.5 GB of memory) is still running and has taken half an hour so far.

Below is the code taken from the windows machine because I'm on it right now. It's exactly the same apart from a few headers in and out.
I may do some time trials on my machines and maybe win the lotto in the process.

Code: Select all

#include "stdafx.h"
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <string>
#include <vector>
#include <list>
//#include <unistd.h>
#include <ctime>
#include <cstdlib>
#include <algorithm>

int generateRandomNumber()
{
int iReturn = 0;
iReturn = rand() % 59 + 1;
return iReturn;
}
int main()
{
time_t timer;
struct tm y2k = { 0 };
int seconds;
y2k.tm_hour = 0;   y2k.tm_min = 0; y2k.tm_sec = 0;
y2k.tm_year = 100; y2k.tm_mon = 0; y2k.tm_mday = 1;
time(&timer);  /* get current time; same as: timer = time(NULL)  */
seconds = difftime(timer, mktime(&y2k));
seconds = seconds % 10000000;
srand((int)seconds);

using std::cin;
using std::cout;
using std::endl;
using std::getchar;
using std::list;
using std::sort;
using std::string;
using std::stringstream;
string sExit = "n";

int iNumberCount1[60] = {};
int iNumberCount2[60] = {};
int iRandom1=0;
int iRandom2=0;
int iRandom3=0;
int iRandom4=0;
int iRandom5=0;
int iRandom6=0;
int iMainLoopMax = 0;
time_t now = time(0);
char* dt = ctime(&now);
cout << "\tThe local date and time is: " << dt << endl;
list<int> lList;
int iListCount = 1;
cout << endl << endl << "ENTER SAMPLE AMMOUNT (MINIUM 61):";
while (!(cin >> iMainLoopMax))
{
cout << "INCORRECT VALUE";
cin.clear();
}

for (int iMainLoop = 0; iMainLoop < iMainLoopMax; iMainLoop++)
{
int iSkip1 = 0;
int iSkip2 = 0;
int iSkip3 = 0;
int iSkip4 = 0;
int iSkip5 = 0;
int iSkip6 = 0;
cout << "Remaing iterations: " << iMainLoopMax - iMainLoop << endl;
iListCount = 0;
lList.clear();
while (iListCount < 7)
{
do
{
iRandom1 = generateRandomNumber();
if (iRandom1 != iRandom2 &&
iRandom1 != iRandom3 &&
iRandom1 != iRandom4 &&
iRandom1 != iRandom5 &&
iRandom1 != iRandom6)
{
cout << "\t\tDraw Number: " << iRandom1 << endl;
lList.push_front(iRandom1);
lList.sort();
lList.unique();
iListCount = lList.size();
iSkip1 = 1;
cout << "List Count: " << iListCount << endl <<
" iRandom1 " << endl;
}
} while (iSkip1 == 0);
if (iListCount == 6)
break;
do
{
iRandom2 = generateRandomNumber();
if (iRandom2 != iRandom1 &&
iRandom2 != iRandom3 &&
iRandom2 != iRandom4 &&
iRandom2 != iRandom5 &&
iRandom2 != iRandom6)
{
cout << "\t\tDraw Number: " << iRandom2 << endl;
lList.push_front(iRandom2);
lList.sort();
lList.unique();
iListCount = lList.size();
iSkip2 = 1;
cout << "List Count: " << iListCount << endl <<
" iRandom2 " << endl;
}
} while (iSkip2 == 0);
if (iListCount == 6)
break;
do
{
iRandom3 = generateRandomNumber();
if (iRandom3 != iRandom1 &&
iRandom3 != iRandom2 &&
iRandom3 != iRandom4 &&
iRandom3 != iRandom5 &&
iRandom3 != iRandom6)
{
cout << "\t\tDraw Number: " << iRandom3 << endl;
lList.push_front(iRandom3);
lList.sort();
lList.unique();
iListCount = lList.size();
iSkip3 = 1;
cout << "List Count: " << iListCount << endl <<
" iRandom3 " << endl;
}
} while (iSkip3 == 0);
if (iListCount == 6)
break;
do
{
iRandom4 = generateRandomNumber();
if (iRandom4 != iRandom1 &&
iRandom4 != iRandom2 &&
iRandom4 != iRandom3 &&
iRandom4 != iRandom5 &&
iRandom4 != iRandom6)
{
cout << "\t\tDraw Number: " << iRandom4 << endl;
lList.push_front(iRandom4);
lList.sort();
lList.unique();
iListCount = lList.size(); iSkip4 = 1;
iSkip4 = 1;
cout << "List Count: " << iListCount << endl <<
" iRandom4 " << endl;
}
} while (iSkip4 == 0);
if (iListCount == 6)
break;
do
{
iRandom5 = generateRandomNumber();
if (iRandom5 != iRandom1 &&
iRandom5 != iRandom2 &&
iRandom5 != iRandom3 &&
iRandom5 != iRandom4 &&
iRandom5 != iRandom6)
{
cout << "\t\tDraw Number: " << iRandom5 << endl;
lList.push_front(iRandom5);
lList.sort();
lList.unique();
iListCount = lList.size();
iSkip5 = 1;
cout << "List Count: " << iListCount << endl <<
" iRandom5 " << endl;
}
} while (iSkip5 == 0);
if (iListCount == 6)
break;
do
{
iRandom6 = generateRandomNumber();
if (iRandom6 != iRandom1 &&
iRandom6 != iRandom2 &&
iRandom6 != iRandom3 &&
iRandom6 != iRandom4 &&
iRandom6 != iRandom5)
{
iRandom6 = generateRandomNumber();
cout << "\t\tDraw Number: " << iRandom6 << endl;
lList.push_front(iRandom6);
lList.sort();
lList.unique();
iListCount = lList.size();
iSkip6 = 1;
cout << "List Count: " << iListCount << endl <<
" iRandom6 " << endl;
}
} while (iSkip6 == 0);
if (iListCount == 6)
break;
cout << "Draw List Count: " << iListCount << endl;
}
cout << "-----------------------------------------" << endl;
lList.unique();
iListCount = lList.size();
for (list<int>::iterator list_iter = lList.begin();
list_iter != lList.end(); list_iter++)
{
cout << "\t\tLotto Number: " << *list_iter << endl;
iNumberCount1[*list_iter]++;
iNumberCount2[*list_iter]++;
}
//I can't recall why this is here FFS!!
for (int iWait = 0; iWait < 999999; iWait++)
{
if (iWait % 100000 == 0)
cout << ".";
}
cout << endl << iListCount << " List Size" << endl;
cout << endl;
}
// End of Part 1 Draw

// Start of Sort
int iNumbersDrawn = 0;
for (int n = 1; n < 60; n++)
{
if (iNumberCount1[n]>0)
{
cout << "  " << n << " Drawn " << iNumberCount1[n] << " times." << std::endl;
iNumbersDrawn = iNumbersDrawn + iNumberCount1[n];
}
}

int iHigh1 = 0;
int iHigh2 = 0;
int iHigh3 = 0;
int iHigh4 = 0;
int iHigh5 = 0;
int iHigh6 = 0;
int iLow1 = iMainLoopMax;
int iLow2 = iMainLoopMax;
int iLow3 = iMainLoopMax;
int iLow4 = iMainLoopMax;
int iLow5 = iMainLoopMax;
int iLow6 = iMainLoopMax;
string sHigh1 = "";
string sHigh2 = "";
string sHigh3 = "";
string sHigh4 = "";
string sHigh5 = "";
string sHigh6 = "";
string sLow1 = "";
string sLow2 = "";
string sLow3 = "";
string sLow4 = "";
string sLow5 = "";
string sLow6 = "";
cout << endl << "CALCULATING HIGH DRAWS" << endl;
for (int n = 1; n < 60; n++)
{
int y = generateRandomNumber();
int iExit = 0;
cout << ".";
if (iNumberCount1[y] != 0)
{
std::ostringstream convert;
convert << y;
if (iNumberCount1[y] >= iHigh1)
{
cout << endl << "INSERTING " << y << " @ Posistion 1" << endl;
iHigh6 = iHigh5;
iHigh5 = iHigh4;
iHigh4 = iHigh3;
iHigh3 = iHigh2;
iHigh2 = iHigh1;
iHigh1 = iNumberCount1[y];
sHigh6 = sHigh5;
sHigh5 = sHigh4;
sHigh4 = sHigh3;
sHigh3 = sHigh2;
sHigh2 = sHigh1;
sHigh1 = convert.str();
iExit = 1;
}
if (iExit == 0)
{
if (iNumberCount1[y] >= iHigh2)
{
cout << endl << "INSERTING " << y << " @ Posistion 2" << endl;
iHigh6 = iHigh5;
iHigh5 = iHigh4;
iHigh4 = iHigh3;
iHigh3 = iHigh2;
iHigh2 = iNumberCount1[y];
sHigh6 = sHigh5;
sHigh5 = sHigh4;
sHigh4 = sHigh3;
sHigh3 = sHigh2;
sHigh2 = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
if (iNumberCount1[y] >= iHigh3)
{
cout << endl << "INSERTING " << y << " @ Posistion 3" << endl;
iHigh6 = iHigh5;
iHigh5 = iHigh4;
iHigh4 = iHigh3;
iHigh3 = iNumberCount1[y];
sHigh6 = sHigh5;
sHigh5 = sHigh4;
sHigh4 = sHigh3;
sHigh3 = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
if (iNumberCount1[y] >= iHigh4)
{
cout << endl << "INSERTING " << y << " @ Posistion 4" << endl;
iHigh6 = iHigh5;
iHigh5 = iHigh4;
iHigh4 = iNumberCount1[y];
sHigh6 = sHigh5;
sHigh5 = sHigh4;
sHigh4 = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
if (iNumberCount1[y] >= iHigh5)
{
cout << endl << "INSERTING " << y << " @ Posistion 5" << endl;
iHigh6 = iHigh5;
iHigh5 = iNumberCount1[y];
sHigh6 = sHigh5;
sHigh5 = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
if (iNumberCount1[y] >= iHigh6)
{
cout << endl << "INSERTING " << y << " @ Posistion 6" << endl;
iHigh6 = iNumberCount1[y];
sHigh6 = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
cout << endl << y << " NOT INSERTED" << endl;
}
iNumberCount1[y] = 0;
}
else
{
n = n - 1;
}
}
cout << endl << "CALCULATING LOW DRAWS" << endl;
for (int n = 1; n < 60; n++)
{
int y = generateRandomNumber();
int iExit = 0;
cout << ".";
if (iNumberCount2[y] != 0)
{
std::ostringstream convert;
convert << y;
if (iNumberCount2[y] <= iLow1)
{
cout << endl << "INSERTING " << y << " @ Posistion 1" << endl;
iLow6 = iLow5;
iLow5 = iLow4;
iLow4 = iLow3;
iLow3 = iLow2;
iLow2 = iLow1;
iLow1 = iNumberCount2[y];
sLow6 = sLow5;
sLow5 = sLow4;
sLow4 = sLow3;
sLow3 = sLow2;
sLow2 = sLow1;
sLow1 = convert.str();
iExit = 1;
}
if (iExit == 0)
{
if (iNumberCount2[y] <= iLow2)
{
cout << endl << "INSERTING " << y << " @ Posistion 2" << endl;
iLow6 = iLow5;
iLow5 = iLow4;
iLow4 = iLow3;
iLow3 = iLow2;
iLow2 = iNumberCount2[y];
sLow6 = sLow5;
sLow5 = sLow4;
sLow4 = sLow3;
sLow3 = sLow2;
sLow2 = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
if (iNumberCount2[y] <= iLow3)
{
cout << endl << "INSERTING " << y << " @ Posistion 3" << endl;
iLow6 = iLow5;
iLow5 = iLow4;
iLow4 = iLow3;
iLow3 = iNumberCount2[y];
sLow6 = sLow5;
sLow5 = sLow4;
sLow4 = sLow3;
sLow3 = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
if (iNumberCount2[y] <= iLow4)
{
cout << endl << "INSERTING " << y << " @ Posistion 4" << endl;
iLow6 = iLow5;
iLow5 = iLow4;
iLow4 = iNumberCount2[y];
sLow6 = sLow5;
sLow5 = sLow4;
sLow4 = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
if (iNumberCount2[y] <= iLow5)
{
cout << endl << "INSERTING " << y << " @ Posistion 5" << endl;
iLow6 = iLow5;
iLow5 = iNumberCount2[y];
sLow6 = sLow5;
sLow5 = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
if (iNumberCount2[y] <= iLow6)
{
cout << endl << "INSERTING " << y << " @ Posistion 6" << endl;
iLow6 = iNumberCount2[y];
sLow6 = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
cout << endl << y << " NOT INSERTED" << endl;
}
iNumberCount2[y] = 0;
}
else
{
n = n - 1;
}
}
cout << "\tThese are your recommended HIGH numbers: " << endl
<< "\t" << sHigh1 << " with " << iHigh1 << " draws" << endl
<< "\t" << sHigh2 << " with " << iHigh2 << " draws" << endl
<< "\t" << sHigh3 << " with " << iHigh3 << " draws" << endl
<< "\t" << sHigh4 << " with " << iHigh4 << " draws" << endl
<< "\t" << sHigh5 << " with " << iHigh5 << " draws" << endl
<< "\t" << sHigh6 << " with " << iHigh6 << " draws" << endl;

cout << "\tThese are your recommended LOW numbers: " << endl
<< "\t" << sLow1 << " with " << iLow1 << " draws" << endl
<< "\t" << sLow2 << " with " << iLow2 << " draws" << endl
<< "\t" << sLow3 << " with " << iLow3 << " draws" << endl
<< "\t" << sLow4 << " with " << iLow4 << " draws" << endl
<< "\t" << sLow5 << " with " << iLow5 << " draws" << endl
<< "\t" << sLow6 << " with " << iLow6 << " draws" << endl;
sExit = getchar();
while (sExit != "Q")
{
// Left in for Windows Console
}
return 0;
}
-----------------------------------------------------------------------
Hey Ho! Pip & Dandy!
MyDungeon() << :Fuel: :Octane2: :Octane2: :Octane2: :Octane: :Indy: MyLoft() << :540: :Octane: MyWork() << :Indy: :Indy: :O2: :O2: :O2: :Indigo: :Indigo:
Well, from a simple programming perspective rather than a performance optimising perspective, you need to learn the wonders of arrays a bit more and how they can cut down on repetition of code. You've used them a bit, but you could shorten that code by a good hundred lines or more by replacing loads of your other variables with arrays and then optimising other passages of code accordingly.

If you replace:

Code: Select all

int iRandom1=0;
int iRandom2=0;
int iRandom3=0;
int iRandom4=0;
int iRandom5=0;
int iRandom6=0;


With...

Code: Select all

int[6] iRandom = {};


And if you do the same for the iSkip variables as well, then instead of code like this:

Code: Select all

while (iListCount < 7)
{
do
{
iRandom1 = generateRandomNumber();
if (iRandom1 != iRandom2 &&
iRandom1 != iRandom3 &&
iRandom1 != iRandom4 &&
iRandom1 != iRandom5 &&
iRandom1 != iRandom6)
{
cout << "\t\tDraw Number: " << iRandom1 << endl;
lList.push_front(iRandom1);
lList.sort();
lList.unique();
iListCount = lList.size();
iSkip1 = 1;
cout << "List Count: " << iListCount << endl <<
" iRandom1 " << endl;
}
} while (iSkip1 == 0);
if (iListCount == 6)
break;
do
{
iRandom2 = generateRandomNumber();
if (iRandom2 != iRandom1 &&
iRandom2 != iRandom3 &&
iRandom2 != iRandom4 &&
iRandom2 != iRandom5 &&
iRandom2 != iRandom6)
{
cout << "\t\tDraw Number: " << iRandom2 << endl;
lList.push_front(iRandom2);
lList.sort();
lList.unique();
iListCount = lList.size();
iSkip2 = 1;
cout << "List Count: " << iListCount << endl <<
" iRandom2 " << endl;
}
} while (iSkip2 == 0);
if (iListCount == 6)
break;
do
{
iRandom3 = generateRandomNumber();
if (iRandom3 != iRandom1 &&
iRandom3 != iRandom2 &&
iRandom3 != iRandom4 &&
iRandom3 != iRandom5 &&
iRandom3 != iRandom6)
{
cout << "\t\tDraw Number: " << iRandom3 << endl;
lList.push_front(iRandom3);
lList.sort();
lList.unique();
iListCount = lList.size();
iSkip3 = 1;
cout << "List Count: " << iListCount << endl <<
" iRandom3 " << endl;
}
} while (iSkip3 == 0);
if (iListCount == 6)
break;
do
{
iRandom4 = generateRandomNumber();
if (iRandom4 != iRandom1 &&
iRandom4 != iRandom2 &&
iRandom4 != iRandom3 &&
iRandom4 != iRandom5 &&
iRandom4 != iRandom6)
{
cout << "\t\tDraw Number: " << iRandom4 << endl;
lList.push_front(iRandom4);
lList.sort();
lList.unique();
iListCount = lList.size(); iSkip4 = 1;
iSkip4 = 1;
cout << "List Count: " << iListCount << endl <<
" iRandom4 " << endl;
}
} while (iSkip4 == 0);
if (iListCount == 6)
break;
do
{
iRandom5 = generateRandomNumber();
if (iRandom5 != iRandom1 &&
iRandom5 != iRandom2 &&
iRandom5 != iRandom3 &&
iRandom5 != iRandom4 &&
iRandom5 != iRandom6)
{
cout << "\t\tDraw Number: " << iRandom5 << endl;
lList.push_front(iRandom5);
lList.sort();
lList.unique();
iListCount = lList.size();
iSkip5 = 1;
cout << "List Count: " << iListCount << endl <<
" iRandom5 " << endl;
}
} while (iSkip5 == 0);
if (iListCount == 6)
break;
do
{
iRandom6 = generateRandomNumber();
if (iRandom6 != iRandom1 &&
iRandom6 != iRandom2 &&
iRandom6 != iRandom3 &&
iRandom6 != iRandom4 &&
iRandom6 != iRandom5)
{
iRandom6 = generateRandomNumber();
cout << "\t\tDraw Number: " << iRandom6 << endl;
lList.push_front(iRandom6);
lList.sort();
lList.unique();
iListCount = lList.size();
iSkip6 = 1;
cout << "List Count: " << iListCount << endl <<
" iRandom6 " << endl;
}
} while (iSkip6 == 0);
if (iListCount == 6)
break;
cout << "Draw List Count: " << iListCount << endl;
}


You can achieve the same with:

Code: Select all

while (iListCount < 6)
{
for (int i=0; i<7; i++)
{
do
{
iRandom[i] = generateRandomNumber();
bool theSame=false;
for (int j=0; j<7; j++)
{
if (i==j)
continue;
if (iRandom[i] == iRandom[j])
theSame=true;
}

if (!theSame)
{
cout << "\t\tDraw Number: " << iRandom[i] << endl;
lList.push_front(iRandom[i]);
lList.sort();
lList.unique();
iListCount = lList.size();
iSkip[i] = 1;
cout << "List Count: " << iListCount << endl <<
" iRandom[" << i << "] " << endl;
}
} while (iSkip[i] == 0);
if (iListCount == 6)
break;
}
cout << "Draw List Count: " << iListCount << endl;
}


This isn't going to fix the IRIX performance of it I don't think, but it'll make it a lot more concise and easy to edit. Note that as I'm used to using a C++ compiler to do my coding, you may need to change the bool bit to an int, or use a C library if you're wanting to use pure C here.

Other bits to tidy are to replace...

Code: Select all

int generateRandomNumber()
{
int iReturn = 0;
iReturn = rand() % 59 + 1;
return iReturn;
}


with...

Code: Select all

int generateRandomNumber()
{
return rand() % 59 + 1;
}


This one will improve performance slightly as you're not having to create a variable, initialise it to zero, set it to another value, then destroy it every time you want to grab a random value. This is for starters anyway :)
Systems in use:
:Indigo2IMP: - Nitrogen : R10000 195MHz CPU, 384MB RAM, SolidIMPACT Graphics, 36GB 15k HDD & 300GB 10k HDD, 100Mb/s NIC, New/quiet fans, IRIX 6.5.22
:Fuel: - Lithium : R14000 600MHz CPU, 4GB RAM, V10 Graphics, 36GB 15k HDD & 300GB 10k HDD, 1Gb/s NIC, New/quiet fans, IRIX 6.5.30
Other system in storage: :O2: R5000 200MHz, 224MB RAM, 72GB 15k HDD, PSU fan mod, IRIX 6.5.30
Absolutely correct chap, suppose I was more focused on getting it running than optimizing.

int generaeteRandom though was the left overs of moving 99% to the top of the main and seeding only once, which is why it looks messy.
-----------------------------------------------------------------------
Hey Ho! Pip & Dandy!
MyDungeon() << :Fuel: :Octane2: :Octane2: :Octane2: :Octane: :Indy: MyLoft() << :540: :Octane: MyWork() << :Indy: :Indy: :O2: :O2: :O2: :Indigo: :Indigo:
you could also move "bool theSame=false;" out of the loops. declare in advance, only set within loops
r-a-c.de
4 Minutes down to 25 seconds on Power5, about an hour down to 56 seconds on 300MHz Octane2.. for 10,000 draws after cleaning up code.
-----------------------------------------------------------------------
Hey Ho! Pip & Dandy!
MyDungeon() << :Fuel: :Octane2: :Octane2: :Octane2: :Octane: :Indy: MyLoft() << :540: :Octane: MyWork() << :Indy: :Indy: :O2: :O2: :O2: :Indigo: :Indigo:
interesting that the changes had so much more impact on irix
r-a-c.de
Jeez, that's a ridiculous difference! That was just with code tidying, not with any major algorithm change or anything?
Systems in use:
:Indigo2IMP: - Nitrogen : R10000 195MHz CPU, 384MB RAM, SolidIMPACT Graphics, 36GB 15k HDD & 300GB 10k HDD, 100Mb/s NIC, New/quiet fans, IRIX 6.5.22
:Fuel: - Lithium : R14000 600MHz CPU, 4GB RAM, V10 Graphics, 36GB 15k HDD & 300GB 10k HDD, 1Gb/s NIC, New/quiet fans, IRIX 6.5.30
Other system in storage: :O2: R5000 200MHz, 224MB RAM, 72GB 15k HDD, PSU fan mod, IRIX 6.5.30
Yup, that was implementing all your changes, changing everything to arrays etc.. I'm now running a 1,00000 sample draws. I've added the ability to add the number of draws as an argument so that I can #time ./a.out 1000000

Code: Select all

//If you supply an int above 61 as a command line argument, user input will not be required
//and iMainLoop is the argument supplied. iMainLoop is the number of lotto draws.

#include "stdafx.h"  //Include for Microsoft Systems / Remove for UNIX systems
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <string>
#include <vector>
#include <list>
//#include <unistd.h> //Remove for Microsoft Systems / Include for UNIX systems
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <ctime>
#include <cstdlib>
#include <algorithm>

int generateRandomNumber()
{
return rand() % 59 + 1;
}
int main(int argc, char* argv[])
{
// Seed the randomizer with the current machine seconds
time_t timer;
struct tm y2k = { 0 };
int seconds;
y2k.tm_hour = 0;   y2k.tm_min = 0; y2k.tm_sec = 0;
y2k.tm_year = 100; y2k.tm_mon = 0; y2k.tm_mday = 1;
time(&timer);  /* get current time; same as: timer = time(NULL)  */
seconds = difftime(timer, mktime(&y2k));
seconds = seconds % 10000000;
srand((int)seconds);


using std::cin;
using std::cout;
using std::endl;
using std::getchar;
using std::list;
using std::sort;
using std::string;
using std::stringstream;
string sExit = "n";

int iNumberCount1[60] = {};
int iNumberCount2[60] = {};
int iRandom[6] = { 0 };
int iMainLoopMax = 0;
time_t now = time(0);
char* dt = ctime(&now);
cout << "\tThe local date and time is: " << dt << endl;
list<int> lList;
int iListCount = 1;

// Check if an argument is supplied. If it is, is it valid?
// If any doubt, set the default run to 1000.
if (argv[1] != NULL)
{
if (!(atoi(argv[1]) >> iMainLoopMax))
{
cout << endl << endl << "INCORRECT ARGUMENT - USING DEFAULT 100";
iMainLoopMax = 1000;
}
else
{
iMainLoopMax = atoi(argv[1]);
}
}
else
{
cout << endl << endl << "ENTER SAMPLE AMMOUNT (MINIUM 61):";
while (!(cin >> iMainLoopMax))
{
cout << "INCORRECT VALUE";
cin.clear();
}
}
cout << endl << "ITERATIONS: " << iMainLoopMax << endl;

// Start running the 6 ball lotto draws.
for (int iMainLoop = 0; iMainLoop < iMainLoopMax; iMainLoop++)
{
int iSkip[6] = { 0 };
cout << "Remaing iterations: " << iMainLoopMax - iMainLoop << endl;
iListCount = 0;
lList.clear();
bool theSame = false;
while (iListCount < 6)
{
for (int i = 0; i<7; i++)
{
do
{
iRandom[i] = generateRandomNumber();
theSame = false;
for (int j = 0; j<7; j++)
{
if (i == j)
continue;
if (iRandom[i] == iRandom[j])
theSame = true;
}

if (!theSame)
{
cout << "\t\tDraw Number: " << iRandom[i] << endl;
lList.push_front(iRandom[i]);
lList.sort();
lList.unique();
iListCount = lList.size();
iSkip[i] = 1;
cout << "List Count: " << iListCount << endl <<
" iRandom[" << i << "] " << endl;
}
} while (iSkip[i] == 0);
if (iListCount == 6)
break;
}
cout << "Draw List Count: " << iListCount << endl;
}
cout << "-----------------------------------------" << endl;
lList.unique();
iListCount = lList.size();
//Copy the list to another list because later on, we will destroy the lists when sorting high draws and low draws.
for (list<int>::iterator list_iter = lList.begin();
list_iter != lList.end(); list_iter++)
{
cout << "\t\tLotto Number: " << *list_iter << endl;
iNumberCount1[*list_iter]++;
iNumberCount2[*list_iter]++;
}
cout << endl << iListCount << " List Size" << endl;
cout << endl;
}
// End of Part 1 Draw

// Start of Sort
int iNumbersDrawn = 0;
// Display each number with the amount it has been drawn.
for (int n = 1; n < 60; n++)
{
if (iNumberCount1[n]>0)
{
cout << "  " << n << " Drawn " << iNumberCount1[n] << " times." << std::endl;
iNumbersDrawn = iNumbersDrawn + iNumberCount1[n];
}
}
int iHigh[6] = { 0 };
int iLow[6] = { iMainLoopMax };
string sHigh[6] = { "" };
string sLow[6] = { "" };
cout << endl << "CALCULATING HIGH DRAWS" << endl;
for (int n = 1; n < 60; n++)
{
int y = generateRandomNumber();
int iExit = 0;
cout << ".";
if (iNumberCount1[y] != 0)
{
std::ostringstream convert;
convert << y;
if (iNumberCount1[y] >= iHigh[0])
{
cout << endl << "INSERTING " << y << " @ Posistion 1" << endl;
for (int i = 5; i > 0; i=i-1)
{
iHigh[i] = iHigh[i - 1];
}
iHigh[0] = iNumberCount1[y];
for (int i = 5; i > 0; i=i-1)
{
sHigh[i] = sHigh[i - 1];
}
sHigh[0] = convert.str();
iExit = 1;
}
if (iExit == 0)
{
if (iNumberCount1[y] >= iHigh[1])
{
cout << endl << "INSERTING " << y << " @ Posistion 2" << endl;
for (int i = 5; i > 1; i=i-1)
{
iHigh[i] = iHigh[i - 1];
}
iHigh[1] = iNumberCount1[y];
for (int i = 5; i > 1; i = i - 1)
{
sHigh[i] = sHigh[i - 1];
}
sHigh[1] = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
if (iNumberCount1[y] >= iHigh[2])
{
cout << endl << "INSERTING " << y << " @ Posistion 3" << endl;
for (int i = 5; i > 2; i = i - 1)
{
iHigh[i] = iHigh[i - 1];
}
iHigh[2] = iNumberCount1[y];
for (int i = 5; i > 2; i = i - 1)
{
sHigh[i] = sHigh[i - 1];
}
sHigh[2] = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
if (iNumberCount1[y] >= iHigh[3])
{
cout << endl << "INSERTING " << y << " @ Posistion 4" << endl;
for (int i = 5; i > 3; i = i - 1)
{
iHigh[i] = iHigh[i - 1];
}
iHigh[3] = iNumberCount1[y];
for (int i = 5; i > 3; i = i - 1)
{
sHigh[i] = sHigh[i - 1];
}
sHigh[3] = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
if (iNumberCount1[y] >= iHigh[4])
{
cout << endl << "INSERTING " << y << " @ Posistion 5" << endl;
for (int i = 5; i > 4; i = i - 1)
{
iHigh[i] = iHigh[i - 1];
}
iHigh[4] = iNumberCount1[y];
for (int i = 5; i > 4; i = i - 1)
{
sHigh[i] = sHigh[i - 1];
}
sHigh[4] = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
if (iNumberCount1[y] >= iHigh[5])
{
cout << endl << "INSERTING " << y << " @ Posistion 6" << endl;
iHigh[5] = iNumberCount1[y];
sHigh[5] = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
cout << endl << y << " NOT INSERTED" << endl;
}
iNumberCount1[y] = 0;
}
else
{
n = n - 1;
}
}
cout << endl << "CALCULATING LOW DRAWS" << endl;
for (int n = 1; n < 60; n++)
{
int y = generateRandomNumber();
int iExit = 0;
cout << ".";
if (iNumberCount2[y] != 0)
{
std::ostringstream convert;
convert << y;
if (iNumberCount2[y] <= iLow[0])
{
cout << endl << "INSERTING " << y << " @ Posistion 1" << endl;
for (int i = 5; i > 0; i = i - 1)
{
iLow[i] = iLow[i - 1];
}
iLow[0] = iNumberCount2[y];
for (int i = 5; i > 0; i = i - 1)
{
sLow[i] = sLow[i - 1];
}
sLow[0] = convert.str();
iExit = 1;
}
if (iExit == 0)
{
if (iNumberCount2[y] <= iLow[1])
{
cout << endl << "INSERTING " << y << " @ Posistion 2" << endl;
for (int i = 5; i > 1; i = i - 1)
{
iLow[i] = iLow[i - 1];
}
iLow[1] = iNumberCount2[y];
for (int i = 5; i > 1; i = i - 1)
{
sLow[i] = sLow[i - 1];
}
sLow[1] = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
if (iNumberCount2[y] <= iLow[2])
{
cout << endl << "INSERTING " << y << " @ Posistion 3" << endl;
for (int i = 5; i > 2; i = i - 1)
{
iLow[i] = iLow[i - 1];
}
iLow[2] = iNumberCount2[y];
for (int i = 5; i > 2; i = i - 1)
{
sLow[i] = sLow[i - 1];
}
sLow[2] = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
if (iNumberCount2[y] <= iLow[3])
{
cout << endl << "INSERTING " << y << " @ Posistion 4" << endl;
for (int i = 5; i > 3; i = i - 1)
{
iLow[i] = iLow[i - 1];
}
iLow[3] = iNumberCount2[y];
for (int i = 5; i > 3; i = i - 1)
{
sLow[i] = sLow[i - 1];
}
sLow[3] = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
if (iNumberCount2[y] <= iLow[4])
{
cout << endl << "INSERTING " << y << " @ Posistion 5" << endl;
for (int i = 5; i > 4; i = i - 1)
{
iLow[i] = iLow[i - 1];
}
iLow[4] = iNumberCount2[y];
for (int i = 5; i > 4; i = i - 1)
{
sLow[i] = sLow[i - 1];
}
sLow[4] = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
if (iNumberCount2[y] <= iLow[5])
{
cout << endl << "INSERTING " << y << " @ Posistion 6" << endl;
iLow[5] = iNumberCount2[y];
sLow[5] = convert.str();
iExit = 1;
}
}
if (iExit == 0)
{
cout << endl << y << " NOT INSERTED" << endl;
}
iNumberCount2[y] = 0;
}
else
{
n = n - 1;
}
}
cout << "\tThese are your recommended HIGH numbers: " << endl;
for (int i = 0; i < 6; i++)
{
cout << "\t" << sHigh[i] << " with " << iHigh[i] << " draws" << endl;
}
cout << "\tThese are your recommended LOW numbers: " << endl;
for (int i = 0; i < 6; i++)
{
cout << "\t" << sLow[i] << " with " << iLow[i] << " draws" << endl;
}
sExit = getchar();
return 0;
}

IBM returned 1,000,000 in 40Minutes 53Seconds.
Octane returned 1,000,000 in 1Hour 45Minutes 37Seconds

ALAS.. the improvement wasn't as much, but still worth it.. I found a delay loop still in the old program.
The memory taken up are both very similar before 3744k after 3760k
Pre clean-up 10,000 1Minute 27Seconds
Post clean up 10,000 1Minute 19seconds

Must not forget that, it's a random program, so whatever algorithm, one could still take longer than the other.
-----------------------------------------------------------------------
Hey Ho! Pip & Dandy!
MyDungeon() << :Fuel: :Octane2: :Octane2: :Octane2: :Octane: :Indy: MyLoft() << :540: :Octane: MyWork() << :Indy: :Indy: :O2: :O2: :O2: :Indigo: :Indigo:
if you wanna beef it up more you could replace the iostreams with c stuff and use static inline for generateRandomNumber()
r-a-c.de
foetz wrote: if you wanna beef it up more you could replace the iostreams with c stuff and use static inline for generateRandomNumber()

NICE!
Shaved off 18 seconds !! :D
Inline 10,000 1Minute 1Second

Also thinking I may remove the copy of lists for high and low and NOT setting them to zero when sorted, but this may mean more hit attempts?
-----------------------------------------------------------------------
Hey Ho! Pip & Dandy!
MyDungeon() << :Fuel: :Octane2: :Octane2: :Octane2: :Octane: :Indy: MyLoft() << :540: :Octane: MyWork() << :Indy: :Indy: :O2: :O2: :O2: :Indigo: :Indigo:
Just run a 10000 test on my super fast Octane2.. 21 Seconds.. beating the IBM by 4 seconds
Octane2 300MHz 1.5GB RAM Single CPU 1 Min 5 Seconds
Octane2 600MHz 4GB RAM Dual CPU 21 Seconds
IBM 285 Power5 2GHz 1GB RAM Single CPU 25 Seconds

Now running a Million draws on each. (again tests are random and not like for like)
-----------------------------------------------------------------------
Hey Ho! Pip & Dandy!
MyDungeon() << :Fuel: :Octane2: :Octane2: :Octane2: :Octane: :Indy: MyLoft() << :540: :Octane: MyWork() << :Indy: :Indy: :O2: :O2: :O2: :Indigo: :Indigo:
the 600mhz octane beat the 2ghz power5? :shock:
r-a-c.de
Indeed..
I'd like to test if it utilizing both CPUs by restricting it to a single CPU, If I Recall Incorrectly.. what is the command runonone ? Am I thinking of a smoke/jaleo command?
It does use both CPUs we can see from top. Further testing with a new machine introduced:

Octane 2 - 2x600MHZ - 3584MB Ram -- 10,000 Draws - 21s
IBM Power5 2GHZ - 1GB Ram -- 10,000 Draws - 24s
Octane 2 - 1x300MHZ - 1536MB Ram -- 10,000 Draws - 1m 03s
Octane 1 - 2x195 MHZ - 768MB Ram -- 10,000 Draws - 1m 31s
-----------------------------------------------------------------------
Hey Ho! Pip & Dandy!
MyDungeon() << :Fuel: :Octane2: :Octane2: :Octane2: :Octane: :Indy: MyLoft() << :540: :Octane: MyWork() << :Indy: :Indy: :O2: :O2: :O2: :Indigo: :Indigo:
"runon" is what you're looking for
r-a-c.de
foetz wrote: "runon" is what you're looking for

Cheers Foetz, running on an individual brings the time to match the IBM 25 Seconds 10,000.
-----------------------------------------------------------------------
Hey Ho! Pip & Dandy!
MyDungeon() << :Fuel: :Octane2: :Octane2: :Octane2: :Octane: :Indy: MyLoft() << :540: :Octane: MyWork() << :Indy: :Indy: :O2: :O2: :O2: :Indigo: :Indigo: