/*
Online Java - IDE, Code Editor, Compiler

Online Java is a quick and easy tool that helps you to build, compile, test your programs online.
*/
//VERSION 3
//return statements again bizarrely do not stop execution.
//Also removed system.exit(0) and set flag to control code flow.
//This code takes logical concepts from Version1 and Version2


//In VERSION1 and VERSION2, accessing number1 and number2 with substring
//In this example  remainingPortionFirstNumber = Integer.toString(number1);
//so it is not sufficient to use int since it will limit length of the number.

//also this is more closer to the first principles used in addition
//the code is much more tider, better variable names
//So I will explain most logic at variable declaration.
//using same test casee.
//Most importantly, it is 100% recursion based.
//I had to force it back into consecutiveNines loop by configuring a flag here..
//I envisage I need to incorporate this into Version1 and Version2 to ensure
//it removes iteration... and also remove do while loop



public class Main
{
    //these variables manage the StopClock
    static long startTime;
    static long endTime;
    static boolean running;
    static long elapsed;
    
    
    static long lastDigitNumber; //this performs %10 on remainingPortion
    
    // this is the (initial number /10) to remove lastDigitNumber
    static long remainingPortion;
    
    static boolean finishedUniformMSD; //it has finished addition of the most MSD
    //common at same position on number1 and number2
    
    //once it has determined grandTotal (remainingPortion is empty)
    static boolean finishedExecution;

    //either 1 or 0 as in real world
    static long carryForward;
    
    //total of the digits
    static long total;
    
    //flag to identify if consecutive nines
    //it affects how the numbers are changed 9=>0 (carryForward=1)
    //or 9=>9 (no carryForward)
    //or 9=>10 (if MSD and carryForward=1)
    static boolean consecutiveNines=false;
   
    //remainingPortionFirstNumber or remainingPortionSecondNumber 
    //are changed to this variable
    //once either remainingPortionSecondNumber==0 
    //or remainingPortionFirstNumber==0
    //i.e it is processing the left non uniform MSD
    //For instance the   remainingPortionFirstNumber= 7 is assigned to number
    //76      number1
    //+8      number2
    static String number;
    
    static String grandTotal; 
    // as you would expect to see in equals
    //section when performing calculation
    //   556 
    //  +733
    //  ------
    //  1289
     // ------
     
    //it keeps backupTotal since it might have filled grandTotal
    //above such as   289 (taking lastDigitTotal=2)  
    //and expecting another.. But if there is not another number,
    //it has to store the backupTotaltotal = 12  to give 1289
    static String backupTotal;
   
    //likewise it stores backupGrandTotal since above grandTotal
    //would be 289 and if it realises 
    //remainingPortionFirstNumber and remainingPortionSecondNumber are 0
    //it would attempt grandTotal = total + grandTotal    = 12289
    //instead it has to re-instate backupGrandTotal = 89
    //perform grandTotal= String.valueOf(backupTotal) + backupGrandTotal  = 12 89
    static String backupGrandTotal;
   
    static long remainingPortionFirstNumber;
    static long remainingPortionSecondNumber;
   
    static int count=0;
   
    static long lastDigitFirstNumber;
    static long lastDigitSecondNumber;
    static long lastDigitTotal;
   
    //doing  4357
         //  + 51
         
    
    public static void start() {
        Main.startTime = System.nanoTime();
        Main.running = true;
    }

    public static void stop() {
        Main.endTime = System.nanoTime();
        Main.running = false;
    }

    public static long getElapsedTime() {
      
        if (running) {
            elapsed = System.nanoTime() - startTime;
        } else {
            elapsed = endTime - startTime;
        }
        return elapsed;
    }

