/*
 * The program implements a very simple genetic algorithm, using
 * straightforward (but inefficient) data structures.  The algorithm
 * finds square roots of positive integers through a process of
 * natural selection.
 *
 * Usage:
 *
 *	natselsqrt [-d] [-g n] [-m n] [-p n] [-s n] [-S n] number ...
 *
 * In its simplest form, the program is invoked with a one or more
 * positive integer arguments.  For each argument, a random population
 * is generated and an evolutionary simulation searches for a value
 * that, when squared, is as close to the given integer as possible.
 *
 * Switches can be used to modify the program behavior as follows:
 *
 *	-d	Produce debugging output, showing the best individual
 *		and the generation number each time a better
 *		individual is found.
 *	-g n	Specify the number of generations to run for (default 100).
 *	-m n	Specify the probability of genetic mutation (default
 *		0.001).  Each time a new organism is generated, it is
 *		mutated with a probability equal to this value.  If
 *		the organism mutates, a single randomly selected digit
 *		is changed to a new value from 0 to 9, with uniform
 *		distribution.
 *	-p n	Specify the size of the population of organisms
 *		(default 1000).  This is the number of organisms that
 *		compete to survive into the next generation.
 *	-s n	Specify the size of the selection pool (default 500).
 *		This is the number of organisms that survive into the
 *		next generation.  Note that surviving gives an
 *		organism a chance to become a parent, but does not
 *		guarantee it.  The difference between the -p value
 *		and the -s value is the number of new organisms
 *		produced at the beginning of each generation.
 *	-S n	Specify a seed for the random-number generator.  If no
 *		random seed is given, one is derived from the time of
 *		day.
 *
 * Each organism in the colony is an integer, represented for
 * convenience as a linked list of decimal digits.  The representation
 * is very handy for doing genetic crossover and mutation, and is easy
 * to understand, but it is quite inconvenient for use in squaring a
 * number.  The reader should note that the representation is quite
 * inefficient in both space and time.  Serious users of genetic
 * algorithms put great effort into efficient representations, because
 * they may simulate many hundreds of thousands of generations, each
 * with thousands or millions of organisms.
 * 
 * Many other aspects of this program are simplified in other ways.
 * The program should not be taken as an example of how to implement a
 * genetic algorithm correctly, although it can be useful in
 * understanding the general method.
 *
 * Based on code (c) 2001 Geoff Kuenning.   Updated for Spring
 * 2002 CS 70 use by Melissa O'Neill.
 */

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <algorithm>
#include <string>
#include <float.h>		// For DBL_MAX
#include <cassert>
#include <vector>
#include <list>

using namespace std;

/*
 * Although the code does not define any classes to represent organisms
 * and colonies of organisms, to make the code clearer the following
 * typedefs define aliases that make it easier to follow the code than
 * simply writing list<int> and vector<list<int>>.
 */
 
typedef list<int> Organism;
typedef vector<Organism> Colony;

#include "natselsqrt-private.hpp"

/*
 * Defaults for switch-selectable arguments.
 */

const int COLONY_SIZE = 1000;		// -p: Number of organisms in
					//     colony (aka population)

const int MAX_GENERATIONS = 50;		// -g: Number of generations

const int MAX_RANDOM_SURVIVORS = COLONY_SIZE / 10;
					// -r: Number of random survivors to
					//     next generation

const double MUTATION_PROBABILITY = 0.001;
					// -m: Probability of mutation

const int SELECTION_POOL_SIZE = COLONY_SIZE / 2;
					// -s: Number of survivors to
					//     next generation

/*
 * Global constants of the implementation.
 *
 * The number of digits in an organism is indirectly limited by the
 * maximum precision that the computer can represent.  We use
 * double-precision arithmetic to extend the precision (doubles store
 * more bits on most machines), but even so we are limited to about 14
 * digits.  Since the organism's value will be squared, that limits
 * the organism itself to 7 digits.
 */

const int ORGANISM_BASE   = 10;		// Number base of representation
const int ORGANISM_DIGITS = 7;		// Digits in an organism


