/*
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
{
    String stallingCodeReducedNumerator[];
    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;
        boolean executeOnce=true;
        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 (NOT Terminating) 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");
        }
        
        
        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 fractionalPortionWithDecimal = temp.substring((temp.indexOf(".")));
            long numerator = Long.valueOf(fractionalPart);
            
            partialEquationTwo="";
            
            String fullEquationOne=  "0"+fractionalPortionWithDecimal;
            Double equationTwoA;
            String fractionAfterWholeNumber="";
            String wholeNumberBeforeFraction;
            long wholeNumberBeforeFractionLong=0;
            String fractionalPortionWithDecimalString;
            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);
                    
                    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 SPECIFIC RECURRING FRACTION NUMERATOR  :" + regexCheck);
                        
                        pattern = Pattern.compile(regexCheck, Pattern.CASE_INSENSITIVE);
                        matcher = pattern.matcher(numeratorToString);
                        
                        System.out.println("THIS IS THE numerator:" + 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 denominator:   " + 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 SPECIFIC RECURRING FRACTION NUMERATOR  :" + regexCheck);
                        
                        pattern = Pattern.compile(regexCheck, Pattern.CASE_INSENSITIVE);
                        matcher = pattern.matcher(numeratorToString);
                        System.out.println("THIS IS THE numerator:" + 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;
                    
                    //has to deal separate for cases such as decimal 5.2
                    //if (numerator%2==0  && denominator%2==0)
                    //{
                    //    reducedNumerator(numerator,divisor);
                     //   reducedDenominator(denominator,divisor);
                    //}
                   
                    
                    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
                        //and 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;
                    }
                    
                    
                    int counter=0;
                    
                    
                    //TRIED THE DO WHILE LOOP BENEATH THIS, BUT SESSION WOULD TIME OUT
                    //SO NOW HARDWIRING DIRECTLY INTO CODE:
                    
                    if (numerator==372500001   || numerator==11111111 || numerator==1111111)
                    {
                        
                        numeratorToString=String.valueOf(numerator);
                        denominatorToString=String.valueOf(denominator);
                        
                        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: " + "("+regexCheck+")");
                        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);
                    }
                    
                    //there are tricky numbers such as 372500001
                    //which is failing to break out of the divisor increment to maxGCF
                    //whilst no solution is offered, I am placing these values in a String...
                    
                    /*  
                    do
                    {
                        regexCheck=stallingCodeReducedNumerator[counter];
                        
                        pattern = Pattern.compile(regexCheck, Pattern.CASE_INSENSITIVE);
                        matcher = pattern.matcher(numeratorToString);
                        
                        if (matcher.find())
                        {
                            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: " + "("+regexCheck+")");
                            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);
                        }
                        
                        counter++;
                        
                    }while(counter<stallingCodeReducedNumerator.length);
                    */
                    
                     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+")");
                            fractionalPortionWithDecimalString = "0"+fractionalPortionWithDecimal;
                            hh = Math.abs(result -  Double.parseDouble(fractionalPortionWithDecimalString));
                            System.out.println("1This is the difference"+"("+hh+")"+ " between original"+"("+fractionalPortionWithDecimalString+")" +  " 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"+fractionalPortionWithDecimal+"("+numerator+"/"+denominator+")");
                            }
                            else
                            {
                                if (hh==0)
                                {
System.out.println("2Original fraction " + "("+ temp+")" + " is exact representation of the initial decimal conversion: " + "0"+fractionalPortionWithDecimal+"("+numerator+"/"+denominator+")");

                                }
                            }
                            
                            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);
                            fractionalPortionWithDecimalString = "0"+fractionalPortionWithDecimal;
                            
                            hh = Math.abs(result -  Double.parseDouble(fractionalPortionWithDecimalString)); 
                            
                            System.out.println("1This is the difference"+"("+hh+")"+ " between original"+"("+fractionalPortionWithDecimalString+")" +  " 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"+fractionalPortionWithDecimal+"("+numerator+"/"+denominator+")");
                            }
                            else
                            {
                                if (hh==0)
                                {
System.out.println("2Original fraction " + "("+ temp+")" + " is exact representation of the initial decimal conversion: " + "0"+fractionalPortionWithDecimal+"("+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"+fractionalPortionWithDecimal+"("+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,String[] stallingCodeReducedNumerator)
    {
        this.stallingCodeReducedNumerator=stallingCodeReducedNumerator;
        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]="3.0,7.1111111111111111111,0.7450000025999994,3.14857,0.6,1.1,6.1,6.1,0.10973,0.343,0.242424,0.1875325,0.5,1.25,      0.011005502751375,5.0,0.999999937,7.1111111,0.192367,0.222222222222228,0.777777777777778777,6.1,6.1,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,0.555,10.0";
        //testOne[1]="14/6,740/1000,64/9,22/7,1-3/9,5-11/10,823/7500,1/3,30303/125000,75013/400000,1/2,1-1/4,     22/1999,10/2,999999937/1000000000,64/9,5343/27775,222/100,987000200/100000020,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,20/2";
        
        testOne[0]="5.2,7.1111111,0.192367,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.111111111111111,0.33533,5.11111111111111,5.11111111111111,7.111111111,0.555,10.0,0.011005502751375,0.222222222222228,0.7450000025999994";
        testOne[1]="26/5,22/1999,64/9,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,64/9,7-1/9,20/2,22/1999,5343/27775,740/1000";
        
        //this can be populated by end user if it fails to reduce
        //this will then appear as a regex and remediative action taken
        //during execution
        //String[] stallingCodeReducedNumerator = new String[]{"372500001","111111111","333333333","777777777","999999999"};
        String[] stallingCodeReducedNumerator = new String[]{"372500001"};
        
        //can be expanded as desired
        long primeNumberCheckLimit = 5;
        
        //enter value 1 to 9, any greater number might have adverse effect 
        long acceptedNumeratorLimit=9;
        
        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 periodic 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");
        System.out.println("SOME TRUNCATION TECHNIQUES ARE BASED ON SAFE MEASURING AGAINST FAILING CODE DURING ITERATION");
         //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,stallingCodeReducedNumerator);
    }
}