/*
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.*;

public class Main
{
    static int executions; // number executions
    static int temp;  //used when switching position of numbers
    static int[] ascending = new int[4];   //it is set to 4 since this is requirements..
    static int[] descending = new int[4];  //it is set to 4 since this is requirements..
    static int count=1;  //it is used to create offset for index to store ascending and descending numbers
    static int subtraction; // performs subtraction (ascending - descending)
    
    static StringJoiner sj = new StringJoiner("");  
    //conversion, used to store each ascending number.
    //There is no delimiter since the numbers received from Integer array are required in contiguous block such as 1234
    
    static StringJoiner sj1 = new StringJoiner("");
    //conversion, used to store each ascending number.
    //There is no delimiter since the numbers received from Integer array are required in contiguous block such as 1234
    
    static int lastDigit=0;  // when %10 can not be performed in recursive call, it will be the last digit.
    
    static int N=0001;  //as per requirements, ensure it has at least two different unique numbers...
    
    
    public static void main(String[] args) 
    {
        System.out.println("Welcome to Online IDE!! Happy Coding :)");
        
        
        //This will return value of number executions...
        //it does not need to keep track of descending numbers since once the ascending number is
        //calculated, it will reverse the numbers...
        
        System.out.println("Number executions:" + KaprekarConstant(N, ascending));
        
    }
    
    public static int KaprekarConstant(int number, int[] ascending)
    {
        if ((number/10)==0)    //this is expected once the number is only 1 digit long
                               //so it is not divisible by 10 and there will be 0 remainder upon attempting division
        {
            executions++;  //executions only occurs here since we know that this phase will occur exactly
                           //once EACH time the 4 digit number is reduced to 1 digit...
                           
            ascending[0]=number;  //at this point, it sets this digit in first position of ascending array.
                                  // This location will not overwrite any content since I populated array from right to left
                                  //with the other 3 digits
                                  
            //critical testing to ensure that 4 numbers are in ascending array
            //System.out.println("current: " + Arrays.toString(ascending));
            
            //this will progress through the ascending array which has all 4 numbers populated...
            //note this execution will occur for whole length and only once..
            //if there was a number such as  8235
            //this has occured because 235 is sorted in ascending order...
            //But ascending[0] has been filled with remaining last digit.
            //There is only one number that needs to be sorted (at ascending[0])
            //it would always reach the correct location..
            // 8,2,3,5 =>  2,8,3,5  => 2,3,8,5 => 2,3,5,8 
            
            //if number was 2235 or 1235, it would require no adjustment...
            
            //if number was 2345
            //4,2,3,5 =>  2,4,3,5 => 2,3,4,5 
            //it is guaranteed to finish in maximum 3 moves, hence the k=0, k=1 and k=2
            
            for (int k=0; k<(ascending.length-1); k++)
            {
                //if the current value is greater than the next adjacent on right....
                //it needs to reverse order since numbers should be increasing...
                if (ascending[k]>ascending[k+1])
                {
                    //keeps a backup of the next adjacent.
                    temp=ascending[k+1];
                    
                    //the adjacent number takes value of current position.
                    ascending[k+1]=ascending[k];
                    
                    //current position takes value from adjacent position...
                    ascending[k]=temp;
                    
                }
            }
            
            //critical testing to ensure that number is ascending..
            //System.out.println("end: " + Arrays.toString(ascending));
            
            //instead of applying full same logic above, the numbers can be reversed
            //in order to give the descending array.
            
            //moves forward direction in ascending array...
            for (int m=0;m<ascending.length;m++)
            {
                //the smallest number from ascending array (most left hand side)
                //will be on most right hand side on the descending array.
                //descending[(descending.length-1)-m   is at highest position when m=0....
                
                descending[(descending.length-1)-m]=ascending[m];
                
            }
            
            //procesing all integers from the ascending array
            for (int p: ascending)
            {
                //populating into a StringJoiner with no delimiters...
                sj.add(String.valueOf(p));
            }
            
            //procesing all integers from the descending array
            for (int p: descending)
            {
                //populating into a StringJoiner with no delimiters...
                sj1.add(String.valueOf(p));
                
            }
            
            //Tried several conversions such as intValue, Integer.valueOf,  Integer.parseInt()
            //although it failed, it still made it extremely difficult to perform subtraction
            //unless a contiguous block of numbers was available.
            //Only option avaialble was creating a String from Integer array or 
            //a StringJoiner directly integer array and processing this as a String
            
            //and fortunately found a subtraction method in java.Math  which performs subtraction..    
            
            //useful check
            //System.out.println(sj.toString());
            //System.out.println(sj1.toString());
        
            int subtraction = Math.subtractExact(Integer.valueOf(sj1.toString()), Integer.valueOf(sj.toString()));
            
            //Only significant screen output showing the subtraction...
            System.out.println((sj1.toString() + "-" + (sj.toString() + "=" + subtraction)));
            
            //if it hits the value Kaprekar's constant, it returns number executions....
            if (subtraction==6174)
            {
                return executions;
            }
            
            //otherwise, it starts process again (recursive method call in which it takes the existing number
            //it puts digits into ascending order and also descending order.
            //and performs subtraction.. It continues until it reaches total of 6174
            
            else
            {
                count=1;   //default value.
                
                //resets all significant variables..
                //important due to static nature...
                sj=new StringJoiner("");
                sj1=new StringJoiner("");
                
                //although this does get populated completely, 
                // before numbers are adjusted based on ascending, its best just to clear the values...
                ascending = new int[4];
                descending = new int[4]; 
                
                //performs recursive method call
                //this time the number passed is subtraction.
                return KaprekarConstant(subtraction, ascending);
                
            }
            
        }
        
        //These line downwards are actually the main core the code...
        //it would not be here if there is a single digit remaining..
        
        //if the initial number is 1234,   then 1234%10 would be 4   (since 123 x 10 = 1230)
        //if the next initial number is 123,   then 123%10 would be 3   (since 12 x 10 = 120)
        //if the next initial number is 12,   then 12%10 would be 2   (since 1 x 10 = 1)
        //It can be seen that all digits apppear above (4,3,2)  and final is  
        //ascending[0]=number, the remaining single digit...
        
        lastDigit=number%10;
        
        //as mentioned before the numbers are populated from ascending[3] => ascending[1]
        //this vacates ascending[0] for last digit...
        ascending[(ascending.length-count)]=lastDigit;
        
        
        //this is now performing the sort....
        //note it can be performed from left to right  OR right to left
        
        //LEFT TO RIGHT (MOVEMENT FOR HIGHER NUMBERS)  (it performs three times rows here maximum)
        // 4,1,3,2 =>  1,4,3,2 => 1,3,4,2 =>  1,3,2,4
        //1,3,2,4  =>  1,2,3,4  (SOLUTION)
        
        //RIGHT TO LEFT  (HIGHER NUMBERS STAY TO RIGHT) (it performs three times rows here maximum)
        // 4,1,3,2 =>  4,1,2,3 =>  1,4,2,3
        // 1,4,2,3 =>  1,2,4,3 =>
        // 1,2,4,3 =>  1,2,3,4  (SOLUTION)
        
        //once it reaches last digit, it inserts it at the front.
        //it adds digit at front and performs a single path through the array.
        
        //in reality the above example should have been demonstrated with 3 digits only...
        
        //moves from right to left and performs sort... both directions viable..
        for (int k=(ascending.length-1); k>0; k--)
        {
            //if right is less than left.. This would be incorrect for ascending numbers...
            if (ascending[k]<ascending[k-1])
            {
                //stores previous value in temp.
                temp=ascending[k-1];
                
                //previous value is the current value
                ascending[k-1]=ascending[k];
                
                //current value is assigned previous value
                ascending[k]=temp;
                
            }
            
        }
        
        count++;  //increment count
        //count is used to set correct index to store the lastdigit.
        
        //three values are being passed here..
        
        //number/10 is the remaining part of the number... it drops off the last digit...
        //for instance   integer of  1234 /10   = 123
        //               integer of  123 /10   = 12
        //               integer of  12 /10   = 1
        //it now becomes subject to                    if ((number/10)==0) 
                         
        
        //ascending value is the array being populated with lastdigit.
        return KaprekarConstant(number/10, ascending);
    }
    
}