    public static double getElapsedTimeInSeconds() {
        return getElapsedTime() / 1_000_000_000.0;
    }     
         
   
    public static void main(String[] args) {
        System.out.println("Welcome to Online IDE!! Happy Coding :)");
        
           //***PASS****  - 100  need flag and no sys exit
        String number2="99";
        String number1= "1";
        
        //***PASS**1764***   need flag and no sys exit
        //String number2="993";
        //String number1="771";
        
        //PASS*****160****** - 160 need flag and no sys exit
        //String number2 = "136";
        //String number1 =  "24";
        
        //PASS******846370032454542****** need flag and no sys exit
        //String number2 = "846369999999999";
        //String number1 =        "32454543";
        
        //PASS****82160**** need flag and no sys exit
        //String number2 = "81636";   
        //String number1 =   "524";
        
        //PASS******* - 400219 need flag and no sys exit
        //String number2 = "399627";   
        //String number1 =    "592";
        
        //pass********* - 400019  need flag and no sys exit
        //String number2 = "399947";   
        //String number1 =     "72";
        
        //PASS********* getting 4962  need flag and no sys exit 
        //String number2 =   "3970";   
        //String number1 =    "992";
        
        //PASS******  562 need flag and no sys exit
        //String number1 =   "370";   
        //String number2 =   "192";
        
        //PASS**** - getting 1000  need flag and no sys exit
        //String number2 =   "999";   
        //String number1 =     "1";u
        
        //PASS*****  1998  need flag and no sys exit
        //String number1 =   "999";   
        //String number2 =   "999";
        
    
        //***PASS***108  need flag and no sys exit
        //String number1 =   "99";   
        //String number2 =   "9";
    
         //***PASS**** 1400019  need flag and no sys exit
         //String number2 = "1399947";   
         //String number1 =      "72";
         
        //***PASS****5210***  need flag and no sys exit
        //String number2 = "4666";
        //String number1 =  "544";
        
        //***PASS***711****  need flag and no sys exit
        //String number2 =  "652";
        //String number1 =   "59";
        
        //PASS****1390219 *****   need flag and no sys exit
        //String number2 = "1389627";   
        //String number1 =     "592";
        
        //PASS****   need flag and no sys exit
        //String number2 = "1384627";   
        //String number1 =     "592";
        
        //PASS***********22023**** need flag and no sys exit
        //String number1 = "21999";   
        //String number2 =     "24";
        
        //PASS****2******* need flag and no sys exit
        //String number1 = "1";   
        //String number2 = "1";
        
        //PASS***10********, need flag and no sys exit
        //String number1 = "1";   
        //String number2 = "9";
        
        //PASS***95759********,  need flag and no sys exit
        //String number1 = "95427";   
        //String number2 =   "332";
        
        //PASS*****9719******   final test 8 (6+1<10) need flag and no sys exit
        //String number1 = "9647";   
        //String number2 =   "72";
        
        //PASS****100119*******   final test 9 (6+4>=10), needed finishedExecution boolean  , no system exit
        //String number1 = "99647";   
        //String number2 =   "472";
        
        //   **PASS** 10009  final test 11,  hopefully 13 also, needed finishedExecution boolean  , no system exit
        //String number1 ="9947"; 
        //String number2 = "62";
        
        //***PASS  22023,  needed finishedExecution boolean  , no system exit
        //String number1 = "21999";   
        //String number2 =     "24";
        
        //**PASS 108 *** needed finishedExecution boolean  , no system exit
        //String number1 = "99";   
        //String number2 =  "9";
        
        //String number1 = "999999999999999999999999999999999999";
        //String number2 = "324235435345435324234324234324";
        
    //NOW PASS with no system exits
    //String number1 =   "32";   
    //String number2 =   "89";
    
        //NOW PASS ******  562 with no system exits
        //String number1 =   "370";   
        //String number2 =   "192";
        
        //***NOW PASS**1764*** with no system exits
        //String number2="993";
        //String number1="771";
        
        //NOW PASS*****  1998  with no system exits
        //String number1 =   "999";   
        //String number2 =   "999";
           
        start();
        System.out.println("****grand total ******:" + addition(number, number1, number2));
        stop();
        System.out.println("Elapsed time in seconds: " + getElapsedTimeInSeconds());
       
    }
   
