
import java.io.IOException;
import java.util.Date;

public class ArrayRunner {
    public static final int RANDOM_CODELETS = 2048;

    public static final int MINGLE_COUNT = 256;
    public static final int QUIT_MINGLE_TIME = ( 5 * 60 * 1000 );

    public static void main( String[] args ) throws IOException {

	    //
	    // Know what time we started
	    //
	Date startTime = new Date();
	Date quitMingleAt = new Date( startTime.getTime() + QUIT_MINGLE_TIME );

	    //
	    // Read in the array
	    //
	ARArray arr = new ARArray( System.in );

	    //
	    // Determine how many random codelets to make
	    //
	int startingCodelets = RANDOM_CODELETS;

	String[] defaultPaths = {
	    "ES",
	    "SE",
	    "EES",
	    "EEWES",
	    "EESWSSEN"
	};

	startingCodelets += defaultPaths.length;

	    //
	    // Make a code rack
	    //
	CodeRack rack = new CodeRack( 2 * startingCodelets );

	    //
	    // Stack the population with a few ones that will
	    // always complete the array
	    //
	for ( int ii=0; ii < defaultPaths.length; ++ii ) {
	    rack.addCodelet( new ARCodelet( arr, 0, 0, defaultPaths[ii] ) );
	}

	    //
	    // Add a few random folks
	    //
	for ( int ii=defaultPaths.length; ii < startingCodelets; ++ii ) {
	    ARCodelet codelet = new ARCodelet( arr );
	    codelet.randomize();
	    rack.addCodelet( codelet );
	}

	    //
	    // Iterate here doing combines..
	    //
	long lastTime = ( new Date() ).getTime();
	boolean outOfTime = false;

	try {
	    while ( !outOfTime ) {
		rack.mingleSomeFolks( MINGLE_COUNT );

		long currentTime = ( new Date() ).getTime();
		long deltaTime = currentTime - lastTime;

		Date projectedEnd = new Date( currentTime + deltaTime );

		outOfTime = projectedEnd.after( quitMingleAt );

		lastTime = currentTime;
	    }

	} catch ( Throwable t ) {
	    System.err.println( t );
	}

	    //
	    // run through all of the codelets and find the
	    // best one.
	    //
	Codelet[] codelets = rack.getCodelets();

	ARCodelet maxCodelet = null;
	int maxScore = Integer.MIN_VALUE;

	for ( int ii=0; ii < codelets.length; ++ii ) {
	    ARCodelet codelet = (ARCodelet)codelets[ ii ];
	    int score = codelet.getFinalScore();

	    if ( score >= maxScore ) {
		maxScore = score;
		maxCodelet = codelet;
	    }
	}

	    //
	    // Print the answer
	    //
	System.out.println( "My score should be: " + maxScore );
	System.out.println( "Patrick's answer is: " + maxCodelet.getPath() );
    }
}
