/*
Online Java - IDE, Code Editor, Compiler
Online Java is a quick and easy tool that helps you to build, compile, test your programs
online.
*/

//FINAL VERSION
//using P(9,9)
//Maximum performance
//It will show the process of all backtracking on the screen outputs
//If it enters error section - identifed 3 occurrences of a number in row/column
//and not recorded in array, it will display all violations on screen for investigation
//As failover it will add the 3 numbers into blockedPermutationNumberColumnSequence/blockedPermutationNumberSequence
//and it will block any further boards

//Also configure this to ensure violations are displayed on the screen
//if (numAttempts%10000==0 && numAttempts!=0)
//It will display all violations in blockedPermutationNumberColumnSequence and blockedPermutationNumberSequence once it hits congratulations also
//Also found up to 31,000,000 was permissible to stay within Java heap space, it might vary depending on the IDE
//int [][]blockedPermutationNumberColumnSequence = new int[31000000][9];
//int [][]blockedPermutationNumberSequence = new int[31000000][9];


import java.math.*;
import java.util.*;
import java.util.stream.*;

interface Fillable
{
    public void fill3x3();
    public void fill9x9(Map<Integer, int[][]> mp);
    public boolean checkUniqueRows(int [][] temp, int rowIndex);
    public boolean checkUniqueColumns(int[][] nineByNine, int colIndex);
    public boolean sudokuComplete(boolean a, boolean b);
    public void wipe9x9Board(int[][] formattedBoard, int[][] nineByNine);
    public void print9x9Board(String history, int numComplete9x9Boards);
    public int convertStringTo3x3(String permutations3x3, int getNumString);
    public void realTime9x9Fill(String history);
    public void display9x9();
    public void displayViolationAllowedBlocks(int numAttempts);

}

class Sudoku implements Fillable
{
    int minimum=362880;
    int maximum=0;

    int randomNumber;
    StringJoiner summary;
    StringJoiner summary1;

    int numAttempts;
    //BigInteger numAttempts=new BigInteger("0");

    //I introduced this to keep track of number completed suduko boards which pass validation
    //BigInteger numSuccessfulCompletedBoards = new BigInteger("0");
    int numSuccessfulCompletedBoards = 0;

    int numRetrieved3x3GridsIn9x9Grid;

    int numberPossibleBoards = 2000000000;

    Set<String> permutationAllBoards = new HashSet();

    Map<Integer, int[][]> mp = new HashMap();

    int possibleNumbers[] = new int[]{1,2,3,4,5,6,7,8,9};

    List<Integer> lst = new ArrayList<Integer>();

    int MiniTest[][] = new int[3][3];
    int formattedBoard[][] = new int [9][9];

    //Map<BigInteger, int[][]> completedBoards = new HashMap<>();
    Map<Integer, int[][]> completedBoards = new HashMap<>();

    //Need to change this into BigInteger
    //BigInteger numComplete9x9Boards = new BigInteger("1");
    int numComplete9x9Boards=1;   //number completed 9x9 boards....

    StringJoiner sj1 = new StringJoiner(",");

    int [][] nineByNine = new int[][]{
            {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0}};


    int totalNumbersProcessed=1;
    long permutations;
    String Permutations3x3into9x9;

    int threeBythree[][] = new int[3][3];

    Set<String> s = new HashSet();

    StringJoiner sj;
    int storeMiniGrids[][][];
    int currentSize;
    int newSize;
    int[][] miniGrid;
    int[][][] miniGridContainer;

    List<Integer> copy = new ArrayList<>(lst);

    boolean endFirstRow3x3=false;
    Random rand = new Random();


    //We are now using Set PermutationAllBoards to hold the completed board (currentStringJoinerFullGrid)
    //This can be phased out
    //String[] completedBoardsLogs = new String[10000];

    int count=0;
    int rowIndex=0;
    int colIndex=0;

    int randomNumber1to9List;
    boolean failedColumns;
    boolean failedRows;
    boolean sudokuSuccess;

    //Taken from previous code
    int position;

    int gridNumber;
    int numFullViolation;

    int positionColumn;
    int[] storeRetrieved3x3Grid=new int[9];

    //I am totally unsure so for now will use large number
    //whole array might need to be changed datatype in future
    int [][]blockedPermutationNumberColumnSequence = new int[28000000][9];
    int [][]blockedPermutationNumberSequence = new int[28000000][9];

    int uniqueEntries=0;

    boolean hasMatchSecondPermutationNumber=false;

    boolean hasMatchSecondPermutationNumberCol=false;

    int pos=0;
    int marker=0;

    int numberOf3x3Processed=0;

    boolean hasExecuteOnce;
    int successfulInputted3x3=0;

    boolean hasProcessedThirdBlockInRow;
    boolean hasViolationFirstTwoBlocks;
    boolean hasFirstWithThirdBlockViolate;
    boolean hasSecondWithThirdBlockViolate;

    boolean []hasViolationTwoStandingTopBlocks = new boolean[3];

    boolean []hasProcessedThirdBlockInColumn = new boolean[3];

    int offset;
    int columnIndexMatch;

    int minimumGridsInRowToProcess;

    int []copyStoreRetrieved3x3Grid=new int[9];
    int []copyStoreRetrieved3x3GridColumn=new int[9];
    int m;
    int idx;

    int rowIndexMatch;

    boolean []hasFirstWithThirdBlockInColumnViolate = new boolean[3];
    boolean []hasSecondWithThirdBlockInColumnViolate = new boolean[3];

    int numFullViolationColumn;

    int locationZeroRow=0;
    int locationZeroCol=0;

    //never resets
    int maxSuccessfulInputted3x3=0;
    int numberColBacktrack;
    int numberRowBacktrack;

    int prevNumFullViolationColumn=0;

    int numStoreOccurenceThreeInColumn=0;
    int numStoreOccurenceThreeInRow=0;

    int locationRestoreBackTrack;

    int [][] allowedPermutationSequenceRow = new int[3000000][9];
    int [][] allowedPermutationSequenceCol = new int[3000000][9];

    int positionAllowed;
    int positionAllowedCol;

    int numThreeStreakRow;
    int numThreeStreakCol;

    public void wipe9x9Board(int [][]formattedBoard, int nineByNine[][])
    {
        for (int q=0; q<nineByNine.length; q++)
        {
            for (int r=0; r<nineByNine[0].length; r++)

            {
                formattedBoard[q][r]=0;
                nineByNine[q][r]=0;
            }
        }
    }

    public Sudoku(long permutations, String  Permutations3x3into9x9)
    {
        this.permutations =permutations;
        this.Permutations3x3into9x9=Permutations3x3into9x9;

        fill3x3();
    }

    public void displayViolationAllowedBlocks(int numAttempts)
    {
        if (!hasExecuteOnce)
        {
            hasExecuteOnce=true;

            if (numAttempts%10000==0 && numAttempts!=0)
            //if(numAttempts==4)
            {
                for (int i=0; i<position;i++)
                {
                    System.out.println("----------------CURRENT violating permutation row sequences: "
                            + Arrays.toString(blockedPermutationNumberSequence[i]));
                }

                for (int i=0; i<positionColumn;i++)
                {
                    System.out.println("----------------CURRENT violating permutation column sequences: "
                            + Arrays.toString(blockedPermutationNumberColumnSequence[i]));
                }

                for (int i=0; i<positionAllowed;i++)
                {
                    System.out.println("----------------CURRENT allowed permutation row sequences: "
                            + Arrays.toString(allowedPermutationSequenceRow[i]));
                }

                for (int i=0; i<positionAllowedCol;i++)
                {
                    System.out.println("----------------CURRENT allowed permutation col sequences: "
                            + Arrays.toString(allowedPermutationSequenceCol[i]));
                }
                //System.exit(0);
            }
        }
    }

    public int convertStringTo3x3(String permutations3x3, int getNum)
    {
        int temp;
        char num;
        String numString;

        num=permutations3x3.charAt(getNum);
        numString= String.valueOf(num);

        temp= Integer.parseInt(numString);

        return temp;
    }

    public void fill3x3()
    {
        int row=0;
        int col=0;
        int numbersProcessed;

        sj = new StringJoiner(",");

        System.out.println("There are : " + permutations + " permutations of arranging  3 x 3 grid" );
        System.out.println("There are : " + Permutations3x3into9x9 + " permutations of arranging  3 x 3 grid into 9 x 9:" + "P(362880,9)" );
        System.out.println("There are : 6,670,903,752,021,072,936,960" + " permutations of completing sudoku (taken from internet)");

        System.out.println("This code will attempt to explore but its impossible to expect much");
        System.out.println("It is used for foundation of experimentation but also it has made serious attempt to complete random process to make a grid");
        System.out.println("I am removing excess code so it is ready future development.");

        do
        {
            IntStream stream = Arrays.stream(possibleNumbers);
            stream.forEach(str -> lst.add(str));

            numbersProcessed=0;

            //System.out.println("*****This is the list size------: " + lst.size());   //list size

            //System.out.println("\n******These are permutations completed:" + s.size());  //set size

            do
            {
                endFirstRow3x3=false;

                randomNumber = rand.nextInt(lst.size());

                randomNumber1to9List=lst.get(randomNumber);
                threeBythree[row][col]= randomNumber1to9List;

                sj.add(Integer.toString(randomNumber1to9List));
                lst.remove(randomNumber);

                if (col%2==0 && col!=0)
                {
                    row++;
                    col=0;
                    endFirstRow3x3 = true;
                }

                if (!endFirstRow3x3)
                {
                    col++;
                }

                numbersProcessed++;

            }while(!lst.isEmpty());

            currentSize=s.size();

            s.add(sj.toString());

            newSize=s.size();
            //System.out.println("This is the new set size: " + newSize + "     Added:   " + sj.toString());

            sj=new StringJoiner(" ");

            if (newSize>currentSize)
            {
                mp.put(newSize,threeBythree);
            }

            row=0;
            col=0;

        }while (s.size()<362880);    // this is getting  <(NUMBER)  x   (3x3 boards)
        //}while (s.size()<10);    // this is getting  <(NUMBER)  x   (3x3 boards)


        fill9x9(mp);
    }

