import java.util.Arrays;

public class Main
{
    public static void main(String[] args)
    {
        shiftPeople sp = new shiftPeople();
        sp.leftOrRight();
    }
}

class shiftPeople
{
    boolean isStartZero=false;
    boolean hasMultiplePeople=false;
    boolean hasMinimumSinglePerson=false;
    
    int count=0;
    int distanceLeft=0;
    int distanceRight=0;
    int temp;
    int pos[]=new int[2];
    int singlePersonLocation;
    
    double averageMoves;
    int numberPeopleMovingForAverage;
    
    int[] people = new int[]{0, 1, 0, 0, 1, 0, 1, 0, 0, 1,0,1,0,1,1,0,0,1,0};  
    
    int length=people.length;
    int numberPeople=countPeople();
    
    public int countPeople()
    {
        for (int i=0;i<length; i++)
        {
            if (people[i]==1)
            {
                numberPeople=numberPeople+1;
            }
        }
        return numberPeople;
    }
    
    public shiftPeople()
    {
        int farEnd;
        int start=0;
        String directionMove;
        
        System.out.println("Length of aisle is: " + length);
        System.out.println("Number people is: " + numberPeople);
        System.out.println("This is the original aisle: " + Arrays.toString(people));
        
        System.out.println("A technique of closest neighbouring people from start and end of aisle will determine");
        System.out.println("the verdict (move people left or right)");
        System.out.println("A single person will be favoured movement direction in their closest side");
        System.out.println("****NOTE VERDICT IS NOT ALWAYS CORRECT DECISION");
        
        System.out.println("\n****Calculating proximity of two people from left hand side****");
        farEnd=length;
        
        if(start==0)
        {
            isStartZero=true;
            directionMove="right";
        }
        else
        {
            directionMove="left";
        }
        
        sideToSide(start,farEnd);
        System.out.println("**************MOVING ALL PEOPLE: " + directionMove);
        beginMove(start,farEnd,directionMove);
        
        isStartZero=false;
        
        System.out.println("\n****Calculating proximity of two people from right hand side****");
        start=length-1;
        farEnd=0;
        
        if(start==0)
        {
            isStartZero=true;
            directionMove="right";
        }
        else
        {
            directionMove="left";
        }
        
        sideToSide(start,farEnd);
        System.out.println("**************MOVING ALL PEOPLE: " + directionMove);
        beginMove(start,farEnd,directionMove);
    }
    
    public void sideToSide(int start, int otherEnd)
    {
        for (int i=start;    isStartZero ? i<otherEnd : i>=otherEnd;    i = isStartZero ? i + 1 : i - 1)
        {
            System.out.println("this is value of person " + i + " :" + people[i]);
            
            if (count==2)
            {
                break;
            }
            
            if (people[i]==1)
            {
                pos[count]=i;
                count++;
                
                if (count==1)
                {
                    singlePersonLocation=i;
                    hasMinimumSinglePerson=true;
                }
            }
        }
        
        if (count==2)
        {
            if (start==0)
            {
                distanceLeft = pos[1]-pos[0]-1;
                System.out.println("Distance is:" + distanceLeft + "\n");
            }
            else
            {
                distanceRight = pos[0]-pos[1]-1;
                System.out.println("Distance is:" + distanceRight + "\n");
            }
            hasMultiplePeople=true;
        }
        
        else if (count==1)
        {
            System.out.println("One person in the aisle: " + "(location:" + singlePersonLocation+")");
        }
        
        else
        {
            System.out.println("Empty aisle");
        }
        count=0;
    }
    
    public void leftOrRight()
    {
        if (hasMinimumSinglePerson)
        {
            if (distanceLeft>distanceRight)
            {
                System.out.println("\n******VERDICT: " + "People to move right\n\n");
            }
            else if (distanceRight>distanceLeft)
            {
                System.out.println("\n******VERDICT: " + "People to move left\n\n");
            }
            else
            {
                if (distanceLeft==0 && distanceRight==0 && !hasMultiplePeople)
                {
                    if ((length-1-singlePersonLocation)<singlePersonLocation)
                    {
                        System.out.println("\n******VERDICT: " + "Move single person to right\n\n");
                    }
                    else if (singlePersonLocation-0<(length-1)-singlePersonLocation)
                    {
                        System.out.println("\n******VERDICT: " + "Move single person to left\n\n");
                    }
                    else
                    {
                        System.out.println("\n******VERDICT: " + "no difference moving single left or right\n\n");
                    }
                }
                else
                {
                    System.out.println("\n******VERDICT: " + "no difference moving left or right\n\n");
                }
            }
        }
    }
    