/*
 * The NatSelEnv class provides the "environment" in which our organisms
 * fight to survive, in the sense that this environment determines how fit 
 * theorganisms are.  In particular, it stores the target value whose root
 * we are trying to find, the closer an organism's value is to the square
 * root of this value, the fitter the organism.
 *
 * Objects of this class are also *function objects* (in particular they are
 * ``binary predicate'' function objects).  This means that they can be used
 * as if they are functions.  In particular, you can write:
 *
 *     Organism organism1;
 *     Organism organism2;
 *     ... evolve the organisms ...
 *     NatSelEnv myEnvironment(100);
 *     if ( myEnvironment(organism1, organism2) )
 *         cout << "Organism 1 is better! (closer to sqrt(100))" << endl;
 *     else
 *         cout << "Organism 2 is better! (closer to sqrt(100))" << endl;
 *
 * Look at the above code, and think about it for a while.  For a while
 * it will probably seem very strange, but it is a powerful technique
 * that is possible because we can overload the function application
 * operator (i.e., operator() ).
 */

class NatSelEnv {
public:
    /*
     * See function descriptions below
     */
    explicit NatSelEnv(double squaredValue);

    double fitness(const Organism& organism);
    
    bool operator() (const Organism& lhs, const Organism& rhs);

private:

    double squaredValue_;
};


/*
 * Environment constructor.  The colony of organisms "live" in an environment
 * that provides the conditions underwhich natural selection occurs.  The
 * environment is the judge of how fit each organism is.  The only argument
 * to the constructor is the value whose root we are trying to find.
 * The closer an organism is to being the square root of this value, the
 * fitter it is.
 */ 
NatSelEnv::NatSelEnv(double squaredValue)
    : squaredValue_(squaredValue)
{
    // Nothing (else) to do.
}


/*
 * Calculate the fitness of an organism.  The fitness is defined as
 * the absolute value of the difference between the organism's square
 * and the target value that we are trying to find the root of.  In
 * other words, if the organism's value is 5 and the target is 36, the
 * fitness is 11 (i.e., 36 - 5*5).
 */
double NatSelEnv::fitness(
    const Organism& organism)		// Organism to test fitness of
{
    double orgValue = organismValue(organism);
    double square = orgValue * orgValue;

    return fabs(square - squaredValue_);
}

/*
 * The function application operator.  This operator allows objects of
 * this type to be used as if they are functions.  In this case, the
 * function is a binary predicate that returns true of the lhs organism
 * is fitter than the rhs organism (i.e., closer to being the square
 * root of _squaredValue.
 */
bool NatSelEnv::operator() (const Organism& lhs, const Organism& rhs)
{
    return fitness(lhs) < fitness(rhs);
}


/*
 * Main driver for testing DNA recombination.  This function processes
 * all option arguments, generates a pool of organisms, and then
 * applies the rules of natural selection to try to find the one that
 * best satisfies the fitness criterion.  In this case, a fit organism
 * is one that approximates the square root of the passed argument.
 * documentation.
 */
int main(
    int argc,				// Argument count
    char* argv[])			// Argument vector
{
    bool debug;				// True to write debugging output
    int colonySize;			// Number of organisms to simulate
    int numSurvivors;			// Number of survivors to next
					// generation
    int maxGenerations;			// Number of generations to run
    double mutationProbability;		// Probability of a mutation
    int maxRandomSurvivors;		// Maximum number of "unfit" survivors
					// to next generation

    /*
     * Process all option arguments.  Note that the last four
     * arguments are reference parameters, which means that the
     * function can modify them.  The return value is the number of
     * the first non-option argument on the command line.
     */
    int argNo = processOptions(argc, argv, debug, colonySize,
			       numSurvivors, mutationProbability,
			       maxRandomSurvivors, maxGenerations);

    /*
     * Check the arguments to be sure we have at least one target.
     */
    if (argNo >= argc)
	usage(argv[0]);

    /*
     * For each target, use natural selection to find the square root.
     */
    for (  ;  argNo < argc;  ++argNo) {
        NatSelEnv environment(atof(argv[argNo]));
	runEvolution(environment, debug, colonySize, numSurvivors,
		 mutationProbability, maxRandomSurvivors, maxGenerations);
    }

    return 0;
}

/*
 * Option processing.  Scan through the arguments, looking at
 * switches.  If we run into a non-switch argument, exit the function.
 *
 * If an illegal switch is detected, we will print a usage message to
 * cerr and terminate the program with an exit status of 2.
 *
 * The return value of this function is the number of the first
 * non-switch argument encountered.  If there are no non-switch
 * arguments, the return value equals argc.
 *
 * The reader will note that this function is fairly long, even though
 * it does relatively little.  That is generally true of
 * switch-processing functions, and it is not considered bad style so
 * long as the function limits itself to simple operations such as
 * setting Boolean flags.
 */