    public void fill9x9(Map<Integer, int[][]> mp)
    {
        boolean hasViolatedBoard=false;

        int temp[][]=new int[3][3];


        int rowCount=0;
        int colCount=0;
        boolean ReachEndColMiniGrid=false;

        gridNumber=1;

        offset=0;

        numberOf3x3Processed=0;
        int m;
        int entry3x3=0;

        boolean condition1=false;
        boolean condition2=false;
        boolean condition3=false;

        int numberMatches=0;

        int numberMatchesCol=0;

        int prevNumFullViolation=0;

        do
        {
            displayViolationAllowedBlocks(numAttempts);

            hasViolatedBoard=false;

            do
            {
                hasViolatedBoard=false;

                //System.out.println("1This is store of 3 x 3 grids: " + Arrays.toString(storeRetrieved3x3Grid));

                String[] perm3x3 = s.toArray(new String[s.size()]);
                String[] perm3x3Selection = new String[perm3x3.length];

                String second3x3StringPlacedInGrid;
                uniqueEntries=0;

                if (numberOf3x3Processed%9!=0  || numberOf3x3Processed==0)
                {
                    do
                    {
                        randomNumber = 1+ rand.nextInt(perm3x3.length-1);

                        if (randomNumber<minimum)
                        {
                            minimum=randomNumber;
                        }

                        if (randomNumber>maximum)
                        {
                            maximum=randomNumber;
                        }

                        //System.out.println("UNIQUE ENTRIES: " + uniqueEntries);

                        //System.out.println("CURRENT permutation numbers generated: "
                        //+ Arrays.toString(storeRetrieved3x3Grid));

                        if ((perm3x3Selection[randomNumber-1])=="ALREADY SELECTED")
                        {
                            //System.out.println("*********************************GRID ALREADY SELECTED" + "("+randomNumber+") " +"GENERATING ANOTHER");

                            randomNumber = 1+ rand.nextInt(perm3x3.length-1);

                            if (randomNumber<minimum)
                            {
                                minimum=randomNumber;
                            }

                            if (randomNumber>maximum)
                            {
                                maximum=randomNumber;
                            }
                        }
                        else
                        {
                            //Based on this we are storing entire row or entire column from storeRetrieved3x3Grid
                            //issue is that in our blockedviolations we are ONLY storing pairs
                            //unless an error occurs
                            //so if we choose uniqueEntries==3 (on basis that no backtracking has occured)
                            //it would then be similar to having no entries in blockedviolations (almost like first run
                            //it appears every run is like the first run since there has been no backtracking.
                            //it would then perform usual operations 1st with 2nd in row (if applicable), 2nd with third.....

                            //I am also getting scenarios where successfulInputted3x3==2
                            //so when it fails on 3rd grd in row, we would expect it to hit:
                            //1st with 3rd or 2nd with 3rd.. It might be interesting to get screen outputs of these
                            //juwt to verify the grid so far exactly represents this. Otherwise it would have stored
                            //all blockedviolations as expected

                            storeRetrieved3x3Grid[uniqueEntries]=randomNumber;
                            uniqueEntries++;

                            //System.out.println("*********************************NEW ENTRY: " + randomNumber);
                            perm3x3Selection[randomNumber-1]="ALREADY SELECTED";
                            //System.out.println("THIS INDEX IS NOW BEING TAGGED AS AKREADY SELECTED IN perm3x3Selection: " + (randomNumber-1));
                            //System.out.println(Arrays.toString(storeRetrieved3x3Grid));

                            if (/*uniqueEntries==1 || */uniqueEntries==4 || uniqueEntries==7)
                            {
                                copyStoreRetrieved3x3GridColumn=new int[9];
                                copyStoreRetrieved3x3GridColumn[0]=storeRetrieved3x3Grid[0];
                                copyStoreRetrieved3x3GridColumn[1]=storeRetrieved3x3Grid[3];
                                copyStoreRetrieved3x3GridColumn[2]=storeRetrieved3x3Grid[6];
                                //System.out.println("Starting to check violations at first column: " + "["+
                                //copyStoreRetrieved3x3GridColumn[0]+","+copyStoreRetrieved3x3GridColumn[1]+","+copyStoreRetrieved3x3GridColumn[2]+"]");
                            }

                            if (/*uniqueEntries==2 || */uniqueEntries==5 || uniqueEntries==8)
                            {
                                copyStoreRetrieved3x3GridColumn=new int[9];
                                copyStoreRetrieved3x3GridColumn[0]=storeRetrieved3x3Grid[1];
                                copyStoreRetrieved3x3GridColumn[1]=storeRetrieved3x3Grid[4];
                                copyStoreRetrieved3x3GridColumn[2]=storeRetrieved3x3Grid[7];
                                //System.out.println("Starting to check violations at second column: " + "["+
                                //copyStoreRetrieved3x3GridColumn[0]+","+copyStoreRetrieved3x3GridColumn[1]+","+copyStoreRetrieved3x3GridColumn[2]+"]");
                            }

                            if (/*uniqueEntries==3 || */uniqueEntries==6 || uniqueEntries==9)
                            {
                                copyStoreRetrieved3x3GridColumn=new int[9];
                                copyStoreRetrieved3x3GridColumn[0]=storeRetrieved3x3Grid[2];
                                copyStoreRetrieved3x3GridColumn[1]=storeRetrieved3x3Grid[5];
                                copyStoreRetrieved3x3GridColumn[2]=storeRetrieved3x3Grid[8];
                                //System.out.println("Starting to check violations at third column: " + "["+
                                //copyStoreRetrieved3x3GridColumn[0]+","+copyStoreRetrieved3x3GridColumn[1]+","+copyStoreRetrieved3x3GridColumn[2]+"]");
                            }


                            if (uniqueEntries>=2 && uniqueEntries<=3)
                            {
                                minimumGridsInRowToProcess=1;
                                copyStoreRetrieved3x3Grid=new int[9];
                                copyStoreRetrieved3x3Grid[0]=storeRetrieved3x3Grid[0];
                                copyStoreRetrieved3x3Grid[1]=storeRetrieved3x3Grid[1];
                                copyStoreRetrieved3x3Grid[2]=storeRetrieved3x3Grid[2];
                                //System.out.println("Starting to check violations at start first row: " + "["+
                                //copyStoreRetrieved3x3Grid[0]+","+copyStoreRetrieved3x3Grid[1]+","+copyStoreRetrieved3x3Grid[2]+"]");
                            }
                            if (uniqueEntries>=5 && uniqueEntries<=6)
                            {
                                minimumGridsInRowToProcess=4;
                                copyStoreRetrieved3x3Grid=new int[9];
                                copyStoreRetrieved3x3Grid[0]=storeRetrieved3x3Grid[3];
                                copyStoreRetrieved3x3Grid[1]=storeRetrieved3x3Grid[4];
                                copyStoreRetrieved3x3Grid[2]=storeRetrieved3x3Grid[5];
                                //System.out.println("Starting to check violations at start second row: " + "["+
                                //copyStoreRetrieved3x3Grid[0]+","+copyStoreRetrieved3x3Grid[1]+","+copyStoreRetrieved3x3Grid[2] +"]");
                            }

                            if (uniqueEntries>=8)
                            {
                                copyStoreRetrieved3x3Grid=new int[9];
                                minimumGridsInRowToProcess=7;
                                copyStoreRetrieved3x3Grid[0]=storeRetrieved3x3Grid[6];
                                copyStoreRetrieved3x3Grid[1]=storeRetrieved3x3Grid[7];
                                copyStoreRetrieved3x3Grid[2]=storeRetrieved3x3Grid[8];
                                //System.out.println("Starting to check violations at start third row: " + "["+
                                //copyStoreRetrieved3x3Grid[0]+","+copyStoreRetrieved3x3Grid[1]+","+copyStoreRetrieved3x3Grid[2]+"]");
                            }

                            if (numFullViolationColumn>prevNumFullViolationColumn)
                            {
                                System.out.println("SEEING IF BACKTRACKING IS CORRECT (COLUMN VIOLATION): ");
                                System.out.println("This is current storeRetrieved3x3Grid: " + Arrays.asList(storeRetrieved3x3Grid[uniqueEntries-1]));
                                System.out.println("It is filling unique entry: " + Arrays.toString(storeRetrieved3x3Grid));
                                numberColBacktrack++;

                                prevNumFullViolationColumn=numFullViolationColumn;
                                //System.exit(0);
                            }

                            if (numFullViolation>prevNumFullViolation)
                            {
                                System.out.println("SEEING IF BACKTRACKING IS CORRECT (ROW VIOLATION):");
                                System.out.println("This is current storeRetrieved3x3Grid: " + Arrays.asList(storeRetrieved3x3Grid[uniqueEntries-1]));
                                System.out.println("It is filling unique entry: " + Arrays.toString(storeRetrieved3x3Grid));
                                //System.exit(0);
                                numberRowBacktrack++;
                                prevNumFullViolation=numFullViolation;
                            }

                            //need to start from 0, can not adust
                            if (uniqueEntries>0 && position!=0)
                            {
                                if (uniqueEntries==9)
                                {
                                    //System.out.println("-----------THESE ARE PERMUTATIONS: " + Arrays.toString(storeRetrieved3x3Grid));
                                }

                                for (int p=numberMatches; p<uniqueEntries;p++)
                                {
                                    //System.out.println("Unique entries: " + uniqueEntries);
                                    //System.out.println("current state of permutation sequences: " + Arrays.toString(storeRetrieved3x3Grid));
                                    //System.out.println("VALUE OF numberMatches(start index:  " + numberMatches+") " + storeRetrieved3x3Grid[numberMatches]);
                                    //System.out.println("It will be checking up to last permutation entry: " + storeRetrieved3x3Grid[uniqueEntries-1]);
                                    //System.out.println("minimumGridsInRowToProcess: " + minimumGridsInRowToProcess);

                                    for (int h=0; h<position; h++)
                                    {
                                        for (int u=numberMatches; u<blockedPermutationNumberSequence[0].length; u++)
                                        {
                                            //System.out.println("IN HERE: " + blockedPermutationNumberSequence[h][u]);
                                            //System.out.println(copyStoreRetrieved3x3Grid[p]);
                                            //System.out.println(blockedPermutationNumberSequence[h][u]);
                                            if (copyStoreRetrieved3x3Grid[p]==blockedPermutationNumberSequence[h][u])
                                            {
                                                if (u==p)
                                                {
                                                    //System.out.println("THIS IS VALUE OF U: " + u);
                                                    //System.out.println("THIS IS VALUE OF P: " + p);

                                                    //System.out.println("prev perm number blocked: "+ blockedPermutationNumberSequence[h][u-1]);

                                                    if (numberMatches==0)
                                                    {
                                                        //System.out.println("MATCH index: " + p + " " + " storeRetrieved3x3Grid[p] " + storeRetrieved3x3Grid[p]);
                                                        //System.out.println("h: " + h + " u: " + u + "  MATCH1 blockedPermutationNumberSequence: " + blockedPermutationNumberSequence[h][u]);
                                                    }

                                                    locationZeroRow=0;

                                                    if (numberMatches>0)
                                                    {
                                                        for (int z=numberMatches;z>=0;z--)
                                                        {
                                                            if(blockedPermutationNumberSequence[h][z]==copyStoreRetrieved3x3Grid[z])
                                                            {
                                                                hasMatchSecondPermutationNumber=true;
                                                                locationZeroRow++;

                                                            }
                                                            else
                                                            {
                                                                hasMatchSecondPermutationNumber=false;
                                                                break;
                                                            }
                                                        }
                                                    }
                                                    //System.out.println("CURRENT permutation numbers generated: " + Arrays.toString(storeRetrieved3x3Grid));
                                                    numberMatches++;
                                                }
                                            }

                                            boolean beforeUniqueEntryEqualNine=false;
                                            boolean afterUniqueEntryEqualNine=false;

                                            if (uniqueEntries<9)
                                            {
                                                beforeUniqueEntryEqualNine =(numberMatches==uniqueEntries && hasMatchSecondPermutationNumber
                                                        && blockedPermutationNumberSequence[h][uniqueEntries]==0);
                                            }
                                            else
                                            {
                                                afterUniqueEntryEqualNine = numberMatches==uniqueEntries && hasMatchSecondPermutationNumber;
                                            }

                                            //System.out.println("**********IMPORTANT INFORMATION ROW VIOLATION CHECK*************");
                                            //System.out.println("Permutations selected: " + Arrays.toString(storeRetrieved3x3Grid));
                                            //System.out.println("ROW SEGMENT: " + Arrays.toString(copyStoreRetrieved3x3Grid));
                                            //System.out.println("Violating RULE[h]:     " + Arrays.toString(blockedPermutationNumberSequence[h]));
                                            //System.out.println("h=" + h + " numberMatches=" + numberMatches + " uniqueEntries=" + uniqueEntries);
                                            //System.out.println("Grid number: " + gridNumber);
                                            //System.out.println("Location of zero (unique entry): " + (locationZeroRow+1));

                                            if (uniqueEntries!=9)
                                            {
                                            }

                                            if(beforeUniqueEntryEqualNine?beforeUniqueEntryEqualNine:afterUniqueEntryEqualNine)
                                            {
                                                System.out.println(Arrays.toString(storeRetrieved3x3Grid) +
                                                        "is in full violation with " +
                                                        Arrays.toString(blockedPermutationNumberSequence[h]));

                                                System.out.println("At index: " + p + " there is violation: " + " permutation number:" + storeRetrieved3x3Grid[p]);
                                                System.out.println("This row permutation selection violates the board: ");
                                                System.out.println("Number unique entries: " + uniqueEntries);

                                                //System.exit(0);

                                                hasViolatedBoard=true;

                                                prevNumFullViolation=numFullViolation;
                                                numFullViolation++;

                                                h=positionColumn;
                                                u=blockedPermutationNumberColumnSequence[0].length;
                                                p=uniqueEntries;
                                                h=position;
                                                //storeRetrieved3x3Grid[uniqueEntries-1]=0;

                                                System.out.println("****1BACKTRACKING TO UNIQUE ENTRY: " + storeRetrieved3x3Grid[uniqueEntries-1]);
                                                System.out.println("Currently failed row: " + failedRows);

                                                locationRestoreBackTrack = storeRetrieved3x3Grid[uniqueEntries-1] -1;
                                                System.out.println("INDEX LOCATION ON storeRetrieved3x3Grid: " + locationRestoreBackTrack);


                                                System.out.println("Current contents as perm3x3Selection (using permutation number): " +  perm3x3Selection[locationRestoreBackTrack]);
                                                System.out.println("Current contents as perm3x3Selection (using random number): " +  perm3x3Selection[randomNumber-1]);
                                                //We know that index taken in perm3x3Selection which has already selected
                                                //is one index less than the actual value in storeRetrieved3x3Grid

                                                //We know random number is the permutation number, so we perform substitution (see location variable declared above)
                                                //perm3x3Selection[randomNumber-1]);

                                                //We also know that random number should be last permutation number selected
                                                perm3x3Selection[locationRestoreBackTrack]="";
                                                System.out.println("Contents perm3x3Selection should be empty and available for selection: " + perm3x3Selection[locationRestoreBackTrack]);
                                                System.out.println("Contents perm3x3Selection should be empty and available for selection: " + perm3x3Selection[(randomNumber-1)]);

                                                storeRetrieved3x3Grid[uniqueEntries-1]=0;
                                                uniqueEntries = uniqueEntries - 1;
                                                //System.exit(0);
                                            }
                                            else
                                            {
                                                //System.out.println("NO VIOLATIONS FOUND");
                                                hasMatchSecondPermutationNumber=false;
                                                break;
                                            }
                                        }
                                    }

                                    for (int h=0; h<positionColumn; h++)
                                    {
                                        for (int u=numberMatchesCol; u<blockedPermutationNumberColumnSequence[0].length; u++)
                                        {
                                            if (copyStoreRetrieved3x3GridColumn[p]==blockedPermutationNumberColumnSequence[h][u])
                                            {
                                                if (u==p)
                                                {
                                                    if (numberMatchesCol==0)
                                                    {

                                                    }

                                                    if (numberMatchesCol>0)
                                                    {
                                                        locationZeroCol=0;

                                                        for (int z=numberMatchesCol;z>=0;z--)
                                                        {
                                                            if(blockedPermutationNumberColumnSequence[h][z]==copyStoreRetrieved3x3GridColumn[z])
                                                            {
                                                                hasMatchSecondPermutationNumberCol=true;
                                                                locationZeroCol++;
                                                            }
                                                            else
                                                            {
                                                                hasMatchSecondPermutationNumberCol=false;
                                                                break;
                                                            }
                                                        }
                                                    }
                                                    numberMatchesCol++;
                                                }
                                            }

                                            boolean beforeUniqueEntryEqualNine=false;
                                            boolean afterUniqueEntryEqualNine=false;

                                            if ((uniqueEntries>3 && uniqueEntries<9) && !hasViolatedBoard)
                                            {
                                                beforeUniqueEntryEqualNine =(numberMatchesCol==uniqueEntries && hasMatchSecondPermutationNumberCol
                                                        && blockedPermutationNumberColumnSequence[h][uniqueEntries]==0);

                                                //System.out.println("**********IMPORTANT INFORMATION COLUMN VIOLATION CHECK*************");
                                                //System.out.println("Permutations selected: " + Arrays.toString(storeRetrieved3x3Grid));
                                                //System.out.println("COL SEGMENT: " + Arrays.toString(copyStoreRetrieved3x3GridColumn));
                                                //System.out.println("Violating RULE[h]:     " + Arrays.toString(blockedPermutationNumberColumnSequence[h]));
                                                //System.out.println("h=" + h + " numberMatchesCol=" + numberMatchesCol + " uniqueEntries=" + uniqueEntries);
                                                //System.out.println("Grid number: " + gridNumber);
                                                //System.out.println("Location of zero (unique entry): " + (locationZeroCol+1));

                                                if (uniqueEntries!=9)
                                                {
                                                    //System.out.println("blockedPermutationNumberSequence[h][uniqueEntries]==0: " + blockedPermutationNumberSequence[h][uniqueEntries]);
                                                }
                                                //System.exit(0);
                                            }
                                            else
                                            {
                                                afterUniqueEntryEqualNine = numberMatchesCol==uniqueEntries && hasMatchSecondPermutationNumberCol;
                                            }

                                            if(beforeUniqueEntryEqualNine?beforeUniqueEntryEqualNine:afterUniqueEntryEqualNine)
                                            {

                                                System.out.println(Arrays.toString(storeRetrieved3x3Grid) +
                                                        "is in full violation with " + Arrays.toString(blockedPermutationNumberColumnSequence[h]));

                                                System.out.println("At index: " + p + " there is violation: " + " permutation number:" + storeRetrieved3x3Grid[p]);
                                                System.out.println("This column permutation selection violates the board: ");
                                                System.out.println("Number unique entries: " + uniqueEntries);


                                                if (uniqueEntries==9)
                                                {
                                                    //System.exit(0);
                                                }

                                                hasViolatedBoard=true;

                                                prevNumFullViolationColumn=numFullViolationColumn;
                                                numFullViolationColumn++;

                                                p=uniqueEntries;
                                                h=positionColumn;
                                                u=blockedPermutationNumberColumnSequence[0].length;


                                                System.out.println("****2BACKTRACKING TO: " + storeRetrieved3x3Grid[uniqueEntries-1]);

                                                System.out.println("Currently failed row: " + failedRows);
                                                System.out.println("Successful grids placed: " + successfulInputted3x3);

                                                locationRestoreBackTrack = storeRetrieved3x3Grid[uniqueEntries-1] -1;
                                                System.out.println("LOCATION: " + locationRestoreBackTrack);

                                                System.out.println("Current contents as perm3x3Selection (using permutation number): " +  perm3x3Selection[locationRestoreBackTrack]);
                                                System.out.println("Current contents as perm3x3Selection (using random number): " +  perm3x3Selection[randomNumber-1]);
                                                //We know that index taken in perm3x3Selection which has already selected
                                                //is one index less than the actual value in storeRetrieved3x3Grid

                                                //We know random number is the permutation number, so we perform substitution (see location variable declared above)
                                                //perm3x3Selection[randomNumber-1]);

                                                //We also know that random number should be last permutation number selected
                                                perm3x3Selection[locationRestoreBackTrack]="";
                                                System.out.println("Contents perm3x3Selection should be empty and available for selection: " + perm3x3Selection[locationRestoreBackTrack]);
                                                System.out.println("Contents perm3x3Selection should be empty and available for selection: " + perm3x3Selection[(randomNumber-1)]);

                                                storeRetrieved3x3Grid[uniqueEntries-1]=0;
                                                uniqueEntries = uniqueEntries - 1;
                                                //System.exit(0);

                                            }
                                            else
                                            {
                                                //System.out.println("NO VIOLATIONS FOUND");
                                                hasMatchSecondPermutationNumberCol=false;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }

                            //System.out.println("The current permutation numbers:  " + storeRetrieved3x3Grid[uniqueEntries]);

                            numberMatches=0;
                            numberMatchesCol=0;

                        }
                    }while (uniqueEntries<9);
                }

                pos=0;

                for (int z:storeRetrieved3x3Grid)
                {
                    if (pos==marker)
                    {
                        //System.out.println("***************************************************************: " + z);
                        //System.out.println("VALUE OF ENTRY in 3x3:" + entry3x3);
                        temp[0][0]=convertStringTo3x3(perm3x3[z],0);
                        temp[0][1]=convertStringTo3x3(perm3x3[z],2);
                        temp[0][2]=convertStringTo3x3(perm3x3[z],4);
                        temp[1][0]=convertStringTo3x3(perm3x3[z],6);
                        temp[1][1]=convertStringTo3x3(perm3x3[z],8);
                        temp[1][2]=convertStringTo3x3(perm3x3[z],10);
                        temp[2][0]=convertStringTo3x3(perm3x3[z],12);
                        temp[2][1]=convertStringTo3x3(perm3x3[z],14);
                        temp[2][2]=convertStringTo3x3(perm3x3[z],16);
                    }
                    pos++;
                }
                marker++;

                //*********************************************************

                if(!hasViolatedBoard)
                {
                    //System.out.println("This is store of 3 x 3 grids: " + Arrays.toString(storeRetrieved3x3Grid));

                    perm3x3 = s.toArray(new String[s.size()]);

                    if (totalNumbersProcessed<=81)
                    {
                        if (totalNumbersProcessed<=27 && !condition2 && !condition3)
                        {
                            rowIndex=0;
                            colIndex=0;
                            condition1=true;
                            condition2=true;
                            condition3=true;
                        }

                        if (totalNumbersProcessed<=54 && totalNumbersProcessed>27 && condition1 && condition3)
                        {
                            rowIndex=3;
                            colIndex=0;
                            condition2=true;
                            condition1=false;
                            condition3=false;
                        }

                        if (totalNumbersProcessed<=81 && totalNumbersProcessed>54 && condition2 && !condition1)
                        {
                            rowIndex=6;
                            colIndex=0;
                            condition3=false;
                            condition1=true;
                            condition2=false;
                        }
                        ReachEndColMiniGrid=false;

                        if (numberOf3x3Processed==9)
                        {
                            switch(gridNumber)
                            {
                                case 1:
                                    rowIndex=0;
                                    hasProcessedThirdBlockInColumn=new boolean[3];
                                    hasSecondWithThirdBlockInColumnViolate=new boolean[3];
                                    hasViolationTwoStandingTopBlocks=new boolean[3];

                                    break;

                                case 2:
                                    rowIndex=0;
                                    break;

                                case 3:
                                    rowIndex=0;
                                    break;

                                case 4:
                                    rowIndex=3;

                                    hasProcessedThirdBlockInRow=false;
                                    hasViolationFirstTwoBlocks=false;
                                    hasFirstWithThirdBlockViolate=false;
                                    hasSecondWithThirdBlockViolate=false;
                                    break;

                                case 5:
                                    rowIndex=3;
                                    break;

                                case 6:
                                    rowIndex=3;
                                    break;

                                case 7:
                                    rowIndex=6;

                                    hasProcessedThirdBlockInRow=false;
                                    hasViolationFirstTwoBlocks=false;
                                    hasFirstWithThirdBlockViolate=false;
                                    hasSecondWithThirdBlockViolate=false;

                                    break;

                                case 8:
                                    rowIndex=6;
                                    break;

                                case 9:
                                    rowIndex=6;
                                    break;
                            }
                        }

                        numberOf3x3Processed=0;

                        for (int n=0; n<temp.length;n++ )
                        {
                            if (colCount>=2 && rowCount!=2)
                            {
                                rowCount++;
                                colCount=0;
                                rowIndex++;

                                if (offset==0)
                                {
                                    colIndex=0;
                                }
                                else
                                {
                                    colIndex=offset;
                                }

                                if (colIndex==8 && numberOf3x3Processed==9)
                                {
                                    colIndex=0;
                                    rowIndex=rowIndex+3;
                                    ReachEndColMiniGrid=true;
                                }

                                if (colIndex!=8 && numberOf3x3Processed==9)
                                {
                                    colIndex=colIndex+1;
                                    rowIndex=0;
                                }
                            }

                            for (int k=0; k<temp[0].length;k++)
                            {
                                numberOf3x3Processed++;

                                if (k==0)
                                {
                                    offset=colIndex;
                                }

                                //System.out.println("--------------------------------------");
                                //System.out.println("Selecting grid (3x3) " + gridNumber +" from : "+ storeRetrieved3x3Grid.length);
                                //System.out.println("Total numbers processed so far: " + totalNumbersProcessed + " out of 81");
                                //System.out.println("Current offset in 9x9 grid: " + offset);
                                //System.out.println("Starting in this col in 9 x 9: " + colIndex);
                                //System.out.println("The current coordinate(3x3):  " + "(" +rowCount +","+ colCount +")");
                                //System.out.println("Following number chosen: " + temp[rowCount][colCount]);
                                //System.out.println("being stored at coordinate(9x9): " + "(" + rowIndex + "," + colIndex +")");
                                //System.out.println("currently processing this from 3 x 3:" + "(" + rowCount + "," +colCount+")");
                                //System.out.println("--------------------------------------\n");

                                sj.add(temp[rowCount][colCount] + "("+rowIndex+","+colIndex+")");

                                nineByNine[rowIndex][colIndex]=temp[rowCount][colCount];

                                realTime9x9Fill(sj.toString());

                                //System.out.println("FILLING BOARD REAL TIME: " + totalNumbersProcessed);
                                //System.out.println("Using entry3x3=" + entry3x3 + " perm=" + perm3x3[entry3x3]);

                                //display9x9();
                                colCount++;
                                colIndex++;

                                if (numberOf3x3Processed==9)
                                {
                                    colCount=0;
                                    rowCount=0;
                                }

                                if (totalNumbersProcessed!=0 && totalNumbersProcessed%9==0)
                                {

                                    ///System.out.println("Numbers processed in 3x3 grid:" + numberOf3x3Processed);

                                    if (numberOf3x3Processed==9)
                                    {
                                        if (!failedRows&& !failedColumns)
                                        {
                                            successfulInputted3x3++;

                                        }
                                    }

                                    gridNumber++;
                                }

                                if (totalNumbersProcessed%81==0)
                                {
                                    completedBoards.put(numComplete9x9Boards,nineByNine);

                                    numAttempts++;
                                    //numAttempts=numAttempts.add(new BigInteger("1"));

                                    if (successfulInputted3x3>maxSuccessfulInputted3x3)
                                    {
                                        maxSuccessfulInputted3x3=successfulInputted3x3;
                                    }

                                    //I adjusted the current suduko board with this value:  numSuccessfulCompletedBoard
                                    System.out.println("\n*********************Current completed sudoku board(s): " + numSuccessfulCompletedBoards + "  out of " + Permutations3x3into9x9 + "  Attempts: " + numAttempts);
                                    System.out.println("RECORDED ENTRIES (ROW VIOLATIONS, includes bi-direction of pairs): " + position);
                                    System.out.println("RECORDED ENTRIES (COL VIOLATIONS, includes bi-direction of pairs): " + positionColumn);
                                    System.out.println("NUMBER ROW BLOCKED SEQUENCES IN EXECUTION (REQUIRED BACK TRACKING): " + numFullViolation);
                                    System.out.println("NUMBER COL BLOCKED SEQUENCES IN EXECUTION (REQUIRED BACK TRACKING): " + numFullViolationColumn);
                                    System.out.println("SUCCESSFUL INPUTTED 3x3 GRIDS ONTO BOARD WITHOUT VIOLATION:  " + successfulInputted3x3);
                                    System.out.println("MAXIMUM INPUTTED SUCCESSFUL 3X3 GRIDS (FROM GRID 1) WITHOUT VIOLATION: " + maxSuccessfulInputted3x3);
                                    System.out.println("Number stored (3 sequence permutation into VIOLATIONS) in col (due error): " + numStoreOccurenceThreeInColumn);
                                    System.out.println("Number stored (3 sequence permutation into VIOLATIONS) in row (due error): " + numStoreOccurenceThreeInRow);
                                    System.out.println("Frequency (2 sequence permutation into ALLOWED) in row (ANYWHERE on board): " + positionAllowed +"\t" +  String.format("%.1f", Double.valueOf(positionAllowed)/Double.valueOf(numAttempts)) + "%");
                                    System.out.println("Frequency (2 sequence permutation into ALLOWED) in col (ANYWHERE on board): " + positionAllowedCol + "\t" +  String.format("%.1f", Double.valueOf(positionAllowedCol)/Double.valueOf(numAttempts)) + "%")
                                    ;

                                    System.out.println("Number stored (3 sequence permutation into ALLOWED) in row (ANYWHERE on board): " + numThreeStreakRow);
                                    System.out.println("Number Stored (3 sequence permutation into ALLOWED) in col (ANYWHERE on board): " + numThreeStreakCol);

                                    //System.out.println("NUMBER COLUMN BACKTRACK: " + numberColBacktrack++);
                                    //System.out.println("NUMBER ROW BACKTRACK: " + numberRowBacktrack++);

                                    totalNumbersProcessed=0;

                                    sj = new StringJoiner(" ");

                                    if (sudokuComplete(failedRows, failedColumns))
                                    {
                                        //NEED TO BE CAREFUL SINCE IT WILL BE INSIDE HERE IF IT EVALUATES TO TRUE
                                        //SUCCESSFUL BOARD
                                    }
                                }

                                totalNumbersProcessed++;
                            }
                        }
                    }
                }

            }while (hasViolatedBoard);

            //while (numComplete9x9Boards.compareTo(numberPossibleBoards)==-1)
        } while (numComplete9x9Boards<numberPossibleBoards);
    }

    public void print9x9Board(String currentStringJoinerFullGrid, int numComplete9x9Boards)
    {
        //System.out.println("STORING: " + currentStringJoinerFullGrid);
        permutationAllBoards.add(currentStringJoinerFullGrid);

        numComplete9x9Boards = permutationAllBoards.size();

        //System.out.println("********************************************************************************");
        //System.out.println("\nThis is your board number " + (numComplete9x9Boards) + " summary: " + currentStringJoinerFullGrid);

        //System.out.println("********************************************************************************");
        count=count+1;
    }

    public void realTime9x9Fill(String history)
    {
        int row=0;
        int col=0;
        int boardValue=0;
        int startLastNumber;

        int rowtoInt=0;
        int coltoInt=0;
        int boardValuetoInt=0;

        if (history.lastIndexOf(" ")==-1)
        {
            row = Character.getNumericValue(history.charAt(2));
            col = Character.getNumericValue(history.charAt(4));
            boardValue= Character.getNumericValue(history.charAt(0));

            formattedBoard [row][col]=boardValue;
        }
        else
        {
            startLastNumber=history.lastIndexOf(" ");
            row = history.charAt((startLastNumber+3));
            col = history.charAt((startLastNumber+5));
            boardValue = history.charAt((startLastNumber+1));

            rowtoInt = Character.getNumericValue(row);
            coltoInt = Character.getNumericValue(col);
            boardValuetoInt= Character.getNumericValue(boardValue);

            formattedBoard [rowtoInt][coltoInt]=boardValuetoInt;
        }

        checkUniqueRows(formattedBoard, rowIndex);
        checkUniqueColumns(formattedBoard, colIndex);
    }

    public void display9x9()
    {
        for (int i=0; i<formattedBoard.length; i++)
        {
            sj1= new StringJoiner(" ");

            for (int j=0; j<formattedBoard[0].length; j++)
            {
                sj1.add(Integer.toString(formattedBoard[i][j]));

            }
            System.out.println(sj1);
        }
    }

    public boolean checkUniqueRows(int[][] nineByNine, int rowIndex)
    {
        columnIndexMatch=0;
        summary1 = new StringJoiner("| ");

        int occurenceNumberRow=0;

        for (int j=0; j<possibleNumbers.length; j++)
        {
            occurenceNumberRow=0;

            for (int i=0; i<nineByNine[0].length; i++)
            {
                if (possibleNumbers[j]==nineByNine[rowIndex][i])
                {
                    occurenceNumberRow++;

                    if (occurenceNumberRow>1 && !failedRows)
                    {
                        failedRows = true;
                    }
                    columnIndexMatch=i;
                }
            }

            //System.out.println("Number: " + possibleNumbers[j] + " has occured: " + occurenceNumberRow +  " times in  row " + rowIndex + " grid number: " + gridNumber);
            //summary1.add("N:" + String.valueOf(possibleNumbers[j]) + "  O:" + String.valueOf(occurenceNumberRow) + "  Row:" + String.valueOf(rowIndex));

            //System.out.println("****CHECKS TO TROUBLESHOOT FATAL ISSUES WITH LOGGING ROW VIOLATION");
            //System.out.println(Arrays.toString(storeRetrieved3x3Grid));
            //System.out.println("occurenceNumberRow: " + occurenceNumberRow);
            //System.out.println("offset: " + offset);
            //System.out.println("Grid: " + gridNumber);
            //System.out.println("totalNumbersProcessed: " + totalNumbersProcessed);
            //System.out.println("columnIndexMatch:" + columnIndexMatch);
            //System.out.println("!hasViolationFirstTwoBlocks (true condition to enter loop): " + !hasViolationFirstTwoBlocks);
            //System.out.println("should be true !hasFirstWithThirdBlockViolate: " + !hasFirstWithThirdBlockViolate);
            //System.out.println("should be true to enter !hasSecondWithThirdBlockViolate: " + !hasSecondWithThirdBlockViolate);

            if (occurenceNumberRow>=2)
            {
                for (int i=0; i<nineByNine[0].length; i++)
                {
                    if (possibleNumbers[j]==nineByNine[rowIndex][i])
                    {
                        if (offset==3 && !hasViolationFirstTwoBlocks)
                        {
                            //System.out.println("INSIDE HERE");
                            hasViolationFirstTwoBlocks=true;
                            //System.out.println("CURRENT GRID NUMBER: " + gridNumber);

                            //System.out.println("1Coordinate match: "+possibleNumbers[j] + " " + "[" + rowIndex + "][" + i +"]" + "with " + "[" + rowIndex + "][" + columnIndexMatch +"]");
                            //display9x9();
                            blockedPermutationNumberSequence[position][0]=storeRetrieved3x3Grid[gridNumber-2];
                            blockedPermutationNumberSequence[position][1]=storeRetrieved3x3Grid[gridNumber-1];

                            //System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][0]);
                            //System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][1]);
                            //System.out.println("1Blocked permutation sequence first two blocks in row: " + Arrays.toString(blockedPermutationNumberSequence[position]));

                            position++;

                            blockedPermutationNumberSequence[position][0]=storeRetrieved3x3Grid[gridNumber-1];
                            blockedPermutationNumberSequence[position][1]=storeRetrieved3x3Grid[gridNumber-2];

                            //System.out.println("1Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][0]);
                            //System.out.println("1Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][1]);
                            //System.out.println("3Blocked permutation sequence first two blocks in row reverse: " + Arrays.toString(blockedPermutationNumberSequence[position]));

                            position++;

                            //System.exit(0);
                            break;
                        }

                        if (offset==6  && columnIndexMatch>=offset)
                        {
                            if (!hasFirstWithThirdBlockViolate && i<=2)
                            {
                                hasFirstWithThirdBlockViolate=true;
                                //System.out.println("CURRENT GRID NUMBER: " + gridNumber);
                                //System.out.println("2Coordinate match: "+possibleNumbers[j] + " " + "[" + rowIndex + "][" + i +"]" + "with "
                                //        + "[" + rowIndex + "][" + columnIndexMatch +"]");
                                //display9x9();
                                blockedPermutationNumberSequence[position][0]=storeRetrieved3x3Grid[gridNumber-3];
                                blockedPermutationNumberSequence[position][1]=storeRetrieved3x3Grid[gridNumber-1];
                                //System.out.println("2Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][0]);
                                //System.out.println("2Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][1]);
                                //System.out.println("2Blocked permutation sequence first with third block in row : " + Arrays.toString(blockedPermutationNumberSequence[position]));

                                position++;

                                blockedPermutationNumberSequence[position][0]=storeRetrieved3x3Grid[gridNumber-1];
                                blockedPermutationNumberSequence[position][1]=storeRetrieved3x3Grid[gridNumber-3];
                                //System.out.println("3Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][0]);
                                //System.out.println("3Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][1]);
                                //System.out.println("2Blocked permutation first with third block in row reverse sequence: " + Arrays.toString(blockedPermutationNumberSequence[position]));

                                position++;

                                break;
                            }
                            //offset=6 and columnindexmatch>=offset
                            if (!hasSecondWithThirdBlockViolate)
                            {
                                //System.out.println("CURRENT GRID NUMBER: " + gridNumber);
                                //System.out.println("3Coordinate match: "+possibleNumbers[j] + " " + "[" + rowIndex + "][" + i +"]"
                                //       + "with " + "[" + rowIndex + "][" + columnIndexMatch +"]");
                                //display9x9();

                                hasSecondWithThirdBlockViolate=true;
                                blockedPermutationNumberSequence[position][0]=storeRetrieved3x3Grid[gridNumber-2];
                                blockedPermutationNumberSequence[position][1]=storeRetrieved3x3Grid[gridNumber-1];
                                //System.out.println("4Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][0]);
                                //System.out.println("4Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][1]);
                                //System.out.println("2Blocked permutation sequence second with third block in row: " + Arrays.toString(blockedPermutationNumberSequence[position]));
                                position++;

                                blockedPermutationNumberSequence[position][0]=storeRetrieved3x3Grid[gridNumber-1];
                                blockedPermutationNumberSequence[position][1]=storeRetrieved3x3Grid[gridNumber-2];
                                //System.out.println("5Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][0]);
                                //System.out.println("5Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][1]);
                                //System.out.println("2Blocked permutation sequence second with third block in row reverse: "
                                //        + Arrays.toString(blockedPermutationNumberSequence[position]));
                                position++;

                                break;
                            }
                        }
                    }
                    //System.out.println("TROUBLESHOOTING i: " + i);
                }
            }

            //This is sensible to confirm two consecutive blocks are valid
            //We have not developed any system where we can just start the permutation
            //sequences with two valid blocks for instance.
            //If the code struggles to perform backtracking, it might be the only choice
            //We can perhaps

            //there are common conditions in both if conditions, can combine later
            if (totalNumbersProcessed%27==0 && (j==possibleNumbers.length-1)
                    && successfulInputted3x3==2 &&!hasViolationFirstTwoBlocks)
            {
                if (!hasFirstWithThirdBlockViolate)
                {
                    //System.out.println("CURRENT GRID NUMBER: " + gridNumber);
                    allowedPermutationSequenceRow[positionAllowed][0]=storeRetrieved3x3Grid[gridNumber-3];
                    allowedPermutationSequenceRow[positionAllowed][1]=storeRetrieved3x3Grid[gridNumber-1];
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceRow[position][0]);
                    //System.out.println("Storing this into allowed sequence: " + blockedPermutationNumberSequence[position][1]);
                    System.out.println("2Allowed permutation sequence (first and third) in row: " + "(Grid number("+(gridNumber-2)+")," +"Grid number("+(gridNumber)+"),"
                            + " " + Arrays.toString(allowedPermutationSequenceRow[positionAllowed]));
                    positionAllowed++;


                    //System.out.println("CURRENT GRID NUMBER: " + gridNumber);
                    allowedPermutationSequenceRow[positionAllowed][0]=storeRetrieved3x3Grid[gridNumber-1];
                    allowedPermutationSequenceRow[positionAllowed][1]=storeRetrieved3x3Grid[gridNumber-3];
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceRow[position][0]);
                    //System.out.println("Storing this into allowed sequence: " + blockedPermutationNumberSequence[position][1]);
                    System.out.println("2Allowed permutation sequence (third and first) in row: " + "(Grid number("+(gridNumber)+")," +"Grid number("+(gridNumber-2)+"),"
                            + " " + Arrays.toString(allowedPermutationSequenceRow[positionAllowed]));
                    positionAllowed++;
                }

                System.out.println("****CHECKS TO TROUBLESHOOT FATAL ISSUES WITH THIRD BLOCK IN ROW AND PREVIOUS TWO CONFORM TO SUDOKU");
                System.out.println(Arrays.toString(storeRetrieved3x3Grid));
                //System.out.println("occurenceNumberRow: " + occurenceNumberRow);
                //System.out.println("offset: " + offset);
                //System.out.println("Grid: " + gridNumber);
                //System.out.println("columnIndexMatch:" + columnIndexMatch);
                //System.out.println("!hasViolationFirstTwoBlocks (should be true): " + !hasViolationFirstTwoBlocks);
                //System.out.println("***ONE/BOTH OF THE BELOW SHOULD BE FALSE since first two blocks do not violate");
                //System.out.println("!hasFirstWithThirdBlockViolate: " + !hasFirstWithThirdBlockViolate);
                //System.out.println("!hasSecondWithThirdBlockViolate: " + !hasSecondWithThirdBlockViolate);
                //display9x9();

                //System.out.println("CURRENT GRID NUMBER: " + gridNumber);
                allowedPermutationSequenceRow[positionAllowed][0]=storeRetrieved3x3Grid[gridNumber-3];
                allowedPermutationSequenceRow[positionAllowed][1]=storeRetrieved3x3Grid[gridNumber-2];
                //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceRow[position][0]);
                //System.out.println("Storing this into allowed sequence: " + blockedPermutationNumberSequence[position][1]);
                System.out.println("2Allowed permutation sequence (first and second) in row: " + "(Grid number("+(gridNumber-2)+")," +"Grid number("+(gridNumber-1)+"),"
                        + " " + Arrays.toString(allowedPermutationSequenceRow[positionAllowed]));
                positionAllowed++;

                allowedPermutationSequenceRow[positionAllowed][0]=storeRetrieved3x3Grid[gridNumber-2];
                allowedPermutationSequenceRow[positionAllowed][1]=storeRetrieved3x3Grid[gridNumber-3];
                //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceRow[positionAllowed][0]);
                //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceRow[positionAllowed][1]);
                System.out.println("2Allowed permutation sequence (second and first) in row: " + "(Grid number("+(gridNumber-1)+")," +"Grid number("+(gridNumber-2)+"),"
                        + " " + Arrays.toString(allowedPermutationSequenceRow[positionAllowed]));
                positionAllowed++;

                if (!hasSecondWithThirdBlockViolate)
                {
                    //store in allowedPermutationSequenceRow;
                    //System.out.println("CURRENT GRID NUMBER: " + gridNumber);
                    allowedPermutationSequenceRow[positionAllowed][0]=storeRetrieved3x3Grid[gridNumber-2];
                    allowedPermutationSequenceRow[positionAllowed][1]=storeRetrieved3x3Grid[gridNumber-1];
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceRow[positionAllowed][0]);
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceRow[positionAllowed][1]);
                    System.out.println("2Allowed permutation sequence (second and third) in row : " + "(Grid number("+(gridNumber-1)+")," +"Grid number("+(gridNumber)+"),"
                            + " " + Arrays.toString(allowedPermutationSequenceRow[positionAllowed]));
                    positionAllowed++;

                    allowedPermutationSequenceRow[positionAllowed][0]=storeRetrieved3x3Grid[gridNumber-1];
                    allowedPermutationSequenceRow[positionAllowed][1]=storeRetrieved3x3Grid[gridNumber-2];
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceRow[positionAllowed][0]);
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceRow[positionAllowed][1]);
                    System.out.println("2Allowed permutation sequence (third and second) in row : " + "(Grid number("+(gridNumber)+")," +"Grid number("+(gridNumber-1)+"),"
                            + " " + Arrays.toString(allowedPermutationSequenceRow[positionAllowed]));
                    positionAllowed++;
                }

                //This is a consecutive row conforming to suduko
                if (!hasFirstWithThirdBlockViolate && !hasSecondWithThirdBlockViolate)
                {
                    allowedPermutationSequenceRow[positionAllowed][0]=storeRetrieved3x3Grid[gridNumber-3];
                    allowedPermutationSequenceRow[positionAllowed][1]=storeRetrieved3x3Grid[gridNumber-2];
                    allowedPermutationSequenceRow[positionAllowed][2]=storeRetrieved3x3Grid[gridNumber-1];
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceRow[positionAllowed][0]);
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceRow[positionAllowed][1]);
                    System.out.println("Full permitted permutation sequence (first second and third) in row : " + "(Grid number("+(gridNumber-2)+")," +"Grid number("+(gridNumber-1)+"),"+"Grid number("+gridNumber+"),"
                            + " " + Arrays.toString(allowedPermutationSequenceRow[positionAllowed]));
                    display9x9();
                    positionAllowed++;