    public boolean checkHasFinished(boolean hasConfirmedFinishedMoving, String directionMove)
    {
        int interestedLocation;
        
        for (int i=0;i<numberPeople;i++)
        {
            if (directionMove=="right")
            {
                interestedLocation=(length-(i+1));
            }
            else
            {
                interestedLocation=i;
            }
            
            if (!(people[interestedLocation]==1))
            {
                hasConfirmedFinishedMoving=false;
            }
        }
        return hasConfirmedFinishedMoving;
    }
    
    public void beginMove(int start, int otherEnd, String directionMove)
    {
        boolean hasFinishedMoving=true;
        boolean hasPersonPrevMove=false;
       //boolean hasPreviousPerson=false;  //chatGPT has phased this code out
       //so I manually commented it out
       
        boolean hasImprovise=false;
        boolean hasIncreasedRowScan=false;
        boolean hasPersonMove=false;
        boolean hasPersonFinishedMoving=true;
        boolean hasPopulatedPreviousPerson=false;
         
      //chatGPT has phased this code out since states are no longer changing to true
       //boolean hasPerformedThis=false;
        
        int numPeopleMoving=0;
        int moves=0;
        int [] original = new int [length];
        int k=0;
        
        System.arraycopy(people, 0, original, 0, length);
        
        int [] recordPersonMoved = new int[50];
        int numberScansRow=0;
        int currentNumberScansRow=0;
        int indexMove;
        int finishPoint=0;
        
        //This was added by chatGPT but it also prevented chatGPT from giving the person finished moving information
        //So once I kept giving chatGPT more instructions, it also did not remove this out
        // =================== NEW CODE ===================
        //boolean[] registeredFinish = new boolean[length]; // tracks positions already printed as finished
        // =================================================
        
        do
        {
            numberScansRow++;
            hasFinishedMoving=true;
            
            for (int i=start;   isStartZero ? i<(otherEnd-1) : i>otherEnd;    i = isStartZero ? i + 1 : i - 1)
            {
                if (directionMove.equals("left"))
                {
                    indexMove=(i-1);
                }
                else
                {
                    indexMove=(i+1);
                }
                 
                if ((people[indexMove]==0) && (people[i]==1))
                {
                    hasPersonMove=true;
                    
                    if (!hasPersonPrevMove && hasPersonMove)
                    {
                        if (i==(length-1))
                        {
                            k=1;
                        }
                        
                        for (int m=0; m<k;m++)
                        {
                            if (i==recordPersonMoved[m])
                            {
                                System.out.println("\n1START POS:  => " + Arrays.toString(people) + "   Position:" + 0 + " - " + "Position:" + (length-1));
                                System.out.println("Same person continuing move at position: " + i);
                                hasPersonFinishedMoving=false;
                                currentNumberScansRow=numberScansRow;
                                break;
                            }
                            
                            else if (m==(k-1))
                            {
                                System.out.println("\n2START POS:  => " + Arrays.toString(people) + "   Position:" + 0 + " - " + "Position:" + (length-1));
                                System.out.println("New Person has commenced movement at position: " + i);
                                hasPersonFinishedMoving=false;
                                numPeopleMoving=numPeopleMoving+1;
                                
                                System.out.println("*************************NUMBER PEOPLE MOVED: " + numPeopleMoving); // changed label
                                currentNumberScansRow=numberScansRow;
                            }
                        }
                        
                        if (k==0 && numberPeople!=0)
                        {
                            System.out.println("\n4START POS:  => " + Arrays.toString(people) + "   Position:" + 0 + " - " + "Position:" + (length-1));
                            System.out.println("New Person has commenced movement at position: " + i);
                            hasPersonFinishedMoving=false;
                            numPeopleMoving=numPeopleMoving+1;
                            System.out.println("*************************NUMBER PEOPLE MOVED: " + numPeopleMoving); // changed label
                                
                            currentNumberScansRow=numberScansRow;
                        }
                    }
                    
                    if (numberScansRow>currentNumberScansRow && !hasPersonFinishedMoving && !hasPopulatedPreviousPerson /*&& !hasPerformedThis*/)
                    {
                        System.out.println("\n3START POS:  => " + Arrays.toString(people) + "   Position:" + 0 + " - " + "Position:" + (length-1));
                        System.out.println("New Person has commenced movement at position: " + i);
                        System.out.println("*************************NUMBER PEOPLE MOVED: " + numPeopleMoving); // changed label
                        hasIncreasedRowScan=true;
                        hasPopulatedPreviousPerson=true;
                    }
                    //hasPerformedThis=false;
                    
                    if (hasPopulatedPreviousPerson)
                    {
                        people[i]=0; 
                        people[indexMove]=1;
            
                        if (!(people[i]==1 && people[i-1]==1))
                        {
                            System.out.println("fin             " + Arrays.toString(people)); 
                            hasImprovise=true;
                        }
                    }
                    
                    people[i]=0; 
                    people[indexMove]=1;
                    moves++;
                    
                    if (!hasIncreasedRowScan && !hasImprovise)
                    {
                        System.out.println("                " + Arrays.toString(people));    
                    }
                    hasIncreasedRowScan=false;
                    hasImprovise=false;
                    
                    hasPersonPrevMove=true;
                }
                
                /*
                else if (hasPersonMove && people[i]!=0)
                {   
                    if (numberScansRow>currentNumberScansRow && currentNumberScansRow!=0)
                    {
                        currentNumberScansRow=numberScansRow;
                        
                        if (directionMove=="right")
                        {
                            finishPoint=(length-1);
                        }
                        else if (directionMove=="left")
                        {
                            finishPoint=0;
                        }
                        
                        System.out.println("PREVIOUS PERSON FINISHED MOVING AT POSITION: " + finishPoint);
                        hasPersonFinishedMoving=true;
                        System.out.println("REGISTERING UNIQUE ID FOR PREVIOUS PERSON MOVED ONTO: " + finishPoint);
                        recordPersonMoved[k]= 0;
                        k++;
                        hasPreviousPerson=true;
                    }
                    else
                    {
                        System.out.println("PERSON FINISHED MOVING AT POSITION: " + i);
                        hasPersonFinishedMoving=true;
                    }
                    
                    hasPersonMove=false;
                    hasPersonPrevMove=false;
                    
                    if (numberScansRow>currentNumberScansRow && currentNumberScansRow!=0)
                    {
                        System.out.println("REGISTERING UNIQUE ID FOR PERSON MOVED ONTO: " + 0);
                    }
                    else
                    {
                        if(!hasPersonFinishedMoving)
                        {
                            System.out.println("PERSON FINISHED MOVING AT POSITION: " + i);
                        }
                        
                        if (hasPreviousPerson)
                        {
                            System.out.println("PERSON FINISHED MOVING AT POSITION: " + i);
                            hasPreviousPerson=false;
                        }
                        
                        System.out.println("REGISTERING UNIQUE ID FOR PERSON MOVED ONTO: " + i);
                    }
                    hasPopulatedPreviousPerson=false;
                    
                    recordPersonMoved[k]= i;
                    k++;
                }
            }
            */
                
                //CHATGPT HAS WRITTEN INFORMATION IN THE ELSE IF BLOCK AGAIN
                //IT HAS MADE REFERENCE TO ARRAY I DEFINED EARLIER recordPersonMoved
                //BUT I STILL FIND THIS EXTREMELY TRICKY TO UNDERSTAND WITH MY EXISTING CODE
                //SINCE I THOUGHT I WAS ACCOUNTABLE FOR THIS INFORMATION ALREADY
                
                else if (hasPersonMove && people[i]!=0)
                {   
                    // =================== NEW BLOCK ===================
                    // print "PERSON FINISHED MOVING" every time the person cannot move further
                    System.out.println("PERSON FINISHED MOVING AT POSITION: " + i);
                    // register the person moved only if not already in record
                    boolean alreadyCounted=false;
                    
                    for(int r=0;r<k;r++)
                    {
                        if(recordPersonMoved[r]==i)
                        {
                            alreadyCounted=true; 
                            break;
                        }
                    }
                    if(!alreadyCounted)
                    {
                        recordPersonMoved[k]=i;
                        k++;
                    }
                    hasPersonMove=false;
                    hasPersonPrevMove=false;
                    // =================================================
                }
            }
            hasFinishedMoving=checkHasFinished(hasFinishedMoving,directionMove);
            
        }while(!hasFinishedMoving);
        
        System.out.println("\n\nTOTAL Number people moved: " + numPeopleMoving); // display actual number of unique people moved
        
            
        System.out.println("\n\n---------------------------------------------------------");
        System.out.println("Total number of moves " +directionMove +": "+ moves);
        System.out.println("FINISHED MOVEMENT:"+ Arrays.toString(people));
        System.out.println("Number people moved for average: " + numPeopleMoving);
        
        averageMoves = (double)moves/(double)numPeopleMoving;
        System.out.println("AVERAGE MOVE PER PERSON: " + averageMoves);
        System.out.println("---------------------------------------------------------");
        
        numPeopleMoving=0;
        
        
        System.arraycopy(original, 0, people, 0, length);
    }
}