int processOptions(
    int argc,				// Argument count passed to main
    char* argv[],			// Argument vector passed to main
    bool& debug,			// MODIFIED: set true if debugging
					// enabled
    int& colonySize,			// MODIFIED: set to number of
					// organisms to simulate
    int& numSurvivors,			// MODIFIED: set to number of
					// survivors into next generation
    double& mutationProbability,	// MODIFIED: set to probability of
					// genetic mutations
    int& maxRandomSurvivors,		// MODIFIED: set to maximum number of
					// randomly-chosen survivors
    int& maxGenerations)		// MODIFIED: set to number of
					// generations to simulate
{
    /*
     * Before beginning the loop, we set defaults for all options.  By
     * doing the defaults in a single place, it is easy to change the
     * defaults later if necessary.
     *
     * One of the defaults is the random seed.  If the -s switch
     * appears, we can then clobber the random seed with the specified
     * value.
     */
    debug = false;
    colonySize = COLONY_SIZE;
    numSurvivors = SELECTION_POOL_SIZE;
    maxGenerations = MAX_GENERATIONS;
    mutationProbability = MUTATION_PROBABILITY;
    maxRandomSurvivors = MAX_RANDOM_SURVIVORS;

    setRandomSeed();			// Pick a seed for the PRNG


    /*
     * Note that the loop index is modified inside the body of
     * the loop; this is generally poor style but is common in
     * argument processing.  In this case, the modification is done
     * inside the processing of the "s" switch.
     */
    int argNo;
    for (argNo = 1;  argNo < argc;  ++argNo) {
	if (argv[argNo][0] != '-')	// End of switches?  If so, exit
	    break;			// option processing

	/*
	 * By convention, the special switch option "--" means that
	 * all following arguments are non-option arguments, even if
	 * they start with a hyphen.  If we run into that switch, we
	 * must skip over it but then exit the option-processing loop.
	 *
	 * We use C++ strings in the comparison here primarily for
	 * illustrative purposes.  Note that we must explicitly
	 * typecast one of the arguments of the == operator to
	 * "string" or the comparison won't work -- and we WILL NOT
	 * get any compiler error messages!
	 */
	if (argv[argNo] == string("--")) {
	    argNo++;			// Skip over the --
	    break;			// Go to non-option argument processing
	}

	/*
	 * All other switch options should consist of a single hyphen,
	 * an alphabetic character, and nothing else.  At this point
	 * we know that the hyphen exists.  Check to make sure that
	 * there is exactly one character following it.
	 */
	if (argv[argNo][2] != '\0')
	    usage(argv[0]);

	/*
	 * Process switch options.  We do this in a "switch" statement
	 * so that it is easy to add new options later.
	 */
	switch (argv[argNo][1]) {
	    case 'd':			// -d: Turn on debugging
		debug = true;
		break;

	    case 'g':			// -g n: specify generations
		/*
		 * Processing an option that has an argument is a bit
		 * tricky.  First, we must make sure that there is
		 * actually a following argument.  Second, we must
		 * process that argument appropriately (in this case,
		 * by converting it to an integer and saving it in
		 * maxGenerations).  Third, we must make sure that the
		 * option-processing loop does not try to treat the
		 * argument as a switch itself.  We do that by
		 * incrementing the loop index, as noted in the
		 * comments before the loop.  The first and third
		 * operations are combined.
		 */
		if (++argNo >= argc)	// Make sure there's an argument
		    usage(argv[0]);	// if not, complain and exit

		/*
		 * Convert the next argument to an integer (atoi) and
		 * save it.  If the next argument isn't an integer,
		 * atoi will probably return zero.  But that's OK,
		 * because we'll check it later.
		 */
		maxGenerations = atoi(argv[argNo]);
		break;

	    case 'm':			// -m n: specify mutation probability
		if (++argNo >= argc)	// Make sure there's an argument
		    usage(argv[0]);	// if not, complain and exit

		mutationProbability = atof(argv[argNo]);
		break;

	    case 'p':			// -p n: specify colony size
		if (++argNo >= argc)	// Make sure there's an argument
		    usage(argv[0]);	// if not, complain and exit

		colonySize = atoi(argv[argNo]);
		break;

	    case 'r':			// -r n: specify max random survivors
		if (++argNo >= argc)	// Make sure there's an argument
		    usage(argv[0]);	// if not, complain and exit

		maxRandomSurvivors = atoi(argv[argNo]);
		break;
	    case 's':			// -s n: specify selection pool size
		if (++argNo >= argc)	// Make sure there's an argument
		    usage(argv[0]);	// if not, complain and exit

		numSurvivors = atoi(argv[argNo]);
		break;

	    case 'S':			// -S n: specify random seed
		if (++argNo >= argc)	// Make sure there's an argument
		    usage(argv[0]);	// if not, complain and exit

		/*
		 * Convert the next argument to a long (atol) and pass
		 * it to srandom.  If the next argument isn't an
		 * integer, atol will probably return zero.  But
		 * that's OK, because the behavior of the program will
		 * still be reproducible.
		 */
		srandom(atol(argv[argNo]));
		break;

	    default:			// Default: unrecognized option
		usage(argv[0]);
		break;
	}
    }

    /*
     * Check the legality of invocation.  Now that we have extracted
     * all of the user's options, make sure that they are legal and
     * that they are consistent with each other.  If any problems are
     * detected, either abort the program or correct them.
     */
    if (maxGenerations <= 0) {
	cerr << "Number of generations must be positive." << endl;
	usage(argv[0]);
    }
    if (colonySize <= 0) {
	cerr << "Colony size must be positive." << endl;
	usage(argv[0]);
    }
    if (numSurvivors > colonySize) {
	numSurvivors = colonySize / 2;
	cerr
	  << "Selection pool cannot be bigger than colony, reducing it to "
	  << numSurvivors << endl;
    }

    /*
     * Argument processing is done.  The calling function needs to
     * know how many arguments we swallowed so that it can tell where
     * the non-option arguments begin.  So we return the number of the
     * first non-option argument.
     */
    return argNo;
}

