
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class Exercise19022
{

	public static void main( String args[] )
	{
		final String here = "e19022.m ";
		if ( args.length < 1 )
		{
			throw new RuntimeException( here +"add a filename argument" );
		}
		String userSaysFile = args[ 0 ];
		List<String> fileLines = new LinkedList<>();
		try
		{
			Path where = Paths.get( userSaysFile );
			fileLines = Files.readAllLines( where );
		}
		catch ( IOException | InvalidPathException ie )
		{
			System.err.println( here +"couldn't read file "+ userSaysFile +" because "+ ie );
			return;
		}
		/*
		- interpretation of spec -
		file is single line csv of a recurring format with four relevant indicies:
		{ opCode, left operand, right operand, target index }
		opcode 99 is halt
		opcode 1 is memory[ target ] = left + right
		opcode 2 is memory[ target ] = left * right
		after that's done, skip to the next opcode, which is to say, by four
		*/
		int initialInd = 0, loInd = initialInd +1, roInd = loInd +1,
				tInd = roInd +1, nextInd = tInd +1;
		String times = " * ", plus = " + ", operator = times;
		String line = fileLines.get( 0 );
		int pcounter = initialInd, nvLim = 135;
		entireRun :
		for ( int firstNoun = 0; firstNoun < nvLim; firstNoun += 1 )
		{
			for ( int firstVerb = 0; firstVerb < nvLim; firstVerb += 1 )
			{
				pcounter = initialInd;
				String[] memory = line.split( "," );
				System.out.println( "another run, "+ firstNoun +" & "+ firstVerb );
				memory[ loInd ] = Integer.valueOf( firstNoun ).toString();
				memory[ roInd ] = Integer.valueOf( firstVerb ).toString();
				if ( (firstNoun == 0 && firstVerb == 0) )
					// || (firstNoun == 0 && firstVerb == 1) )
				{
					for ( int indP = 0; indP < memory.length; indP += 1 )
					{
						System.out.print( memory[ indP ] +", " );
						if ( (indP % 4) == 3 )
							System.out.println();
					}
				}
				// System.out.println( "- - -" );
				int sentinel = 1_000_000_000;
				int leftAddress = -1, rightAddress = -1, targetAddress = -1,
						result = -1, leftOperand = -1, rightOperand = -1;
				String opCode;
				while ( sentinel > 0 && pcounter < memory.length )
				{
					sentinel -= 1;
					opCode = memory[ pcounter ];
					if ( opCode.equals( "99" ) )
					{
						// System.out.println( here +"halting" );
						break;
					}
					leftAddress = Integer.parseInt( memory[ pcounter + loInd ] );
					rightAddress = Integer.parseInt( memory[ pcounter + roInd ] );
					targetAddress = Integer.parseInt( memory[ pcounter + tInd ] );
					if ( leftAddress <= memory.length )
						leftOperand = Integer.parseInt( memory[ leftAddress ] );
					else
						System.out.println( here +"left address outside at "+ leftAddress );
					if ( rightAddress <= memory.length )
						rightOperand = Integer.parseInt( memory[ rightAddress ] );
					else
						System.out.println( here +"right address outside at "+ rightAddress );
					if ( opCode.equals( "1" ) )
					{
						result = leftOperand + rightOperand;
						operator = plus;
					}
					else if ( opCode.equals( "2" ) )
					{
						result = leftOperand * rightOperand;
						operator = times;
					}
					else
					{
						System.out.println( here +"unrecognized op code "+ opCode );
					}
					if ( targetAddress >= memory.length )
					{
						/*
						System.out.println( " "+ here +"r "+ result +" = "+ leftOperand +"@"+ leftAddress + operator
								+ rightOperand +"@"+ rightAddress +" outside to "+ targetAddress );
						*/
					}
					else
					{
						// 
						/*
						System.out.println( here +"r "+ result +" = "+ leftOperand +"@"+ leftAddress + operator
								+ rightOperand +"@"+ rightAddress +" to "
								+ targetAddress +" ["+ memory[ targetAddress ] +"]" );
						*/
						memory[ targetAddress ] = Integer.valueOf( result ).toString();
					}
					pcounter += nextInd;
				}

				System.out.println( "\t"+ here +"first opcode is "+ memory[ 0 ] );
				if ( "19690720".equals( memory[ 0 ] ) )
				{
					break entireRun;
				}
			}
		}
	}
}



























