/*
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.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

class RepeatDecimalFractions
{
    boolean isPeriodNumber=true;
    String backupFractionalPart;
    long denominator=0;
    
    //used for stop clock
    long startTime;
    long endTime;
    boolean running;
    long elapsed;
    
    long primeNumberCheckLimit;
    long maxGCF;
    long acceptedNumeratorLimit;
    int LIMITPRECISION;
    long numeratorOriginalLong;
    long denominatorOriginalLong;
    String partialEquationTwo;
    boolean singleDigitrecurring;
    String fractionalPart;
    String[] testOne;
    long divisor;
    boolean successReducedNumerator;
    boolean successReducedDenominator;
    boolean isTerminatingDecimal=true;
    List<Long> notPrimeLst = new ArrayList<>();
    List<Long> primeLst = new ArrayList<>();
    int numberConsecutiveDigits=0;
    
    char firstDigit;
      
     //generated this section online via AI  ****************
    public void start() 
    {
        startTime = System.nanoTime();
        running = true;
    }

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

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

    public double getElapsedTimeInSeconds() 
    {
        return getElapsedTime() / 1_000_000_000.0;
    }
    //*******************************************************
    
    public void generateTerminatingNonRepeatFractions()
    {   
        long [] testing = new long[19];
        boolean primeNumber=false;
        long temp;
        long count=0;
        long arraySize = 2147483647;
        long [] noPrimeFactor = new long[21474836];
        long startNum=2;
        
        for (long m=startNum; m<=primeNumberCheckLimit;m++)
        {
            primeNumber=true;
             
            for (long j=2; j<m;j++)
            {
                if (m%j==0 && m>3)
                {
                    System.out.println("is not a prime number: " + m);
                    notPrimeLst.add(m);
                    primeNumber=false;
                    break;
                }
            }
            count++;
            
            if (primeNumber || (m>0 && m<3))
            {
                System.out.println("is a prime number: " + m);
                primeLst.add(m);
            }
        }
        
    }
    
    public boolean reducedNumerator(Long numerator, long divisor)
    {
        if (divisor>numerator)
        {
            return false;
        }
        else
        {
            if (numerator%divisor==0)
            {
                successReducedNumerator = true;
                return successReducedNumerator;
            }
        }
        return false;
    }
    
    public boolean reducedDenominator(long denominator, long divisor)
    {
        if (denominator%divisor==0)
        {
            successReducedDenominator = true;
            return successReducedDenominator;
        }
        return false;
    }
    
    public boolean terminatingDecimal(long primeFactorCheck, long numerator, String decimalOriginal)
    {
        int counter=0;
        isTerminatingDecimal=true;
        List<Long> terminatingDecimalLst = new ArrayList<>();
        boolean primeFactorTwo=false;
        boolean primeFactorFive=false;
        int pos=0;
        String [][] originalDenominatorDividePrime = new String[2000][2];
        String [][]originalDenominatorDivideNonPrime = new String[2000][2];
        double numeratorDividePrimeNumber;
        int numberConsecutiveDigits=0;
        
        Iterator<Long> f = primeLst.iterator();
        
        System.out.println("************************************************");    
        System.out.println("This will just be final part of the code...");
        System.out.println("Since several prime numbers have been generated, I will use the existing numerator");
        System.out.println("And store the results in a String array:   Numerator/prime number AS fraction  and Numerator/prime number AS decimal  and store results.  IT IS TO GET A FEEL OF DIFFERENT PATTERNS AS EXPLORED IN DOCUMENTATION!");
        System.out.println("This will provide a sample should I wish to populate initial array also! ");
        System.out.println("It will also show examples in which repetends have occurred two or more times in the decimal precision ("+LIMITPRECISION+ " digits wide)");
        System.out.println("THIS IS ONLY circumstances available to enhance my code to utilize mapping to fractional equivalent....");
        System.out.println("**************************************************");
        
        while (f.hasNext())
        {
            pos=0;
            long item = f.next();
            counter++;
            
            if (item==2 && primeFactorCheck>=item)
            {
                if (primeFactorCheck%2==0)
                {
                    primeFactorTwo=true;
                }
            }
            
            if (item==5 && primeFactorCheck>=item)
            {
                if (primeFactorCheck%5==0)
                {
                    primeFactorFive=true;
                }
            }
            
            numeratorDividePrimeNumber = (double)(numeratorOriginalLong)/(double)(item);
            
            //************THIS CAN BE TURNED OFF IF REQUIRED, JUST USEFUL FOR GENERATING VALID TEST CASES***********
            originalDenominatorDividePrime[counter][pos] = numeratorOriginalLong + "/" + item;
            originalDenominatorDividePrime[counter][pos+1] = String.valueOf(numeratorDividePrimeNumber);
        
            System.out.println("Original numerator / PRIME number AS FRACTION (not reduced) => " + originalDenominatorDividePrime[counter][pos]);
            System.out.println("Original numerator / PRIME number AS DECIMAL => " +originalDenominatorDividePrime[counter][pos+1]);
            //************THIS CAN BE TURNED OFF IF REQUIRED, JUST USEFUL FOR GENERATING VALID TEST CASES***********
        }
        
        System.out.println("***************************************************");
        System.out.println("CHECK TO SEE IF ORIGINAL FRACTION IS TERMINATING: ");
        
        if ((primeFactorFive || primeFactorTwo))
        {
            System.out.println("Terminating fraction since reduced denominator" + "("+denominator+")" + " has prime factor (divisible by prime number of two or five)");
        }
        else
        {
            System.out.println("Recurring fraction since reduced denominator " + "("+denominator+")" + " is NOT divisble by prime number of two or five");
        }
                
        if (isPeriodNumber)
        {
            System.out.println("Original decimal:" + decimalOriginal + " is a periodic number");
        }
        else
        {
            System.out.println("Original decimal:" + decimalOriginal + " is NOT a periodic number");
        }
        isPeriodNumber=true;
        
        return false;
    }
        
    public void checkRecurrence()
    {
       backupFractionalPart = fractionalPart;
        
        if(fractionalPart.length()>1)
        {
            do
            {
                if (fractionalPart.charAt(0)==fractionalPart.charAt(fractionalPart.length()-1))
                {
                    numberConsecutiveDigits++;
                    singleDigitrecurring = true;
                    fractionalPart=fractionalPart.substring(1);
                    partialEquationTwo = partialEquationTwo + fractionalPart.charAt(0);
                }
                else
                {
                    singleDigitrecurring = false;
                    break;
                }
            }while(fractionalPart.length()>1);
        }
    }
    
    public void fraction(String[] testOne)
    {
        boolean improperFraction=false;
        String temp;
        long posTestOneDecimal=0;
        long posTestOneFraction;
        String numeratorToString="";
        String denominatorToString="";
        String numeratorOriginal="";
        String denominatorOriginal="";
        String decimalOriginal="";
        long denominatorIntoNumerator=0;
        String remainingFraction="";
        String decimalPortionOriginal="";
        int posDecimalPoint;
        
        generateTerminatingNonRepeatFractions();
        
        StringTokenizer st = new StringTokenizer (testOne[0], ",");
        String wholeNumberPortionDecimal;
        String regex="";
        String regexCheck="";
        Pattern pattern = Pattern.compile(regexCheck, Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(numeratorToString);
        
        while (st.hasMoreTokens())
        {
            singleDigitrecurring=false;
            temp= st.nextToken().toString();
            
            posDecimalPoint=temp.indexOf(".");
            decimalOriginal=temp;
            
            posTestOneDecimal++;
            
            System.out.println("\n\n\n*** The Decimal presented: " + temp);
            decimalPortionOriginal = temp.substring(temp.indexOf("."));
            wholeNumberPortionDecimal = temp.substring(0,temp.indexOf("."));
            
            fractionalPart = temp.substring((temp.indexOf(".")+1));
            
            String fractionalPartionWithDecimal = temp.substring((temp.indexOf(".")));
            long numerator = Long.valueOf(fractionalPart);
            
            partialEquationTwo="";
            
            String fullEquationOne=  "0"+fractionalPartionWithDecimal;
            Double equationTwoA;
            String fractionAfterWholeNumber="";
            String wholeNumberBeforeFraction;
            long wholeNumberBeforeFractionLong=0;
            String fractionalPartionWithDecimalString;
            long minNum=0;
            long maxNum=0;
            boolean exitWhileLoop=false;
            long numeratorBackup=0;
            boolean isFractionAfterWholeNumber=false;
            
            //not used in meaningful way.
            //leaving it as a placeholder should I wish to truncate
            //9 digit numerator under certain conditions (see test cases)
            boolean firstDigitNumeratorIllegalRecurring=false;
            
            checkRecurrence();
            fractionalPart=backupFractionalPart;
            
            if (singleDigitrecurring)
            {
                if (numberConsecutiveDigits+1==LIMITPRECISION)
                {
                    System.out.println("Recurring digit occurs: " + LIMITPRECISION + " times");
                    System.out.println("Recurring digit through entire decimal: " + fractionalPart.charAt(0));
                    String fullEquationTwo = fractionalPart.charAt(0) + "." + fractionalPart.charAt(0)+ partialEquationTwo;
                    
                    isPeriodNumber=false;
                        
                    System.out.println("FULL EQUATION ONE: " + fullEquationOne);
                    System.out.println("FULL EQUATION TWO: " + fullEquationTwo);
                    equationTwoA = Double.valueOf(fullEquationTwo) - Double.valueOf(fullEquationOne);
                    System.out.println("FULL EQUATION TWO A: " + equationTwoA);
                    
                    numeratorBackup=numerator;
                    numerator = equationTwoA.longValue();
                    denominator = 9;
                    remainingFraction = numerator + "/" + 9;
                    System.out.println("Fraction of recurring: " + remainingFraction);
                    numerator=numeratorBackup;
                    numberConsecutiveDigits=0;
                }
            }
            long multipliedBy;
            System.out.println("The fraction part:   " + fractionalPart);
            multipliedBy=fractionalPart.length();
            long multipliedByInteger = Long.valueOf(multipliedBy);
            denominator = 1;
            long i=0;
            int count=0;
            
            while (i<multipliedByInteger)
            {
                i++;
            
                if (i<LIMITPRECISION)
                {
                    denominator = denominator * 10;
                }
                else
                {
                    break;
                }
            }
            System.out.println("this is numerator:   " + numerator);
            
            if (multipliedBy==19)
            {
                System.out.println("this is denominator: " + denominator + "0");
            }
            else
            {
                System.out.println("this is denominator: " + denominator);
            }
            
            int numeratorLength=String.valueOf(numerator).length();
            int denominatorLength=String.valueOf(denominator).length();
            
                
            if (numeratorLength>acceptedNumeratorLimit || denominatorLength>acceptedNumeratorLimit)
            {
                
                int digitsAcceptedNumeratorLimit = (int)acceptedNumeratorLimit;
                char firstDigitNum;
                 
                if (singleDigitrecurring)
                {
                    System.out.println("Denominator" + "("+denominator+")" + " considered too large for computation");
                    denominatorToString = String.valueOf(denominator);
                    
                    denominatorToString=denominatorToString.substring(0,digitsAcceptedNumeratorLimit+1);
                    System.out.println("Denominator reduced to " + (digitsAcceptedNumeratorLimit+1) + " digits wide: " + "("+denominatorToString+")" + " due to recurrence numerator");
                    denominator = Long.valueOf(denominatorToString);
                    System.out.println("Truncated denominator: " + denominator);
                    
                    System.out.println("Numerator " + "("+numerator+")" + " considered too large for computation");
                    numeratorToString = String.valueOf(numerator);
                    numeratorToString=numeratorToString.substring(0,digitsAcceptedNumeratorLimit);
                    System.out.println("Numerator truncated to " + digitsAcceptedNumeratorLimit + " digits wide: " + "("+numeratorToString+")" + " due to recurrence numerator");
                    numerator = Long.valueOf(numeratorToString);
                    System.out.println("Truncated numerator:   " + numerator);
                   
                    firstDigitNum = numeratorToString.charAt(0);
                    System.out.println("BACK TO HERE");
                    
                    if(numeratorToString.length()==9)
                    {
                        do
                        {   
                            regex=regex + firstDigitNum;
                            count++;
                        }while(count<numeratorToString.length());
                        
                        regexCheck=regex;
                        System.out.println("2THIS IS THE REGEX TO CHECK FOR POORLY DIVISIBLE NUMERATORS  :" + regexCheck);
                        
                        pattern = Pattern.compile(regexCheck, Pattern.CASE_INSENSITIVE);
                        matcher = pattern.matcher(numeratorToString);
                        
                        System.out.println("2Single digit recurring:" + singleDigitrecurring);
                        
                        if (matcher.find())
                        {
                            if (firstDigitNum=='1' || firstDigitNum=='3' || firstDigitNum=='7' || firstDigitNum=='9' )
                            {
                                numeratorToString = numeratorToString.substring(0,numeratorToString.length()-1);
                                denominatorToString = denominatorToString.substring(0,denominatorToString.length()-1);
                                System.out.println("1Numerator truncated to: " + numeratorToString.length() + " digits " + "("+numeratorToString+")"+" to mitigate resource limitations of recurrence 9 times (1,3,7,9)");
                                System.out.println("2Denominator truncated to: "   + denominatorToString.length() + " digits" + "("+denominatorToString+")"+ " inline with numerator");
                                numerator = Long.valueOf(numeratorToString);
                                denominator = Long.valueOf(denominatorToString);
                                System.out.println("Truncated numerator:   " + numerator);
                                System.out.println("Truncated numerator:   " + denominator);
                                firstDigitNumeratorIllegalRecurring=true;
                            }
                        }  
                    }
                    regex="";
                }
                else
                {
                    denominatorToString = String.valueOf(denominator);
                    numeratorToString = String.valueOf(numerator);
                    int differenceLength = Math.abs(numeratorToString.length() - denominatorToString.length());
                    int differenceNumeratorAndMaxLongPrecision = numeratorToString.length()-digitsAcceptedNumeratorLimit;
                    int differenceDenominatorAndMaxLongPrecision = denominatorToString.length()-digitsAcceptedNumeratorLimit;
                    
                    if (numeratorLength>acceptedNumeratorLimit && denominatorLength>acceptedNumeratorLimit)
                    {
                        digitsAcceptedNumeratorLimit = (int)acceptedNumeratorLimit;
                        
                        if (differenceLength==0)
                        {
                            System.out.println("9Numerator truncated from: " + numeratorToString.length() + " to " + digitsAcceptedNumeratorLimit + " digits");
                            numeratorToString=numeratorToString.substring(0,digitsAcceptedNumeratorLimit);
                            
                            System.out.println("10Denominator truncated from  " + denominatorToString.length() + " to " + (digitsAcceptedNumeratorLimit+1) + " digits:");
                            denominatorToString=denominatorToString.substring(0,digitsAcceptedNumeratorLimit+1);
                        }
                        
                        if (denominatorToString.length()!=(digitsAcceptedNumeratorLimit+1) && numeratorToString.length()!=digitsAcceptedNumeratorLimit && !singleDigitrecurring)
                        {
                            System.out.println("6Numerator truncated from: " + numeratorToString.length() + " to " + digitsAcceptedNumeratorLimit + " digits:");
                            numeratorToString=numeratorToString.substring(0,digitsAcceptedNumeratorLimit);
                            System.out.println("7Denominator truncated from  " + denominatorToString.length() + " to " + (denominatorToString.length()-differenceNumeratorAndMaxLongPrecision) + " digits");
                            denominatorToString=denominatorToString.substring(0,(denominatorToString.length()-differenceNumeratorAndMaxLongPrecision));
                        }
                    } 
                    
                    if (numeratorLength>acceptedNumeratorLimit &&  denominatorLength<acceptedNumeratorLimit)
                    {
                        System.out.println("This is not possible on a decimal. PLEASE CHECK THE LOGIC OF THE CODE");
                    }
                    
                    if (numerator<acceptedNumeratorLimit &&  denominator>acceptedNumeratorLimit+1)
                    {
                        System.out.println("This is not possible on a decimal. PLEASE CHECK THE LOGIC OF THE CODE");
                    }
                    denominator = Long.valueOf(denominatorToString);
                    System.out.println("Truncated denominator: " + denominator);
                    numerator = Long.valueOf(numeratorToString);
                    System.out.println("Truncated numerator:   " + numerator);
                    firstDigitNum = numeratorToString.charAt(0); 
                    
                    System.out.println("2Single digit recurring:" + singleDigitrecurring);
                    
                    if (numeratorToString.length()==9)
                    {
                        do
                        {   
                            regex=regex + firstDigitNum;
                            count++;
                        }while(count<numeratorToString.length());
                        
                        regexCheck=regex;
                        System.out.println("2THIS IS THE REGEX TO CHECK FOR POORLY DIVISIBLE NUMERATORS  :" + regexCheck);
                        
                        pattern = Pattern.compile(regexCheck, Pattern.CASE_INSENSITIVE);
                        matcher = pattern.matcher(numeratorToString);
                        
                        if (matcher.find())
                        {
                            if ((firstDigitNum=='1' || firstDigitNum=='3' || firstDigitNum=='7' || firstDigitNum=='9' ))
                            {
                                numeratorToString = numeratorToString.substring(0,numeratorToString.length()-1);
                                denominatorToString = denominatorToString.substring(0,denominatorToString.length()-1);
                                System.out.println("3Numerator truncated to: " + numeratorToString.length() + " digits " + "("+numeratorToString+")"+" to mitigate resource limitations of recurrence 9 times (1,3,7,9)");
                                System.out.println("4Denominator truncated to: "   + denominatorToString.length() + " digits" + "("+denominatorToString+")"+ "inline with numerator");
            
                                numerator = Long.valueOf(numeratorToString);
                                denominator=Long.valueOf(denominatorToString);
                                firstDigitNumeratorIllegalRecurring=true;
                            }
                        }    
                    }
                    firstDigitNumeratorIllegalRecurring=false;
                    regex="";
                }
            }
            
            if (numerator>denominator)
            {
                maxGCF=denominator;
            }
            else
            {
                maxGCF = numerator;
            } 
            start();
                
            do
            {
                System.out.println("This is potential Greatest Common Factor" +"("+maxGCF+")"+" between " + "Numerator"+"("+numerator+")" + "  Denominator"+"("+denominator+")");
                
                if (numerator==0)
                {
                    break;
                }
                
                if (numerator==1 || denominator==1)
                {
                    break;
                }
                
                for (divisor = 2; divisor<=maxGCF; divisor++)
                {
                    successReducedDenominator=false;
                    successReducedNumerator=false;
                    
                    if (reducedNumerator(numerator,divisor) && reducedDenominator(denominator,divisor))
                    {
                        numeratorToString=String.valueOf(numerator);
                        denominatorToString=String.valueOf(denominator);
                        
                        //not used these two in meaningful way.
                        //will leave if wanting to observe changes in numerator
                        //denominator length during reduction
                        long prevLengthNumerator = numeratorToString.length();
                        long prevLengthDenominator = denominatorToString.length();
                        
                        String prevNumerator = numeratorToString;
                        String prevDenominator=denominatorToString;
                        Double prevDecimal = Double.parseDouble(prevNumerator)/Double.parseDouble(prevDenominator);
                        
                        //not used these two in meaningful way.
                        //will leave if wanting to observe changes in numerator
                        //denominator length during reduction
                        long changeDigitsNumeratorReducing;
                        long changeDigitsDenominatorReducing;
                        
                        denominator = denominator/divisor;
                        numerator = numerator/divisor;
                        
                        double currentDecimal = (double)numerator/(double)denominator;
                        changeDigitsNumeratorReducing= prevLengthNumerator - String.valueOf(numerator).length();
                        System.out.println("Reduction numerator:   ("+prevNumerator+","+String.valueOf(numerator)+ " divisor: " + divisor+")");
                        changeDigitsDenominatorReducing= prevLengthDenominator - String.valueOf(denominator).length();
                        System.out.println("Reduction denominator: ("+prevDenominator+","+String.valueOf(denominator)+ " divisor: " + divisor+")");
                        
                        System.out.println("Reduction in fraction and decimal: " + prevNumerator+"/"+prevDenominator + "("+prevDecimal+")" +" => " + numerator+"/"+denominator+"("+currentDecimal+")");
                        
                        numeratorToString=String.valueOf(numerator);
                        denominatorToString=String.valueOf(denominator);
                        divisor=1;
                    }
                    
                    //there are tricky numbers such as 372500001
                    //which is failing to break out of the divisor increment to maxGCF
                    //whilst no solution is offered, it can be handled in if loop as below
                    //ALTERNATIVELY I CAN PERFORM A REGEX ChECK ON NUMERATOR AND ADJUST NUMERATOR
                    
                    //THIS IS ALTERNATIVE TO USING DO WHILE LOOP (causing more lag on the code, and session kill)
                    //SO VALUES WOULD NEED TO BE HARDWIRED INTO CODE
                    
                   if (numerator==372500001 || numerator==149 || numerator==11111111)
                   {
                        numeratorToString = numeratorToString.substring(0,numeratorToString.length()-1);
                        denominatorToString = denominatorToString.substring(0,denominatorToString.length()-1);
                                
                        System.out.println("11Numerator truncated to: " + numeratorToString.length() + " digits to mitigate idle hanging of numerator: " + "("+numeratorToString+")");
                        System.out.println("12Denominator truncated to: "   + denominatorToString.length() + " digits" + "("+denominatorToString+")"+ " inline with numerator");
                                
                        numerator = Long.valueOf(numeratorToString);
                        denominator = Long.valueOf(denominatorToString);
                                
                        System.out.println("Truncated numerator:   " + numerator);
                        System.out.println("Truncated denominator:   " + denominator);
                   }
                   
                     if (divisor==(maxGCF) && (!successReducedNumerator || !successReducedDenominator))
                    {
                        exitWhileLoop=true;
                        break;
                    }
                
                }
                if (numerator>denominator)
                {
                    maxGCF=denominator;
                    maxNum=numerator;
                    minNum=denominator;
                }
                else
                {
                    maxGCF = numerator;
                    maxNum=denominator;
                    minNum=numerator;
                }
            }while(!exitWhileLoop);
            
            stop();
            
            System.out.println("Elapsed time in seconds to reduce fraction: " + getElapsedTimeInSeconds());
            System.out.println("reduced numerator:   " + numerator);
            System.out.println("reduced denominator: " + denominator);
            
            posTestOneFraction=0;
            StringTokenizer st1 = new StringTokenizer (testOne[1], ",");
    
            while (st1.hasMoreTokens())
            {
                temp= st1.nextToken().toString();
                posTestOneFraction++;
            
                if (posTestOneDecimal==posTestOneFraction)
                {
                    System.out.println("Fraction presented is: " + temp );
                
                    if (temp.indexOf('-')!=-1)
                    {
                        numeratorOriginal = temp.substring((temp.indexOf('-')+1), temp.indexOf('/'));
                        denominatorOriginal = temp.substring(temp.indexOf('/')+1);
                    }
                    if (temp.indexOf('-')==-1)
                    {
                        numeratorOriginal = temp.substring(0,temp.indexOf('/'));
                        denominatorOriginal = temp.substring(temp.indexOf('/')+1);
                        numeratorBackup=Long.valueOf(numeratorOriginal);
                    }
                    long decimalOriginalLong = Long.valueOf(denominatorOriginal);
                    numeratorOriginalLong = Long.valueOf(numeratorOriginal);
                    denominatorOriginalLong=Long.valueOf(denominatorOriginal);
                    
                    double result = 0;
                    String properEntireOriginalFraction="";
                    String originalFraction=temp;
                    long remainingNumerator=0;
                    
                    try
                    {
                        wholeNumberBeforeFraction = temp.substring(0,temp.indexOf("-"));
                        wholeNumberBeforeFractionLong = Long.valueOf(wholeNumberBeforeFraction);
                        fractionAfterWholeNumber = temp.substring(temp.indexOf("-")+1);
                        System.out.println("Whole number before fraction: " + wholeNumberBeforeFractionLong);
                        System.out.println("Fraction after whole number: " + fractionAfterWholeNumber);    
                    }
                    catch (StringIndexOutOfBoundsException e)
                    {
                        System.out.println("No whole number before fraction");
                    }
                    if (decimalOriginalLong<numeratorOriginalLong)
                    {
                        denominatorIntoNumerator = Long.valueOf(numeratorOriginal)/Long.valueOf(denominatorOriginal);
                        System.out.println("Original whole number from fraction (numerator/denominator):" + denominatorIntoNumerator);
                 
                        remainingNumerator = Long.valueOf(numeratorOriginal) - (Long.valueOf(denominatorOriginal) * denominatorIntoNumerator);
                        System.out.println("remaining numerator: " + remainingNumerator);
                 
                        remainingFraction = remainingNumerator + "/" + denominatorOriginal;
                        System.out.println("remaining fraction: " + remainingFraction);
                        System.out.println("Fraction provided in challenge is improper: " + temp);
                        originalFraction = temp;
                        temp=remainingFraction;
                        
                        numeratorOriginal = temp;
properEntireOriginalFraction = ((denominatorIntoNumerator+wholeNumberBeforeFractionLong) + "-" +remainingFraction);

                        System.out.println("Mixed number fraction is: " + properEntireOriginalFraction);
                        
                        if (!String.valueOf(denominatorIntoNumerator+wholeNumberBeforeFractionLong).equals(wholeNumberPortionDecimal))
                        {
                            System.out.println("***Mismatch in whole numbers****");
                            System.out.println("Mixed number fraction has following whole number:" + (denominatorIntoNumerator+wholeNumberBeforeFractionLong));
                            System.out.println("Original decimal has following whole number:" + wholeNumberPortionDecimal);
                            System.out.println("***********");
                        }
                        else
                        {
                            System.out.println("1Mixed number fraction" +"("+(wholeNumberBeforeFractionLong+denominatorIntoNumerator)+")" +  " and original decimal" +"("+wholeNumberPortionDecimal+")" + " have same whole number");
                            
                            if (numerator==0)
                            {
                                System.out.println("There is no fraction in the mixed number fraction" +"("+remainingFraction+")" );
                                break;
                            }
                            
                        }
                        improperFraction=true; 
                    }
                    if (!improperFraction)
                    {
                        if (Long.valueOf(wholeNumberPortionDecimal)!=0 && wholeNumberBeforeFractionLong!=0)
                        {
                            if (!String.valueOf(wholeNumberBeforeFractionLong).equals(wholeNumberPortionDecimal))
                            {
                                System.out.println("***2Mismatch in whole numbers****");
                                System.out.println("Mixed number fraction has following whole number:" + (wholeNumberBeforeFractionLong));
                                System.out.println("Original decimal has following whole number:" + wholeNumberPortionDecimal);
                                System.out.println("***********");
                            }
                            else
                            {
                                System.out.println("3Mixed number fraction" +"("+(wholeNumberBeforeFractionLong)+")" +  " and original decimal" +"("+wholeNumberPortionDecimal+")" + " have same whole number");
                            }
                        }
                    }
                    
                    if (remainingNumerator==0)
                    {
                        remainingNumerator=numeratorBackup;
                    }

if (String.valueOf(remainingNumerator).equals(String.valueOf(numerator)) && denominatorOriginal.equals(String.valueOf(denominator)))
                    {
                        System.out.println("fraction provided in challenge is fully reduced: " + temp);
System.out.println("Original fraction" + "("+temp+")" + " provided is exact representation of the initial decimal conversion: " + decimalOriginal);
                    }
                    else
                    {   
                        double hh;
                        
                        if (isFractionAfterWholeNumber)
                        {
//not always a correct statement, it is being commented
//System.out.println("3Original fraction provided " + temp + " is non- representation of the initial decimal conversion: " + decimalOriginal);
                        }
                        else 
                        {
                        }
                        
                        if (improperFraction)
                        {
                            isFractionAfterWholeNumber=true;
                            result = (double)remainingNumerator/Double.valueOf(denominatorOriginal);
                            System.out.println("1Original fraction"+"("+originalFraction+")" + "has been changed to mixed number fraction"+"("+properEntireOriginalFraction+")");
                            fractionalPartionWithDecimalString = "0"+fractionalPartionWithDecimal;
                            hh = Math.abs(result -  Double.parseDouble(fractionalPartionWithDecimalString));
                            System.out.println("1This is the difference"+"("+hh+")"+ " between original"+"("+fractionalPartionWithDecimalString+")" +  " decimal and associated fraction"+"("+temp+")"+" in decimal" + "("+result+")");
                            
                            if (isFractionAfterWholeNumber && hh!=0)
                            {
                                fractionAfterWholeNumber = temp.substring(temp.indexOf("-")+1);
                                System.out.println("2Original fraction " + "("+ fractionAfterWholeNumber+")" + " is non- representation of the initial decimal conversion: " + "0"+fractionalPartionWithDecimal+"("+numerator+"/"+denominator+")");
                            }
                            else
                            {
                                if (hh==0)
                                {
System.out.println("2Original fraction " + "("+ temp+")" + " is exact representation of the initial decimal conversion: " + "0"+fractionalPartionWithDecimal+"("+numerator+"/"+denominator+")");
//we can now also add a comment as to whether the fraction provided is same as final outcome
                                }
                            }
                            
                            if (!singleDigitrecurring)
                            {   
                                if (String.valueOf(wholeNumberBeforeFractionLong).equals(wholeNumberPortionDecimal))
                                {
                                    if (temp.equals(numerator+"/"+denominator))
                                    {
                                        System.out.println("Original fraction" + "("+temp+")" + " is reduced exactly same as converted decimal (most reduced form): " + "("+numerator+"/"+denominator+")");
                                    }
                                    else
                                    {
                                        System.out.println("Original fraction" + "("+temp+")" + " is NOT reduced identically to the converted decimal (most reduced form): " + "("+numerator+"/"+denominator+")");
                                    }
                                }
                                
System.out.println("1Remaining fraction"+"(" + remainingFraction+")" + " is non- representation of the initial decimal conversion: " + "0"+decimalPortionOriginal);
System.out.println("1Remaining fraction " + "("+remainingFraction+")" + " in decimal is " + result + " and NOT:" + "0"+ decimalPortionOriginal +"(original)");
                  
                            String remainingFractionNumerator = remainingFraction.substring(0,remainingFraction.indexOf("/"));
                            String remainingFractionDenominator = remainingFraction.substring(remainingFraction.indexOf("/")+1);
                            hh=Double.parseDouble(remainingFractionNumerator)/Double.parseDouble(remainingFractionDenominator);
                            
                            double difference = hh - Double.parseDouble(decimalPortionOriginal);
                            System.out.println("2This is the difference"+"("+Math.abs(difference)+")"+ " between original"+"("+"0"+decimalPortionOriginal+")" +  " decimal and associated mixed number remaining fraction" + "("+remainingFraction+")");          
                            }
                            
                            double dec = (double)numerator/(double)denominator;
                            double numeratorDouble = Double.parseDouble(remainingFraction.substring(0,remainingFraction.indexOf("/")));
                            double denominatorDouble = Double.parseDouble(remainingFraction.substring(remainingFraction.indexOf("/")+1));
                            
                            try
                            {
                                result= numeratorDouble/denominatorDouble;
                            }
                            catch (ArithmeticException e)
                            {
                                result = dec;
                            }
                        }
                        else
                        {
                            result= Double.parseDouble(numeratorOriginal)/Double.parseDouble(denominatorOriginal);
                            fractionalPartionWithDecimalString = "0"+fractionalPartionWithDecimal;
                            
                            hh = Math.abs(result -  Double.parseDouble(fractionalPartionWithDecimalString)); 
                            
                            System.out.println("1This is the difference"+"("+hh+")"+ " between original"+"("+fractionalPartionWithDecimalString+")" +  " decimal and associated fraction"+"("+temp+")"+" in decimal" + "("+result+")");

                            if (isFractionAfterWholeNumber && hh!=0)
                            {
    System.out.println("2Original fraction " + "("+ fractionAfterWholeNumber+")" + " is non- representation of the initial decimal conversion: " + "0"+fractionalPartionWithDecimal+"("+numerator+"/"+denominator+")");
                            }
                            else
                            {
                                if (hh==0)
                                {
System.out.println("2Original fraction " + "("+ temp+")" + " is exact representation of the initial decimal conversion: " + "0"+fractionalPartionWithDecimal+"("+numerator+"/"+denominator+")");

if (Long.valueOf(numeratorBackup)==numerator  && Long.valueOf(denominatorOriginal)==denominator)
                                    {
System.out.println("Fraction provided " + "("+numerator+"/"+denominator+")"+ " is in most reduced form");
                                    }
                                }
                                else
                                {
System.out.println("2Original fraction " + "("+ temp+")" + " is non- representation of the initial decimal conversion: " + "0"+fractionalPartionWithDecimal+"("+numerator+"/"+denominator+")");
                                }
                            }                       
                        }
                    }
                }
            }
            remainingFraction="";
            improperFraction=false;
            isFractionAfterWholeNumber=false;
            terminatingDecimal(denominator, numerator,decimalOriginal);
            isPeriodNumber=true;
        }  //end of while (st.hasMoreTokens())
    }
    
    public RepeatDecimalFractions(String[] testOne, long acceptedNumeratorLimit, int LIMITPRECISION, long primeNumberCheckLimit)
    {
        this.acceptedNumeratorLimit=acceptedNumeratorLimit;
        this.testOne=testOne;
        this.LIMITPRECISION=LIMITPRECISION;
        this.primeNumberCheckLimit = primeNumberCheckLimit;
        fraction(testOne);
    }
} //end of class

public class Main
{
    public static void main(String[] args) 
    {
        String[] testOne = new String[2];
        
        //see test cases excel documentation on numbers causing time outs
        //can reduce precision as per guidance
        
        testOne[0]="5.2,7.1111111,0.192367,0.2228,0.777777777777778777,3.14857,0.6,1.1,6.1,6.1,0.10973,0.343,0.242424,0.1875325,0.5,1.25,0.0123,0.0001,0.999,0.15,0.86,10.4,23.5,0.75,0.1111111111111111111,0.1111111111111111111,0.33533,5.1111111111111111111,5.1111111111111111111,7.1111111111111111111,0.555,10.0,0.011005502751375";
        testOne[1]="26/5,22/1999,64/9,5343/27775,222/100,987000200/100000020,22/7,2/3,10/9,1-3/9,5-11/10,823/7500,1/3,30303/125000,75013/400000,1/2,1-1/4,123/10000,1/10000,999/1000,15/100,86/100,10-2/5,23-1/2,3/4,3/27,1/9,33533/100000,4-64/9,64/9,7-1/9,64/9,20/2,22/1999";
        
        //additional testers.....- (corresponds to  TestCaseGenerator.xlsx)
        //testOne[0]="0.950000018,0.400000043,0.950000098,0.400000067,0.950000158,0.400000091,0.950000218,0.400000151,0.950000342,0.400000189,0.950000386,0.400000261,0.950000566,0.400000301,0.950000618,0.400000333,0.950000714,0.400000373,0.950000822,0.400000457,0.950000954,0.400000499,0.950001022,0.400000543,0.950001106,0.400000583,0.950001238,0.400000631,0.950001278,0.400000649,0.950001302,0.400000669,0.950001418,0.400000753,0.950001518,0.400000789,0.950001658,0.400000841,0.950001746,0.400000877,0.950001766,0.400000907,0.950001854,0.400000933,0.950001898,0.400001009,0.950002022,0.400001039,0.950002118,0.400001083,0.950002174,0.400001099,0.950002202,0.400001111,0.950002226,0.400001137,0.950002318,0.400001197,0.950002402,0.400001227,0.950002466,0.400001249,0.950002534,0.400001269,0.950002682,0.400001369,0.950002774,0.400001389,0.950002858,0.400001447,0.950002954,0.400001501,0.950003014,0.400001521,0.950003086,0.400001603,0.950003242,0.400001639,0.950003294,0.400001663,0.950003458,0.400001731,0.950003494,0.400001779,0.950003602,0.400001803,0.950003662,0.400001881,0.950003818,0.400001923,0.950003866,0.400001951,0.950004022,0.400002019,0.950004046,0.400002047,0.950004134,0.400002073,0.950004178,";
        //testOne[1]="950000318/1000000000,400000043/1000000000,950000098/1000000000,400000067/1000000000,950000158/1000000000,400000091/1000000000,950000218/1000000000,400000151/1000000000,950000342/1000000000,400000189/1000000000,950000386/1000000000,400000261/1000000000,950000566/1000000000,400000301/1000000000,950000618/1000000000,400000333/1000000000,950000714/1000000000,400000373/1000000000,950000822/1000000000,400000457/1000000000,950000954/1000000000,400000499/1000000000,950001022/1000000000,400000543/1000000000,950001106/1000000000,400000583/1000000000,950001238/1000000000,400000631/1000000000,950001278/1000000000,400000649/1000000000,950001302/1000000000,400000669/1000000000,950001418/1000000000,400000753/1000000000,950001518/1000000000,400000789/1000000000,950001658/1000000000,400000841/1000000000,950001746/1000000000,400000877/1000000000,950001766/1000000000,400000907/1000000000,950001854/1000000000,400000933/1000000000,950001898/1000000000,400001009/1000000000,950002022/1000000000,400001039/1000000000,950002118/1000000000,400001083/1000000000,950002174/1000000000,400001099/1000000000,950002202/1000000000,400001111/1000000000,950002226/1000000000,400001137/1000000000,950002318/1000000000,400001197/1000000000,950002402/1000000000,400001227/1000000000,950002466/1000000000,400001249/1000000000,950002534/1000000000,400001269/1000000000,950002682/1000000000,400001369/1000000000,950002774/1000000000,400001389/1000000000,950002858/1000000000,400001447/1000000000,950002954/1000000000,400001501/1000000000,950003014/1000000000,400001521/1000000000,950003086/1000000000,400001603/1000000000,950003242/1000000000,400001639/1000000000,950003294/1000000000,400001663/1000000000,950003458/1000000000,400001731/1000000000,950003494/1000000000,400001779/1000000000,950003602/1000000000,400001803/1000000000,950003662/1000000000,400001881/1000000000,950003818/1000000000,400001923/1000000000,950003866/1000000000,400001951/1000000000,950004022/1000000000,400002019/1000000000,950004046/1000000000,400002047/1000000000,950004134/1000000000,400002073/1000000000,950004178/1000000000";

        
        //This has been removed from testing... It is requiring too many regex
        //manipulations to shrink numerator to prevent stalling.
        //0.7450000025999994
        //740/1000
        
        
        long primeNumberCheckLimit = 5;
        
        
        //enter value 1 to 9, any greater number might have adverse effect 
        long acceptedNumeratorLimit=9;
        
	//this is limit in Java, runtime error if increased beyond
        final int LIMITPRECISION=19;
        
        System.out.println("********Welcome to Online IDE!! Happy Coding :)**********");
        System.out.println("NOTE: Precision is limited to " + LIMITPRECISION + " digits wide...");
        System.out.println("NOTE: Any decimal with recurring single digit" + "("+ LIMITPRECISION +" times)" + " will be assumed to be recurring number");
        System.out.println("NOTE: Since computational issues, reduction on decimal component EXCEEDING " + acceptedNumeratorLimit + "(9 digits) will lose its precision by 1 or more digit depending on the decimal.");
        System.out.println("NOTE: Value of acceptedNumeratorLimit = " + acceptedNumeratorLimit+ " digits. This can be changed to speed up most reduced form calculations");
        System.out.println("NOTE: Also to AVOID any Session kills or hanging");
        System.out.println("To create sample of decimals and fractions, original numerator will be divided  numerator/prime number from: " + 2 + " => " + primeNumberCheckLimit);
        System.out.println("DENOMINATOR AND NUMERATOR WILL BOTH BE TRUNCATED INLINE WITH INTEGRITY ORIGINAL INPUTS");
         //example situations of information provided to end user																			
        //1This is the difference(0.0) between original(0.5) decimal and associated fraction(23-1/2) in decimal(0.5)																			
        //2Original fraction (23-1/2) is exact representation of the initial decimal conversion: 0.5(5/10)																			
        //2Original fraction (1/3) is non- representation of the initial decimal conversion: 0.343(343/1000)																			
        //1Remaining fraction(1/9) is non- representation of the initial decimal conversion: 0.1																			
        //1Remaining fraction (1/9) in decimal is 0.1111111111111111 and NOT:0.1(original)																			
        //2This is the difference(0.0111111111111111) between original(0.1) decimal and associated mixed number remaining fraction(1/9)
        //1Mixed number fraction(6) and original decimal(6) have same whole number
        //There is no fraction in the mixed number fraction(0/2)
        
        System.out.println("******************");
        
        RepeatDecimalFractions rdf = new RepeatDecimalFractions(testOne,acceptedNumeratorLimit,LIMITPRECISION,primeNumberCheckLimit);
    }
}