/*
 * Print a usage message and exit.  As is conventional, the exit
 * status is 2 if there is a usage error.
 */
void usage(
    char* programName)			// Name we were run under
{
    cerr << "Usage:\t" << programName <<
      " [-d] [-g n] [-m n] [-p n] [-r n] [-s n] [-S n] number ..." << endl;
    cerr << "Switches:" << endl;
    cerr << "\t-d\tProduce debugging outout." << endl;
    cerr << "\t-g n\tGive number of generations to run for." << endl;
    cerr << "\t-m n\tGive probability of mutation." << endl;
    cerr << "\t-p n\tGive population size." << endl;
    cerr << "\t-r n\tGive maximum number of randomly-chosen survivors." << endl;
    cerr << "\t-s n\tGive selection pool size (number of survivors)." << endl;
    cerr << "\t-S n\tSet random seed" << endl;
    exit(2);
}


/*
 * Use a genetic algorithm to find a square root.  The algorithm
 * operates by repeatedly generating "organisms" that are then tested
 * for "fitness".  In this case, a fit organism is one whose value,
 * when squared, is close to the target.  In each generation, genetic
 * crossover and mutation are used to produce new organisms.  In
 * addition, the fittest organisms survive unchanged into the next
 * generation.
 */
void runEvolution(
    NatSelEnv& environment,		// Number to find square root of
    bool debug,				// Produce debugging information
    int colonySize,			// Size of colony (organisms)
    int numSurvivors,			// Number who survive each generation
    double mutationProbability,		// Probability of a mutation
    int maxRandomSurvivors,		// Maximum number of "unfit" survivors
					// to next generation
    int maxGenerations)			// Number of generations to run for
{
    /*
     * Start with a random population of the chosen size, consisting of
     * randomly chosen organisms.  
     */
    Colony colony;
    colony.reserve(colonySize);		// Reserve space for colonySize
                                        // objects (This line is only present
					// as a small optimization, since
					// we know exactly how big our colony
					// will be.)
    for (int i = 0;  i < colonySize;  ++i)
	colony.push_back(newOrganism());

    /*
     * If we are debugging, we will print out the best candidate each
     * time a new one is found.  To do this, we must track the best
     * fitness found so far.  We start with the best set to the
     * largest possible number so that anything we find will be better.
     */
    double bestFitness = DBL_MAX;

    /*
     * Simulate the requested number of generations
     */
    for (int generation = 0;  generation < maxGenerations;  ++generation) {
	/*
	 * Choose the candidates who will survive until the next
	 * generation and put them at the front of the colony.
	 */
	naturalSelection(environment, colony, numSurvivors, 
                         maxRandomSurvivors);

	/*
	 * If we're debugging, report any improvement.
	 */
	if (debug) {
	    Organism& best = findBest(environment, colony);
	    double newBestFitness = environment.fitness(best);
	    if (newBestFitness < bestFitness) {
		bestFitness = newBestFitness;
		cerr << "Generation " << generation << ": " << best << endl;
	    }
	}

        /*
         * Fill up the remainder of the colony with new organisms
         * whose parents have been selected from the survivors list.
         */
        int numNewOrganisms = colonySize - numSurvivors;
	for (int i = 0;  i < numNewOrganisms;  ++i) {
	    /*
	     * Choose two parents randomly.  Although we use the terms
	     * "father" and "mother", reproduction is actually
	     * asexual; any two organisms can be the parents.  We take
	     * the trouble to be sure the father and mother are
	     * actually different organisms.
	     */
	    int father = randomInt(numSurvivors);
	    int mother = randomInt(numSurvivors);
	    while (father == mother  &&  numSurvivors > 1)
		mother = randomInt(numSurvivors);

	    /*
	     * Cross the parents at a randomly selected place in the
	     * gene string.  Note that this is a simplified
	     * approximation of the way real genetic crossover works.
	     */
	    int crossoverPoint = randomInt(ORGANISM_DIGITS);
	    colony.push_back(
		crossover(colony[father], colony[mother], crossoverPoint));

	    /*
	     * Finally, introduce a random mutation (with small probability).  
	     * Again, this is a rough approximation of reality.
	     */
	    if (random() <= long(mutationProbability * LONG_MAX))
		mutate(colony.back(), randomInt(ORGANISM_DIGITS),
		       randomInt(ORGANISM_BASE));
	}
    }

    /*
     * Report the best organism.  We use double-precision arithmetic,
     * but print the results as integers.  The setf and precision
     * calls will arrange that there is no decimal point.
     */
    Organism& winner = findBest(environment, colony);
    double root = organismValue(winner);
    cout.setf(ios::fixed);
    cout.precision(0);
    cout << winner << " * " << winner << " = " << root * root << endl;
}