                    numThreeStreakRow++;

                }

                //hasExecuteOnce=false;
                //displayViolationAllowedBlocks(10000);
                //System.exit(0);
            }

            if (totalNumbersProcessed%27==0 && (j==possibleNumbers.length-1)  && occurenceNumberRow==3 /*&&successfulInputted3x3!=3*/
                    && (!hasViolationFirstTwoBlocks||!hasFirstWithThirdBlockViolate || !hasSecondWithThirdBlockViolate))
            {
                System.out.println("ERROR - not handled violations in row correctly");
                System.out.println("All of these should be false");
                System.out.println("!hasViolationFirstTwoBlocks: " + !hasViolationFirstTwoBlocks);
                System.out.println("!hasFirstWithThirdBlockViolate: " + !hasFirstWithThirdBlockViolate);
                System.out.println("!hasSecondWithThirdBlockViolate: " + !hasSecondWithThirdBlockViolate);


                numStoreOccurenceThreeInRow++;
                System.out.println("storeRetrieved3x3Grid: " + Arrays.toString(storeRetrieved3x3Grid));
                display9x9();
                System.out.println("CURRENT GRID NUMBER: " + gridNumber);
                blockedPermutationNumberSequence[position][0]=storeRetrieved3x3Grid[gridNumber-3];
                blockedPermutationNumberSequence[position][1]=storeRetrieved3x3Grid[gridNumber-2];
                blockedPermutationNumberSequence[position][2]=storeRetrieved3x3Grid[gridNumber-1];
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][0]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][1]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][2]);
                System.out.println("2Blocked permutation sequence entire row: " + "(Grid number("+(gridNumber-2)+")," +"Grid number("+(gridNumber-1)+"),"
                        +   "Grid number("+(gridNumber)+")" + " " + Arrays.toString(blockedPermutationNumberSequence[position]));

                position++;

                blockedPermutationNumberSequence[position][0]=storeRetrieved3x3Grid[gridNumber-3];
                blockedPermutationNumberSequence[position][1]=storeRetrieved3x3Grid[gridNumber-1];
                blockedPermutationNumberSequence[position][2]=storeRetrieved3x3Grid[gridNumber-2];
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][0]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][1]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][2]);
                System.out.println("2Blocked permutation sequence entire row: " + "(Grid number("+(gridNumber-2)+")," +"Grid number("+(gridNumber)+"),"
                        + "Grid number("+(gridNumber-1)+")" + " " + Arrays.toString(blockedPermutationNumberSequence[position]));
                position++;

                blockedPermutationNumberSequence[position][0]=storeRetrieved3x3Grid[gridNumber-2];
                blockedPermutationNumberSequence[position][1]=storeRetrieved3x3Grid[gridNumber-3];
                blockedPermutationNumberSequence[position][2]=storeRetrieved3x3Grid[gridNumber-1];
                System.out.println("2Blocked permutation sequence: " + Arrays.toString(blockedPermutationNumberSequence[position]));
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][0]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][1]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][2]);
                System.out.println("2Blocked permutation sequence entire row: " + "(Grid number("+(gridNumber-1)+")," +"Grid number("+(gridNumber-2)+"),"
                        + "Grid number("+(gridNumber)+")" + " " + Arrays.toString(blockedPermutationNumberSequence[position]));
                position++;

                blockedPermutationNumberSequence[position][0]=storeRetrieved3x3Grid[gridNumber-2];
                blockedPermutationNumberSequence[position][1]=storeRetrieved3x3Grid[gridNumber-1];
                blockedPermutationNumberSequence[position][2]=storeRetrieved3x3Grid[gridNumber-3];
                //System.out.println("2Blocked permutation sequence: " + Arrays.toString(blockedPermutationNumberSequence[position]));
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][0]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][1]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][2]);
                System.out.println("2Blocked permutation sequence entire row: " + "(Grid number("+(gridNumber-1)+")," +"Grid number("+(gridNumber)+"),"
                        + "Grid number("+(gridNumber-2)+")" + " " + Arrays.toString(blockedPermutationNumberSequence[position]));
                position++;

                blockedPermutationNumberSequence[position][0]=storeRetrieved3x3Grid[gridNumber-1];
                blockedPermutationNumberSequence[position][1]=storeRetrieved3x3Grid[gridNumber-2];
                blockedPermutationNumberSequence[position][2]=storeRetrieved3x3Grid[gridNumber-3];

                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][0]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][1]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][2]);
                System.out.println("2Blocked permutation sequence entire row: " + "(Grid number("+(gridNumber)+")," +"Grid number("+(gridNumber-1)+"),"
                        + "Grid number("+(gridNumber-2)+")" + " " + Arrays.toString(blockedPermutationNumberSequence[position]));
                position++;

                blockedPermutationNumberSequence[position][0]=storeRetrieved3x3Grid[gridNumber-1];
                blockedPermutationNumberSequence[position][1]=storeRetrieved3x3Grid[gridNumber-3];
                blockedPermutationNumberSequence[position][2]=storeRetrieved3x3Grid[gridNumber-2];
                System.out.println("2Blocked permutation sequence: " + Arrays.toString(blockedPermutationNumberSequence[position]));
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][0]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][1]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberSequence[position][2]);
                System.out.println("2Blocked permutation sequence entire row: " + "(Grid number("+(gridNumber)+")," +"Grid number("+(gridNumber-2)+"),"
                        + "Grid number("+(gridNumber-1)+")" + " " + Arrays.toString(blockedPermutationNumberSequence[position]));
                position++;

                hasExecuteOnce=false;
                displayViolationAllowedBlocks(10000);
                //System.exit(0);
            }
        }

        return failedRows;
    }

    public boolean checkUniqueColumns(int[][] nineByNine, int colIndex)
    {
        summary = new StringJoiner("| ");
        int occurenceNumberCol=0;
        rowIndexMatch=0;

        for (int j=0; j<possibleNumbers.length; j++)
        {
            occurenceNumberCol=0;

            for (int i=0; i<nineByNine.length; i++)
            {
                if (possibleNumbers[j]==nineByNine[i][colIndex])
                {
                    occurenceNumberCol++;

                    if (occurenceNumberCol>1 && !failedColumns)
                    {
                        failedColumns = true;
                    }

                    rowIndexMatch=i;
                }
            }
            //System.out.println("Number: " + possibleNumbers[j] + " has occured: " + occurenceNumberCol +  " times in column " + colIndex + " grid number: " + gridNumber);
            //summary.add("N:" + String.valueOf(possibleNumbers[j]) + "  O:" + String.valueOf(occurenceNumberCol) + "  Col:" + String.valueOf(colIndex));

            if(colIndex==3)
            {
                idx=1;
            }

            if (colIndex==6)
            {
                idx=2;
            }

            if (colIndex==0)
            {
                idx=0;
            }
            //System.out.println("****CHECKS TO TROUBLESHOOT FATAL ISSUES WITH LOGGING COLUMN VIOLATION:");
            //System.out.println(Arrays.toString(storeRetrieved3x3Grid));
            //System.out.println("occurenceNumberCol: " + occurenceNumberCol);
            //System.out.println("!hasFirstWithThirdBlockInColumnViolate[idx]: (should be true to enter loop)"
            // + !hasFirstWithThirdBlockInColumnViolate[idx]);
            //System.out.println("rowIndexMatch: " + rowIndexMatch);
            //System.out.println("grid: " + gridNumber);
            //System.out.println("totalNumbersProcessed: " + totalNumbersProcessed);
            //System.out.println("!hasViolationTwoStandingTopBlocks[idx]: " + "(should be true to enter loop)"
            //+ !hasFirstWithThirdBlockInColumnViolate[idx]);

            if (occurenceNumberCol>=2  &&  !hasFirstWithThirdBlockInColumnViolate[idx])
            {
                for (int i=0; i<nineByNine.length; i++)
                {
                    if (occurenceNumberCol>=2)
                    {
                        if (possibleNumbers[j]==nineByNine[i][colIndex])
                        {
                            if (i<=2)
                            {
                                if (rowIndexMatch>=6)
                                {
                                    //System.out.println("CURRENT GRID NUMBER: " + gridNumber);
                                    //System.out.println("4Coordinate match: "+possibleNumbers[j] + " " + "[" + i + "][" + colIndex +"]" + "with " + "[" + rowIndexMatch + "][" + colIndex +"]");
                                    hasFirstWithThirdBlockInColumnViolate[idx]=true;

                                    blockedPermutationNumberColumnSequence[positionColumn][0]=storeRetrieved3x3Grid[gridNumber-7];
                                    blockedPermutationNumberColumnSequence[positionColumn][1]=storeRetrieved3x3Grid[gridNumber-1];
                                    //display9x9();
                                    //System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][0]);
                                    //System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][1]);

                                    //System.out.println("2Blocked permutation sequence first with third block in column: " + Arrays.toString(blockedPermutationNumberColumnSequence[positionColumn]));
                                    positionColumn++;

                                    blockedPermutationNumberColumnSequence[positionColumn][0]=storeRetrieved3x3Grid[gridNumber-1];
                                    blockedPermutationNumberColumnSequence[positionColumn][1]=storeRetrieved3x3Grid[gridNumber-7];
                                    //System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][0]);
                                    //System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][1]);

                                    //System.out.println("2Blocked permutation sequence first with third block in column reverse sequence: " + Arrays.toString(blockedPermutationNumberColumnSequence[positionColumn]));

                                    positionColumn++;

                                    //System.exit(0);
                                    //break;
                                }

                                else
                                {
                                    if ((rowIndex>=3) && !hasViolationTwoStandingTopBlocks[idx])
                                    {
                                        //System.out.println("CURRENT GRID NUMBER: " + gridNumber);
                                        //System.out.println("5Coordinate match: "+possibleNumbers[j] + " " + "["+i+"]["+colIndex+"]" + "with " + "[" + rowIndexMatch + "][" + colIndex +"]");
                                        //display9x9();
                                        hasViolationTwoStandingTopBlocks[idx]=true;

                                        blockedPermutationNumberColumnSequence[positionColumn][0]=storeRetrieved3x3Grid[gridNumber-4];
                                        blockedPermutationNumberColumnSequence[positionColumn][1]=storeRetrieved3x3Grid[gridNumber-1];

                                        //System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][0]);
                                        //System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][1]);

                                        //System.out.println("1Blocked permutation sequence two standing top blocks at offset: " + offset + " row: " + rowIndex+"  " + Arrays.toString(blockedPermutationNumberColumnSequence[positionColumn]));
                                        positionColumn++;

                                        blockedPermutationNumberColumnSequence[positionColumn][0]=storeRetrieved3x3Grid[gridNumber-1];
                                        blockedPermutationNumberColumnSequence[positionColumn][1]=storeRetrieved3x3Grid[gridNumber-4];
                                        //System.out.println("3Blocked permutation sequence two standing top blocks in reverse: " + Arrays.toString(blockedPermutationNumberColumnSequence[positionColumn]));
                                        positionColumn++;
                                    }
                                }
                            }
                        }
                    }

                    if ((occurenceNumberCol==3||occurenceNumberCol==2) && rowIndexMatch>=6 && !hasSecondWithThirdBlockInColumnViolate[idx])
                    {
                        //System.out.println("STATE CHECK: " + i + " " + hasSecondWithThirdBlockInColumnViolate[idx]);
                        if (i>=6 /*&& !hasSecondWithThirdBlockInColumnViolate[idx] && !hasFirstWithThirdBlockInColumnViolate[idx]*/)
                        {
                            //System.out.println("CURRENT GRID NUMBER: " + gridNumber);
                            //System.out.println("6Coordinate match: "+possibleNumbers[j] + " " +"[" + rowIndexMatch + "][" + colIndex +"]" + " with block above");
                            //display9x9();

                            hasSecondWithThirdBlockInColumnViolate[idx] = true;

                            blockedPermutationNumberColumnSequence[positionColumn][0]=storeRetrieved3x3Grid[gridNumber-4];
                            blockedPermutationNumberColumnSequence[positionColumn][1]=storeRetrieved3x3Grid[gridNumber-1];

                            //System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][0]);
                            //System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][1]);


                            //System.out.println("2Blocked permutation bottom sequence second with third block in column: " + Arrays.toString(blockedPermutationNumberColumnSequence[positionColumn]));
                            positionColumn++;
                            blockedPermutationNumberColumnSequence[positionColumn][0]=storeRetrieved3x3Grid[gridNumber-1];
                            blockedPermutationNumberColumnSequence[positionColumn][1]=storeRetrieved3x3Grid[gridNumber-4];

                            //System.out.println("2Blocked permutation sequence second with third block in column reverse: " + Arrays.toString(blockedPermutationNumberColumnSequence[positionColumn]));
                            positionColumn++;

                            //System.exit(0);
                            break;
                        }
                    }
                }
            }

            //similar structure as rows to create allowed permutation column blocks
            //there are common conditions in both if conditions, can combine later
            //We need to process this check once it has completed each grid individually
            //on bottom row (gridnumber4, 5 and 6)

            if ((totalNumbersProcessed==63 || totalNumbersProcessed==72 || totalNumbersProcessed==81)
                    && (j==possibleNumbers.length-1)
                /*successfulInputted3x3==2*/)
            {
                System.out.println("****CHECKS TO TROUBLESHOOT FATAL ISSUES WITH THIRD BLOCK IN COL AND PREVIOUS TWO CONFORM TO SUDOKU");
                System.out.println(Arrays.toString(storeRetrieved3x3Grid));
                //System.out.println("occurenceNumberCol: " + occurenceNumberCol);
                //System.out.println("offset: " + offset);
                //System.out.println("Grid: " + gridNumber);
                //System.out.println("totalNumbersProcessed: " + totalNumbersProcessed);
                //System.out.println("rowIndexMatch:" + rowIndexMatch);
                //System.out.println("!hasViolationTwoStandingTopBlocks[idx] (should be true): " + !hasViolationTwoStandingTopBlocks[idx]);
                //System.out.println("***ONE/BOTH OF THE BELOW SHOULD BE FALSE since first two blocks do not violate");
                //System.out.println("!hasFirstWithThirdBlockInColumnViolate: " + !hasFirstWithThirdBlockInColumnViolate[idx]);
                //System.out.println("!hasSecondWithThirdBlockInColumnViolate: " + !hasSecondWithThirdBlockInColumnViolate[idx]);
                //display9x9();

                if(!hasViolationTwoStandingTopBlocks[idx])
                {

                    //System.out.println("CURRENT GRID NUMBER: " + gridNumber);
                    allowedPermutationSequenceCol[positionAllowedCol][0]=storeRetrieved3x3Grid[gridNumber-7];
                    allowedPermutationSequenceCol[positionAllowedCol][1]=storeRetrieved3x3Grid[gridNumber-4];
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceCol[positionAllowedCol][0]);
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceCol[positionAllowedCol][1]);
                    System.out.println("2Allowed permutation sequence (first and second) in col: " + "(Grid number("+(gridNumber-6)+")," +"Grid number("+(gridNumber-3)+"),"
                            + " " + Arrays.toString(allowedPermutationSequenceCol[positionAllowedCol]));
                    positionAllowedCol++;

                    allowedPermutationSequenceCol[positionAllowedCol][0]=storeRetrieved3x3Grid[gridNumber-4];
                    allowedPermutationSequenceCol[positionAllowedCol][1]=storeRetrieved3x3Grid[gridNumber-7];
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceCol[positionAllowedCol][0]);
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceCol[positionAllowedCol][1]);
                    System.out.println("2Allowed permutation sequence (second and first) in col: " + "(Grid number("+(gridNumber-3)+")," +"Grid number("+(gridNumber-6)+"),"
                            + " " + Arrays.toString(allowedPermutationSequenceCol[positionAllowedCol]));
                    positionAllowedCol++;
                }

                if (!hasFirstWithThirdBlockInColumnViolate[idx])
                {
                    //System.out.println("CURRENT GRID NUMBER: " + gridNumber);
                    allowedPermutationSequenceCol[positionAllowedCol][0]=storeRetrieved3x3Grid[gridNumber-7];
                    allowedPermutationSequenceCol[positionAllowedCol][1]=storeRetrieved3x3Grid[gridNumber-1];
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceCol[positionAllowedCol][0]);
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceCol[positionAllowedCol][1]);
                    System.out.println("2Allowed permutation sequence (first and third) in col : " + "(Grid number("+(gridNumber-6)+")," +"Grid number("+(gridNumber)+"),"
                            + " " + Arrays.toString(allowedPermutationSequenceCol[positionAllowedCol]));
                    positionAllowedCol++;

                    allowedPermutationSequenceCol[positionAllowedCol][0]=storeRetrieved3x3Grid[gridNumber-1];
                    allowedPermutationSequenceCol[positionAllowedCol][1]=storeRetrieved3x3Grid[gridNumber-7];
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceCol[positionAllowedCol][0]);
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceCol[positionAllowedCol][1]);
                    System.out.println("2Allowed permutation sequence (third and first) in col : " + "(Grid number("+(gridNumber)+")," +"Grid number("+(gridNumber-6)+"),"
                            + " " + Arrays.toString(allowedPermutationSequenceCol[positionAllowedCol]));
                    positionAllowedCol++;
                }

                if (!hasSecondWithThirdBlockInColumnViolate[idx])
                {
                    //store in allowedPermutationSequenceRow;
                    //System.out.println("CURRENT GRID NUMBER: " + gridNumber);
                    allowedPermutationSequenceCol[positionAllowedCol][0]=storeRetrieved3x3Grid[gridNumber-4];
                    allowedPermutationSequenceCol[positionAllowedCol][1]=storeRetrieved3x3Grid[gridNumber-1];
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceCol[positionAllowedCol][0]);
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceCol[positionAllowedCol][1]);
                    System.out.println("2Allowed permutation sequence (second and third) in col : " + "(Grid number("+(gridNumber-3)+")," +"Grid number("+(gridNumber)+"),"
                            + " " + Arrays.toString(allowedPermutationSequenceCol[positionAllowedCol]));
                    positionAllowedCol++;

                    allowedPermutationSequenceCol[positionAllowedCol][0]=storeRetrieved3x3Grid[gridNumber-1];
                    allowedPermutationSequenceCol[positionAllowedCol][1]=storeRetrieved3x3Grid[gridNumber-4];
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceCol[positionAllowedCol][0]);
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceCol[positionAllowedCol][1]);
                    System.out.println("2Allowed permutation sequence (third and second) in col : " + "(Grid number("+(gridNumber)+")," +"Grid number("+(gridNumber-3)+"),"
                            + " " + Arrays.toString(allowedPermutationSequenceCol[positionAllowedCol]));
                    positionAllowedCol++;

                    //hasExecuteOnce=false;
                    displayViolationAllowedBlocks(10000);
                    //System.exit(0);
                }

                //This is a consecutive col conforming to suduko
                if (!hasFirstWithThirdBlockInColumnViolate[idx] && !hasSecondWithThirdBlockInColumnViolate[idx])
                {
                    allowedPermutationSequenceRow[positionAllowed][0]=storeRetrieved3x3Grid[gridNumber-7];
                    allowedPermutationSequenceRow[positionAllowed][1]=storeRetrieved3x3Grid[gridNumber-4];
                    allowedPermutationSequenceRow[positionAllowed][2]=storeRetrieved3x3Grid[gridNumber-1];
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceRow[positionAllowed][0]);
                    //System.out.println("Storing this into allowed sequence: " + allowedPermutationSequenceRow[positionAllowed][1]);
                    System.out.println("Full permitted permutation sequence (first second and third) in col : " + "(Grid number("+(gridNumber-6)+")," +"Grid number("+(gridNumber-3)+")," +"Grid number("+gridNumber+"),"+
                            " " + Arrays.toString(allowedPermutationSequenceRow[positionAllowed]));
                    display9x9();
                    positionAllowedCol++;
                    numThreeStreakCol++;
                }

                //hasExecuteOnce=false;
                //displayViolationAllowedBlocks(10000);
                //System.exit(0);
            }
            //*****************************

            if ((totalNumbersProcessed==63 || totalNumbersProcessed==72 || totalNumbersProcessed==81) && (j==possibleNumbers.length-1)
                    && occurenceNumberCol==3
                    && (!hasSecondWithThirdBlockInColumnViolate[idx]||!hasFirstWithThirdBlockInColumnViolate[idx] ||!hasViolationTwoStandingTopBlocks[idx]))
            {
                System.out.println("ERROR - not handled violations in column correctly");
                System.out.println("**All of these should be false");
                System.out.println("!hasSecondWithThirdBlockInColumnViolate[idx]: " + !hasSecondWithThirdBlockInColumnViolate[idx]);
                System.out.println("!hasFirstWithThirdBlockInColumnViolate[idx]: " + !hasFirstWithThirdBlockInColumnViolate[idx]);
                System.out.println("!hasViolationTwoStandingTopBlocks[idx]: " + !hasViolationTwoStandingTopBlocks[idx]);


                System.out.println("CURRENT GRID NUMBER: " + gridNumber);
                System.out.println("storeRetrieved3x3Grid:" + Arrays.toString(storeRetrieved3x3Grid));
                display9x9();
                numStoreOccurenceThreeInColumn++;

                blockedPermutationNumberColumnSequence[positionColumn][0]=storeRetrieved3x3Grid[gridNumber-7];
                blockedPermutationNumberColumnSequence[positionColumn][1]=storeRetrieved3x3Grid[gridNumber-4];
                blockedPermutationNumberColumnSequence[positionColumn][2]=storeRetrieved3x3Grid[gridNumber-1];
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][0]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][1]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][2]);
                System.out.println("2Blocked permutation in column sequence: " + Arrays.toString(blockedPermutationNumberColumnSequence[positionColumn]));
                positionColumn++;

                blockedPermutationNumberColumnSequence[positionColumn][0]=storeRetrieved3x3Grid[gridNumber-7];
                blockedPermutationNumberColumnSequence[positionColumn][1]=storeRetrieved3x3Grid[gridNumber-1];
                blockedPermutationNumberColumnSequence[positionColumn][2]=storeRetrieved3x3Grid[gridNumber-4];
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][0]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][1]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][2]);
                System.out.println("2Blocked permutation in column sequence: " + Arrays.toString(blockedPermutationNumberColumnSequence[positionColumn]));
                positionColumn++;

                blockedPermutationNumberColumnSequence[positionColumn][0]=storeRetrieved3x3Grid[gridNumber-4];
                blockedPermutationNumberColumnSequence[positionColumn][1]=storeRetrieved3x3Grid[gridNumber-7];
                blockedPermutationNumberColumnSequence[positionColumn][2]=storeRetrieved3x3Grid[gridNumber-1];
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][0]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][1]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][2]);
                System.out.println("2Blocked permutation in column sequence: " + Arrays.toString(blockedPermutationNumberColumnSequence[positionColumn]));
                positionColumn++;

                blockedPermutationNumberColumnSequence[positionColumn][0]=storeRetrieved3x3Grid[gridNumber-4];
                blockedPermutationNumberColumnSequence[positionColumn][1]=storeRetrieved3x3Grid[gridNumber-1];
                blockedPermutationNumberColumnSequence[positionColumn][2]=storeRetrieved3x3Grid[gridNumber-7];
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][0]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][1]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][2]);
                System.out.println("2Blocked permutation in column sequence: " + Arrays.toString(blockedPermutationNumberColumnSequence[positionColumn]));
                positionColumn++;

                blockedPermutationNumberColumnSequence[positionColumn][0]=storeRetrieved3x3Grid[gridNumber-1];
                blockedPermutationNumberColumnSequence[positionColumn][1]=storeRetrieved3x3Grid[gridNumber-4];
                blockedPermutationNumberColumnSequence[positionColumn][2]=storeRetrieved3x3Grid[gridNumber-7];
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][0]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][1]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][2]);
                System.out.println("2Blocked permutation in column sequence: " + Arrays.toString(blockedPermutationNumberColumnSequence[positionColumn]));
                positionColumn++;

                blockedPermutationNumberColumnSequence[positionColumn][0]=storeRetrieved3x3Grid[gridNumber-1];
                blockedPermutationNumberColumnSequence[positionColumn][1]=storeRetrieved3x3Grid[gridNumber-7];
                blockedPermutationNumberColumnSequence[positionColumn][2]=storeRetrieved3x3Grid[gridNumber-4];
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][0]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][1]);
                System.out.println("Storing this into blocked violation sequence: " + blockedPermutationNumberColumnSequence[positionColumn][2]);
                System.out.println("2Blocked permutation in column sequence: " + Arrays.toString(blockedPermutationNumberColumnSequence[positionColumn]));
                positionColumn++;

                hasExecuteOnce=false;
                displayViolationAllowedBlocks(10000);
                //System.exit(0);
            }
        }
        return failedColumns;
    }

    public boolean sudokuComplete(boolean duplicateNumbersRow, boolean duplicateNumbersCol)
    {
        gridNumber=1;
        uniqueEntries=0;


        numberOf3x3Processed=0;
        pos=0;
        marker=0;
        m=0;

        hasFirstWithThirdBlockInColumnViolate=new boolean[3];

        hasProcessedThirdBlockInRow=false;
        hasViolationFirstTwoBlocks=false;
        hasFirstWithThirdBlockViolate=false;
        hasSecondWithThirdBlockViolate=false;

        //Given the code logic, since the fourth grid will overspill into two rows or two columns
        //it is not possible to know the starting grid. So difficult to place in the Allowed array.
        //But for now, displaying information on screen suffices.
        if (successfulInputted3x3>3)
        {
            System.out.println("***Successful: " + successfulInputted3x3 + "consecutive permutation numbers" );
            display9x9();
            System.out.println(Arrays.toString(storeRetrieved3x3Grid));
        }

        successfulInputted3x3=0;


        if (duplicateNumbersRow || duplicateNumbersCol)
        {
            //System.out.println("**************************");
            System.out.println("Better luck next time, failed on board attempt:" + count + "\nPermutations selected: (" + Arrays.toString(storeRetrieved3x3Grid)+")" + " minimum: "+ minimum + " maximum:" + maximum);

            //display9x9();

            hasExecuteOnce=false;
            //displayViolationAllowedBlocks(10000);

            storeRetrieved3x3Grid=new int[9];
            wipe9x9Board(formattedBoard,nineByNine);

            copyStoreRetrieved3x3Grid=new int[9];
            copyStoreRetrieved3x3GridColumn=new int[9];
            //System.out.println("**************************");

            //Not sure this method even works
            //print9x9Board(sj.toString(), numComplete9x9Boards);

            System.out.println("Moving onto Board Number: " + numComplete9x9Boards);

            failedRows=false;
            failedColumns=false;

            return false;
        }
        else
        {
            System.out.println("**************************");
            System.out.println("\nCongratulations, sudoku complete on board: " + count + " Permutations selected: (" + Arrays.toString(storeRetrieved3x3Grid)+")");
            System.out.println("Complete solution:" + sj.toString());
            System.out.println("**************************");

            display9x9();

            hasExecuteOnce=false;
            displayViolationAllowedBlocks(10000);

            wipe9x9Board(formattedBoard,nineByNine);

            copyStoreRetrieved3x3Grid=new int[9];
            copyStoreRetrieved3x3GridColumn=new int[9];

            System.out.println("Moving onto Board Number: " + numComplete9x9Boards);

            failedRows=false;
            failedColumns=false;

            numSuccessfulCompletedBoards++;

            storeRetrieved3x3Grid=new int[9];

            //System.exit(0);
            return true;
        }
    }
}

