/**
 * Exerimental determination of the average number of "control breaks" is a
 * random set of unique number.
 *
 * Control break:  break in increasing sequence; i.e., x[k-1] > x[k]
 *
 * Author:  Timothy Rolfe
 */
import java.io.*;
import java.text.DecimalFormat;

public class Chk_N
{//Random generator is used in shuffle.
   static java.util.Random generator = new java.util.Random();

   public static void main ( String[] args )
   {
      int    pass, nPasses;
      int    size, maxSize, sizeStep;
      int[]  test;
      int    k;
      double nBreaks;
      PrintWriter csvFile = null;
      DecimalFormat fmt = new DecimalFormat ("0.000");

      try
      {  File f  = new File("SegNumb.csv");
      // Boolean true in FileWriter opens the file in append mode
      // Boolean true in PrintWriter enables automatic line flushing
         csvFile = new PrintWriter(new FileWriter(f, true), true);
      }
      catch (IOException e)
      {  System.err.println ("CSV file open failed: " + e);
         System.exit(-1);
      }

      System.out.print ("Initial array length:  ");
      if ( args.length < 1 )
         size = readInt();
      else
      {  size = Integer.parseInt(args[0]);
         System.out.println (size);
      } // end if/else regarding args[0]

      System.out.print ("Maximum array length:  ");
      if ( args.length < 2 )
         maxSize = readInt();
      else
      {  maxSize = Integer.parseInt(args[1]);
         System.out.println (maxSize);
      } // end if/else regarding args[1]

      System.out.print ("Increment for length:  ");
      if ( args.length < 3 )
         sizeStep = readInt();
      else
      {  sizeStep = Integer.parseInt(args[2]);
         System.out.println (sizeStep);
      } // end if/else regarding args[2]

      System.out.print ("Number of passes:  ");
      if ( args.length < 4 )
         nPasses = readInt();
      else
      {  nPasses = Integer.parseInt(args[3]);
         System.out.println (nPasses);
      } // end if/else regarding args[3]

      test = new int [maxSize];
      for ( k = 0; k < maxSize; k++ )
         test[k] = k+1;

      csvFile.println    ("n,avg.nSegs");
      System.out.println ("n,avg.nSegs");
      for ( ; size <= maxSize; size += sizeStep )
      {
         nBreaks = 0;

         for ( pass = 0; pass < nPasses; pass++ )
         {
            shuffleArray ( test, size );
            for ( k = 1; k < size; k++ )
               if ( test[k-1] > test[k] )
                  nBreaks++;
         }
         csvFile.println    ( size + "," + fmt.format(nBreaks/nPasses) );
         System.out.println ( size + "," + fmt.format(nBreaks/nPasses) );
      }
   }


/**
 * Shuffle the entire array, using the class scope generator
 */
   static void shuffleArray ( int[] x, int lim )
   {  while ( lim > 1 )
      {  int item;
         int save = x[lim-1];

         item = generator.nextInt(lim);
         x[--lim] = x[item];                // Note predecrement on lim
         x[item] = save;
      } // end while
   } // end shuffleArray()

// Code for reading console from "Java in a Nutshell", p. 166
// Wrap System.in as a BufferedReader.
   static BufferedReader console = new BufferedReader
                                  (new InputStreamReader(System.in));

   public static String readLine()
   {  String rtnVal = "";

      try
      {  rtnVal = console.readLine(); }
      catch (java.io.IOException e)
      {  System.err.println ("File input failed: " + e);
         System.exit(-1);
      }
      return rtnVal;
   } // end readLine()

   public static int readInt()
   {
      String lineInp = readLine();

      try
      {  return Integer.parseInt( lineInp.trim() );  }
      catch (Exception e)
      {  System.err.println (e);
         System.err.println ("Offending line:  " + lineInp);
         System.err.println ("Returning zero.");
         return 0;
      }
   }
}