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

import java.util.*; 

public class Main 
{
    static int n=15; // this is number of coins
    static int[] coins = new int[n];  //array storing the coins
    
    
    //this was my desired approach but unfortunately if I did not perform System.exit(0) once it found a single head,
    //the code continued to loop... So I had to comment this since it was unreachable...
    //System.out.println("The number rounds: " + fc.getRounds());
    
    public static void main(String[] args) 
    {
        
        System.out.println("Program to test flipping coins multiple times.");
        System.out.println("All heads to remain. All tails to be removed.");
        System.out.println("Execution ends when one HEAD left");
        System.out.println("");
         
        FlipCoin fc= new FlipCoin(n, coins); // ****instantiate Flipcoin.
        } 
    } 

class FlipCoin 
{
    private int numberCoins;   //numbercoins remaining.
    private int coins[];  //number coins
    
    //enum for keeping values of Heads and Tails..
    //this will be used for random selection...
    //Equally they could have been assigned String values..
    //But in this case the random number would then need index a String array and get String value...
    //since values remain constant in enum, this is ok..
    
    enum Coins
    {
        HEAD (1), TAIL(2);
        
        int value;
        
        //this binds associated value to the enum constants..
        Coins (int value)
        {
            this.value=value;
        }
    }
     
    static int executions=0;  // needs to be static due to repeat instantations and mantaining total..
    
    public FlipCoin(int numberCoins, int[] coins) 
    {
        this.numberCoins=numberCoins;
        this.coins=coins;
    
        System.out.println("number coins right now is:" + numberCoins); 
        
        if (numberCoins==0)
        {
            System.out.println("Enter valid number coins greater than 0 ");
            System.exit(0);
        }
        
        int heads=0;   //count of heads
        int tails=0;   //count of tails    
        
         
        for (int i=0; i<numberCoins;i++) // this will process each coins left..
        {
            Random random = new Random();
            // This will generate numbers 1 & 2. 
            // 1 , WILL BE TAKEN TO BE HEADS 
            // 2,  WILL BE TAKEN TO BE TAILS 
            int rand = random.nextInt(2) + 1; 
           
            coins[i]=rand;   //assigning value
           
            if (coins[i]==Coins.HEAD.value) //ALL HEADS ARE COUNTED 
            { 
                System.out.println (Coins.HEAD.name());  //this gets the name from enum. Taken to be the constant. 
                heads++;  //increments number heads...
                
            } 
            
            if (coins[i]==Coins.TAIL.value) //ALL TAILS ARE COUNTED 
            {
                System.out.println(Coins.TAIL.name()); //this gets the name from enum. Taken to be the constant. 
                tails++;  //increments number tails...
            }
            
        }  //end for loop - processing the coins...
        
   
        
        // This is out of the for loop, once all coins are tossed, it will check the tails.. 
        
        // This is an illegal outcome. Since all tails will be eliminated, which is all coins... 
        if (tails==numberCoins) 
        {
            //However it still is a valid flip..
            executions++;
            
            //information to end user..
            System.out.println("All tossed coins are tails");
            System.out.println("All coins to be re-thrown");
            System.out.println("Number executions:" +  executions);
        
        //method call
        flipCoinsAgain(numberCoins,heads,tails); 
        }  //end of if  where all coins left are tails...
        
        //this is now a case where there are heads and tails remaining....
        else
        {
        
        //if all heads are thrown first time, this is still a valid scenario...
        //need to keep processing until all heads becomes tails..
        //except being that one final head has to remain.
        
        do 
        { 
        
        //it is ready to remove the tails as per requirements..
        numberCoins=numberCoins-tails; 
        
        //it will keep calling this loop until there is more than 1 head remaining.
        if (heads>1) 
        {
            System.out.println("New number of coins: " + numberCoins);
            System.out.println("Number heads remaining: " + (heads));
            executions++;   //incrementing number of executions....
            flipCoinsAgain(numberCoins, heads, tails); // ANY HEADS THAT ARE TOSSED WILL TRIGGER COINS TOSSED AGAIN WITH REVISED NUMBER COINS executions++; //THIS INCREMENTS SINCE ALL APPLICABLE COINS ARE TOSSED AGAIN. 
        
        }
        
        //Also note, the do while loop will end if numberCoins>1
        //the condition below (heads==1) should coincide with this.
        //but when I tried to reduce numberCoins to   numberCoins=numberCoins - tails;  (0),
        //it continued to loop in do while indefinitely...
       
       
        if (heads==1) 
        {
            System.out.println("One head left: " + numberCoins);
            
            executions++;
            
            System.out.println("Number executions:" +  (executions));
           
            //it is ready to remove the tails as per requirements..
            //I tried this and was hoping it would break out of the do while loop
            //and return back to the main method in which I intended to report on executions..
            //but for some reason, it kept looping in the do while loop indefinitely...
            //so only option was to break out of the code...
            //numberCoins=numberCoins-tails; 
            
            //forced to exit
            System.exit(0);
            
        }
        
        }while(numberCoins>1);
        }
        
        //THE WHOLE CYCLE WILL CONTINUE UNTIL 1 COIN IS LEFT WHICH IS HEADS.
        //AS EXPLAINED BEFORE, THE CODE IS NOT TERMINATING ON THE EXIT CONDITION...
        
    }  // end constructor...
    
        //method flip coins again...
        void flipCoinsAgain(int numberCoins, int heads, int tails) 
        {
            System.out.println("\nFlipping ALL coins again");
            System.out.println("Number executions so far:" +  executions);
            
            //important to reset the counter, since previous totals become irrelevant to a new flip...
            //also given that numberCoins has been reduced...        
            heads=0;
            tails=0;
            
           //process coin flips again..
            new FlipCoin(numberCoins, coins);
            
        } 
        
        //didn't end up using the getter as described above...
        int getRounds() 
        {
            return executions; 
            
        } 
        }