public class Permutation
{
    public static void main(String[] args)
    {
        System.out.println("Welcome to Online IDE!! Happy Coding :)");
        int originalNumber=9;
        int n=originalNumber;
        int r =9;
        Map <Integer, Long> m = new HashMap<>();
        System.out.println("***PERMUTATIONS***");
        System.out.println("P(n,r) = n! / (n−r)!");
        System.out.println("P(" + n+","+r+") = " + n+"!" + " / " + "("+n+"-"+r+")!");

        String Permutations3x3into9x9="108,883,584,818,776,183,656,945,007,213,012,309,135,068,193,536,000";
        String sudokuSolutions = "6,670,903,752,021,072,936,960";

        Sudoku sud = new Sudoku (Permutations (n,r,originalNumber, m),Permutations3x3into9x9);
    }

    public static long Permutations (int n, int r, int originalNumber, Map factorialResults)
    {
        long result=0;
        int temp;
        int denominator;

        if (originalNumber<r || r<0)
        {
            System.out.println("please enter n ≥ r ≥ 0");
            System.exit(0);
            return 0;
        }

        if (n>=1)
        {
            result = (n* (Permutations (n-1, r,originalNumber, factorialResults)));
            factorialResults.put(n,result);

            if (n==originalNumber)
            {
                denominator = originalNumber-r;

                if (factorialResults.containsKey(denominator))
                {
                    return result / (long)factorialResults.get(denominator);
                }
            }
            return result;
        }
        return 1;
    }
}