/*
 * Do natural selection by choosing the organisms that have the
 * greatest fitness and placing them into a preselected section of
 * the colony.
 *
 * The selection is done by the simple expedient of sorting the
 * organisms by fitness, with the most fit placed first, but with a
 * little bit of randomness thrown in.
 */
void naturalSelection(
    NatSelEnv& environment,		// Environment in which natural
                                        // selection takes place
    Colony& colony,			// colony to select on
    int numSurvivors,		// Number of organisms to have left
    int maxRandomSurvivors)		// Maximum no. of random survivors
{
    /*
     * Selection boils down to just sorting, but we don't need to sort
     * everything.  We only need to bring the fittest numSurvivors to
     * the front of the array.  Interestingly, the code below has
     * evolved as follows:
     * 
     * First version
     *
     *     sort(colony.begin(), colony.end(), environment);
     * 
     * Second version
     *
     *     partial_sort(colony.begin(), colony.begin() + numSurvivors, 
     *                  colony.end(), environment);
     *
     * Third (current) version
     *
     *     nth_element(colony.begin(), colony.begin() + numSurvivors, 
     *                 colony.end(), environment);
     *
     * The third version did change the behaviour of the program compared
     * to previous versions of the code because the random survial code
     * that follows replaces different organisms in this case.
     */
    nth_element(colony.begin(), colony.begin() + numSurvivors, 
                colony.end(), environment);

    /*
     * In real genetics, the fittest organisms sometimes don't
     * survive, and instead less-fit ones reproduce.  This turns out
     * to be a good thing, because it introduces important variance
     * into the genetic pool.  We'll randomize things very slightly to
     * simulate this behavior.
     *
     * Note that this simulation is poor in that all unfit organisms
     * have an equal chance to survive.  A better implementation would
     * make the probability of survival dependent on the fitness.
     */
    int poolSize = colony.size();
    int randomSurvivors = randomInt(maxRandomSurvivors);
    for (int i = 0;  i < randomSurvivors;  ++i) {
	int firstSlot = randomInt(poolSize);
	int secondSlot = randomInt(poolSize);
	if (firstSlot != secondSlot)
	    swap(firstSlot, secondSlot);
	/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- BUG!  Fix this bug when you're
	 * doing the refactoring work for the coding component.  Don't
	 * fix it before... (because it'll make your code give different
	 * answers from the ones we're expecting).
	 * 
	 * The code above should be
	 * 
	 *    if (firstSlot != secondSlot)
	 *        swap(colony[firstSlot], colony[secondSlot]);
	 *
	 */
    }
    
    /*
     * Finally, those organisms that were fortunate enough to be fit or
     * get lucky die and are erased from the colony.
     */
    colony.erase(colony.begin() + numSurvivors, colony.end());
}


/*
 * Find the best organism in a colony.  "Best" is defined simply as
 * the organism with the lowest fitness.  In case of ties, the
 * first-found is chosen.
 */
Organism& findBest(
    NatSelEnv& environment,		// Environment
    Colony& colony)			// Colony to search
{
    return *min_element(colony.begin(), colony.end(), environment);
}


/*
 * Perform in-place DNA mutation.  We walk through the target string,
 * looking for the position that is to be mutated.  When we reach it,
 * we replace the existing gene with the new value provided.
 */
void mutate(
    Organism& target,			// Organism to suffer mutatation
    int position,			// Position to mutate (0-indexed)
    int newGene)			// Gene to insert at mutation point
{
    // If the Organism class supported operator[], we could simply write:
    // target[position] = newGene, but it does not, so we must write the
    // following loop instead.

    int pos = 0;
    for (Organism::iterator i = target.begin(); i != target.end(); ++i) {
        if (++pos == position) {
            *i = newGene;
            return;
        }
    }
}


/*
 * Create a single new organism by generating a string of random
 * digits that is of the proper length.  We create the random digits
 * in a fixed-length array, and then let the Organism constructor
 * produce the final result.
 */
Organism newOrganism()
{
    Organism newOrg;

    for (int i = 0;  i < ORGANISM_DIGITS;  ++i)
	newOrg.push_back(randomInt(ORGANISM_BASE));

    return newOrg;
}


/*
 * Perform DNA crossover.  We walk through the two parent strings
 * simultaneously, copying one or the other to the result.  The choice
 * of what to copy depends on the current position relevant to the
 * recombination position.  Genes from 0 through position-1 are taken
 * from parent 1; genes from position through the end of the list are
 * taken from parent 2.  Note that the length of the list is
 * determined implicitly.
 */
Organism crossover(
    const Organism& parent1,		// First parent's gene list
    const Organism& parent2,		// Second parent's gene list
    int position)			// Where to switch from first to second
{
    Organism result;			// Where we'll build the crossover
    Organism::const_iterator geneIter1 = parent1.begin();
    Organism::const_iterator geneIter2 = parent2.begin();
    for (int i = 0; i < position; ++i, ++geneIter1, ++geneIter2)
        result.push_back(*geneIter1);
    for (;  geneIter2 != parent2.end();  ++geneIter2)
        result.push_back(*geneIter2);
    return result;
}


/*
 * Convert an integer list back into a plain integer.  This only works
 * if the integer list contains values in the range 0-9.  It assumes
 * that the integer list represents a decimal number.
 *
 * The return value is a double because it allows us to represent more
 * digits.  An alternative would be a long long, but that's not standard yet.
 */
double organismValue(
    const Organism& org)		// List to be converted
{
    double result = 0;

    for (Organism::const_iterator i = org.begin();  i != org.end();  ++i)
	result = result * ORGANISM_BASE  +  *i;

    return result;
}


/*
 * Output function for printing organisms (poor creatures, when printed
 * they look like numbers!)
 */
ostream& operator<<(
    ostream& out, 
    const Organism& org)
{
    for (Organism::const_iterator i = org.begin();  i != org.end();  ++i)
        out << int(*i);
    return out;
}


/*
 * Set up a "random" random seed.  This routine works by using the
 * time of day to initialize the pseudorandom number generator. 
 *
 * On a machine that supports /dev/random, a better way to initialize
 * the PRNG would be to read from that device into an array and then use
 * the initstate function to set the initial state table for the random.
 * number generator.  However, doing so would complicate the code.
 */
void setRandomSeed()
{
    srandom(time(NULL));
}


/*
 * Generate a uniformly distributed random integer between 0
 * (inclusive) and a specified maximum value (exclusive).  For
 * example, randomInt(6) will generate a number between 0 and 5, with
 * each value being equally probable.
 * 
 * The code here is a little tricky because we're dealing with integer
 * arithmetic and trying to avoid any bias in the random number generator.
 * Bias is possible because the range of the random number generator
 * (0 .. LONG_MAX inclusive) may not be perfectly divisible by our output
 * range.  To prevent bias, we just discard random number values from
 * the bad zone.
 * 
 */
int randomInt(
    int maximum)			// Maximum value (never generated)
{
    long divisor = LONG_MAX / maximum;
    int candidate;
    do {
        candidate = random() / divisor;
    } while (candidate >= maximum);
    return candidate;
}

/* Junk to make emacs use the right C++ style when editing this code:
 *   Local Variables:
 *   c-file-style: "stroustrup"
 *   End:
 */