    public static String addition (String number, String number1, String number2)
    {
        remainingPortionFirstNumber=Long.valueOf(number1);
        remainingPortionSecondNumber=Long.valueOf(number2);
       
       
       
         if (remainingPortionFirstNumber==0 && !consecutiveNines)
            {
                System.out.println("FORCE 1");
                //generic variables are set on remaining part of number2
               
                remainingPortion=remainingPortionSecondNumber;
                number=number2;   //it assigns the other number to give correct logic
                finishedUniformMSD = true;
            }
           
            if (remainingPortionSecondNumber==0 && !consecutiveNines)
            {
                System.out.println("FORCE ");
                remainingPortion=remainingPortionFirstNumber;
                number=number1;  //it assigns the other number to give correct logic
                finishedUniformMSD = true;
                System.out.println("WHAT ISP: " + remainingPortionFirstNumber);
                System.out.println(grandTotal);
            }
       
          //it can not be above...  both are progressing equally.
         
        if (!finishedUniformMSD)
        {
            System.out.println("this is when the code flows");
            count++;
           
            System.out.println(remainingPortionFirstNumber);
            System.out.println(remainingPortionSecondNumber);
           
            lastDigitFirstNumber = remainingPortionFirstNumber%10;
            System.out.println("This is last digit first number: " +lastDigitFirstNumber);
            lastDigitSecondNumber = remainingPortionSecondNumber%10;
            System.out.println("This is last digit first number: " +lastDigitSecondNumber);
           
            total = lastDigitFirstNumber + lastDigitSecondNumber;
           
            System.out.println(lastDigitFirstNumber +  "+" + lastDigitSecondNumber + "="+total);
            System.out.println("GRAND SO FAR1: " + grandTotal);
            System.out.println(total);
           
            if (grandTotal==null)
                {
                    grandTotal="";
                   
                }
           
           
           
            //it can only do this if the first MSD on either number is not 0.
            //if (!finishedUniformMSD)
           
           
           
                remainingPortionFirstNumber = remainingPortionFirstNumber/10;
                remainingPortionSecondNumber=remainingPortionSecondNumber/10;
                System.out.println("MUST");
           
           
           
            if (total+carryForward>=10 && !finishedExecution)
            {
                System.out.println("OVER");
                System.out.println("WHAT IS LAST DIGIT TOTAL: " + lastDigitTotal);
               
                backupTotal=Long.toString(total+carryForward);
                backupGrandTotal = grandTotal;
                total = total + carryForward;
                System.out.println("TOTAL: " + total);
                System.out.println("TEST: " + 3%10);
                lastDigitTotal = total%10;
                grandTotal = lastDigitTotal + grandTotal;
                carryForward=1;
               
                System.out.println("***GRAND SO FAR: " + grandTotal);
                System.out.println("backup GRAND SO FAR: " + backupGrandTotal);
                System.out.println("backup total SO FAR: " + backupTotal);
               
                addition(number, Long.toString(remainingPortionFirstNumber), Long.toString(remainingPortionSecondNumber));
            }
           
            if (total+carryForward<10 && !finishedExecution)
            {
                System.out.println("UNDER");
               
                backupTotal=Long.toString(total+carryForward);
                backupGrandTotal = grandTotal;
                total= total + carryForward;
                System.out.println("TOTAL: " + total);
                lastDigitTotal = total%10;
                System.out.println("TEST: " + 3%10);
                System.out.println("WHAT IS TOTAL:");
                grandTotal = lastDigitTotal + grandTotal;
                carryForward=0;
               
                System.out.println("GRAND SO FAR: " + grandTotal);
                System.out.println("backup GRAND SO FAR: " + backupGrandTotal);
                System.out.println("backup total SO FAR: " + backupTotal);
               
                addition(number, Long.toString(remainingPortionFirstNumber), Long.toString(remainingPortionSecondNumber));
            }
           
       
           
        }
       
        System.out.println("NOT HERE1");
       
        if (remainingPortionFirstNumber==0 && remainingPortionSecondNumber==0)
        {
            System.out.println("backuptotal: " + backupTotal);
            System.out.println("backupGrandTotal: " + backupGrandTotal);
            System.out.println("grandTotal: " + grandTotal);
           
                grandTotal= String.valueOf(backupTotal) + backupGrandTotal;
           
           
            System.out.println("uniform numbers finished execution: grandtotal: " + grandTotal);
            finishedExecution=true;
            //System.exit(0);
            return grandTotal;
        }
       
       
        //this can be only option when one of the numbers most MSD is not equal to 0
        //hence it completes extra logic
       
        else
        {
       
        System.out.println("NOT HERE2");
        
        if (!finishedExecution)
        {
       
       
       
        //this deals with the non-uniform aspect, until then, it continues normally.
        if (remainingPortionFirstNumber%10 == 0  || remainingPortionSecondNumber==0)
        {
       
        remainingPortion = Long.valueOf(number);
        lastDigitNumber = remainingPortion%10;
       
        System.out.println("remain:"+ remainingPortion);
        System.out.println("last: " + lastDigitNumber);
        System.out.println(carryForward);
        System.out.println(grandTotal);
       
                                             //so 98499 948  
                                      //    +    71   = 9 8500 019
        if (consecutiveNines)
        {
            System.out.println("TIME FOR EXTRA LOGIC");
            System.out.println("CURRERRN grand: " + grandTotal);
            System.out.println("left remaining portion: " + remainingPortion);
            System.out.println(grandTotal);
           
            if (remainingPortion/10==0)
            {
                System.out.println("single nine left");
                //this represents only a single nine left
                //in that case it would take totanotl of it with carry forward
                total = lastDigitNumber + carryForward;
                grandTotal = Long.toString(total)+ grandTotal;
                System.out.println("IJN: " + grandTotal);
                //System.exit(0);
                finishedExecution=true;
                return grandTotal;
            }
           
           
           
            lastDigitNumber = remainingPortion%10;
           
           
           
                if (lastDigitNumber==9)
                {
                    System.out.println("GETS JH");
                total = lastDigitNumber + carryForward;
                lastDigitNumber=total%10;
                grandTotal = lastDigitNumber + grandTotal;
                remainingPortion=remainingPortion/10;
                consecutiveNines=true;
                addition(Long.toString(remainingPortion), number1, number2);
                }
               
                //end of the 9s
                else
                {
                    total = lastDigitNumber + carryForward;
                    grandTotal = total + grandTotal;
                    //shrink value
                    remainingPortion=remainingPortion/10;
                    grandTotal = remainingPortion + grandTotal;
                    System.out.println("finished1");
                    System.out.println(grandTotal);
                    //System.exit(0);
                    finishedExecution=true;
                    return grandTotal;
                   
                }
               
            }
       
        //easiest - done
                                     //so  784308  
                                     //    +   51   = 784359
       
        if (lastDigitNumber+carryForward<10 && !finishedExecution)     //lastdigit = 3
        {
            System.out.println("ldn: " + lastDigitNumber);
            total = lastDigitNumber + carryForward;
            grandTotal = Long.toString(total) + grandTotal;
            System.out.println("grad: " + grandTotal);
           
           
            remainingPortion=remainingPortion/10;
            System.out.println("current remaining check: " + remainingPortion);
           
            if (remainingPortion!=0)
            {
                grandTotal=remainingPortion+grandTotal;
                System.out.println("finished2");
                finishedExecution=true;
                //there is still MSD left
            }
                System.out.println(grandTotal);
                finishedExecution=true;
                //System.exit(0);
                return grandTotal;
        }
       
                //easiest - done
                                     //so  784948  
                                     //    +   71   = 785 019
       
       
         if (lastDigitNumber+carryForward>9 && !finishedExecution)     //lastdigit = 9
        {
                //checks next highest MSD for another 9
                if (remainingPortion%10==9)
                {
                    System.out.println("consecutive nine");
                   
                    //it leaves remainingportion intact
                    //remainingPortion=remainingPortion/10;
                    //but sets flag to handle the situation better.
                    consecutiveNines=true;
                    System.out.println("current grand: " + grandTotal);
                   
                    addition(Long.toString(remainingPortion), number1, number2);
                   
                }
           
            if (lastDigitNumber!=9 && !finishedExecution)
            {
                System.out.println("DDD");
                total = lastDigitNumber + 1;   //carry 1 over
               
                grandTotal = total + grandTotal;
                System.out.println("CURRENT GRAND: " + grandTotal);
               
                //since it has dealt with lastNumber remainingPortion has to remove this
               
                remainingPortion=remainingPortion/10;   //now 78
                System.out.println(remainingPortion);
               
                grandTotal = remainingPortion + grandTotal;
               
                System.out.println("NEW: " + grandTotal);
                 System.out.println("finished3");
            System.out.println(grandTotal);
                //System.exit(0);
                    return grandTotal;
            }
           
                                     //so 98499 948  
                                      //    +    71   = 9 8500 019
           
           if (!finishedExecution)
           {
            System.out.println("curent ggrand: " + grandTotal);
            System.out.println("current remain: " + remainingPortion);
           
            grandTotal=remainingPortion+grandTotal;
            return grandTotal;
           }
        }
       
    }
   
        }
    }  //end of else
   
    return grandTotal;
   
}
   
   
}

