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

class RepeatDecimalFractions
{
    //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;
    
     //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;
        long denominatorDivisiblePrimeFactor=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("**************************************************");
        
        
        System.out.println("CHECK TO SEE IF ORIGINAL FRACTION IS TERMINATING: ");    
            
        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);
        
            if (executeOnce)
            {
                if (primeFactorFive || primeFactorTwo)
                {
                    System.out.println("Terminating fraction since reduced denominator is divisble by prime number of two or five");
                    System.out.println(decimalOriginal + " is a periodic number");
            }
            else
            {
                System.out.println("NOT Terminating fraction since reduced denominator is NOT divisble by prime factor of two or five");
            }
            executeOnce=false;
          }
          
          //************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***********
        }
        
        return false;
    }
        
    public void checkRecurrence()
    {
       String 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
                {
                    fractionalPart=backupFractionalPart;
                    singleDigitrecurring = false;
                    break;
                }
            }while(fractionalPart.length()>1);
        }
    }
    
    public void fraction(String[] testOne)
    {
        boolean improperFraction=false;
        String temp;
        long posTestOneDecimal=0;
        long posTestOneFraction;
        String numeratorOriginal="";
        String denominatorOriginal="";
        String decimalOriginal="";
        long denominatorIntoNumerator;
        String remainingFraction="";
        String decimalPortionOriginal="";
        int posDecimalPoint;
        
        generateTerminatingNonRepeatFractions();
        
        StringTokenizer st = new StringTokenizer (testOne[0], ",");
        
        String wholeNumberPortionDecimal;
        
        while (st.hasMoreTokens())
        {
            singleDigitrecurring=false;   
            temp= st.nextToken().toString();
            
            posDecimalPoint=temp.indexOf(".");
            decimalOriginal=temp;
            
            posTestOneDecimal++;
            System.out.println("\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;
            long denominator=0;
            String wholeNumberBeforeFraction;
            long wholeNumberBeforeFractionLong=0;
            String numeratorToString;
            String denominatorToString="";
        
            System.out.println("fractional part before checkRecurrence method call: " + fractionalPart); 
            checkRecurrence();
            System.out.println("fractional part after  checkRecurrence method call: " + fractionalPart); 
            System.out.println("This is full equation one: " + fullEquationOne);
        
            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;
        
                    System.out.println("FULL EQUATION ONE: " + fullEquationOne);
                    System.out.println("FULL EQUATION TWO: " + fullEquationTwo);
                    System.out.println(Double.valueOf(fullEquationOne));
                    equationTwoA = Double.valueOf(fullEquationTwo) - Double.valueOf(fullEquationOne);
                    System.out.println("FULL EQUATION TWO A: " + equationTwoA);
        
                    numerator = equationTwoA.longValue();
                    denominator = 9;
                    remainingFraction = numerator + "/" + 9;
                    System.out.println("Fraction of recurring: " + remainingFraction);
                }
                else
                {
                    numberConsecutiveDigits=0;
                }
            }
            
            if (!singleDigitrecurring)
            {
                long multipliedBy;
                System.out.println("The fraction part: " + fractionalPart);
                multipliedBy=fractionalPart.length();
                long multipliedByInteger = Long.valueOf(multipliedBy);
                denominator = 1;
                long i=0;
        
                while (i<multipliedByInteger)
                {
                    i++;
            
                    if (i<limitPrecision)
                    {
                        denominator = denominator * 10;
                        System.out.println("value denominator: " + denominator);
                        System.out.println("value i: " + i);
                    }
                    else
                    {
                        break;
                    }
                }
                System.out.println("this is numerator: " + numerator);
                System.out.println("this is denominator: " + denominator);
                
                if (numerator>acceptedNumeratorLimit)
                {
                    if (denominator>numerator)
                    {
                        System.out.println("Denominator" + "("+denominator+")" + " considered too large for computation");
                        denominatorToString = String.valueOf(denominator);
                        denominatorToString=denominatorToString.substring(0,9);
                        System.out.println("Denominator reduced to 9 digits wide: " + denominatorToString);
                        denominator = Long.valueOf(denominatorToString);
                    }
           
                    System.out.println("Numerator" + "("+numerator+")" + " considered too large for computation");
                    numeratorToString = String.valueOf(numerator);
                    numeratorToString=numeratorToString.substring(0,9);
                    System.out.println("Numerator reduced to 9 digits wide: " + numeratorToString);
                    numerator = Long.valueOf(numeratorToString);
           
                    if (numerator>acceptedNumeratorLimit)
                    {
                        System.out.println("Numerator" + "("+numerator+")" + " considered too large for computation");
                        numeratorToString = String.valueOf(numerator);
                        numeratorToString=numeratorToString.substring(0,numeratorToString.length()-1);
                        System.out.println("Numerator reduced to 8 digits wide: " + numeratorToString);
                        denominatorToString=String.valueOf(denominator);
                        denominatorToString=denominatorToString.substring(0,8);
                        System.out.println("Denominator reduced to 8 digits wide: " + denominatorToString);
                    }
             }
             
             if (numerator>denominator)
             {
                 maxGCF=denominator;
             }
            else
            {
                maxGCF = numerator;
            } 
        
            start();
       
            for (divisor = 1; divisor<=maxGCF; divisor++)
            {
                if (reducedNumerator(numerator,divisor) && reducedDenominator(denominator,divisor))
                {
                    denominator = denominator/divisor;
                    numerator = numerator/divisor;
                    successReducedDenominator=false;
                    successReducedNumerator=false;
                }
            }
            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);
                    }
                    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("-"));
                        System.out.println("Var: " + wholeNumberBeforeFraction);
                        wholeNumberBeforeFractionLong = Long.valueOf(wholeNumberBeforeFraction);
                        System.out.println("Whole number before fraction: " + wholeNumberBeforeFractionLong);
                    }
                    catch (StringIndexOutOfBoundsException e)
                    {
                        System.out.println("Improper fraction with no existing whole number in front");
                        System.out.println("CATCH2");
                    }
                    if (decimalOriginalLong<numeratorOriginalLong)
                    {
                        denominatorIntoNumerator = Long.valueOf(numeratorOriginal)/Long.valueOf(denominatorOriginal);
                        System.out.println("Original 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);
                        System.out.println(wholeNumberPortionDecimal);
                        System.out.println(String.valueOf(denominatorIntoNumerator+wholeNumberBeforeFractionLong));
                 
                        if (!String.valueOf(denominatorIntoNumerator+wholeNumberBeforeFractionLong).equals(wholeNumberPortionDecimal))
                        {
                            System.out.println("***Mismatch in whole numbers****");
                            System.out.println("Fraction has following whole number:" + (denominatorIntoNumerator+wholeNumberBeforeFractionLong));
                            System.out.println("Original decimal has following whole number:" + wholeNumberPortionDecimal);
                            System.out.println("***********");
                        }
                        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("Fraction has following whole number:" + (wholeNumberBeforeFractionLong));
                                System.out.println("Original decimal has following whole number:" + wholeNumberPortionDecimal);
                                System.out.println("***********");
                            }
                        }
                    }
                    System.out.println("numeratorOriginal:"+ numeratorOriginal);
                    System.out.println("numerator:" + String.valueOf(numerator));
                    System.out.println("denominatorOriginal: " + denominatorOriginal);
                    System.out.println("denominator:"+ String.valueOf(denominator));
              
if (numeratorOriginal.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
                    {
                        System.out.println("2Fraction provided in challenge: " + temp + " might not be correctly reduced " + "("+numerator+"/"+denominator+")");
                        
                        if (improperFraction)
                        {
                            System.out.println("Discrepency above is due to conversion from improper=>proper fraction");
                            result = (double)remainingNumerator/Double.valueOf(denominatorOriginal);
                            System.out.println("1Original fraction"+"("+originalFraction+")" + "has been changed to proper fraction"+"("+properEntireOriginalFraction+")");
                 
                            if (!singleDigitrecurring)
                            {
                                System.out.println("Remaining fraction is: " + 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)");
                            }
                            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
                        {
                            System.out.println("numeratorOriginalLong: " + numeratorOriginalLong);
                            System.out.println("denominatorOriginalLong: " + denominatorOriginalLong);
                         
                            result= Double.parseDouble(numeratorOriginal)/Double.parseDouble(denominatorOriginal);
System.out.println("2Original reduced fraction provided " + temp + " is non- representation of the initial decimal conversion: " + "0"+fractionalPartionWithDecimal);
                    
                            if (!singleDigitrecurring)
                            {
                                System.out.println("1Remaining original fraction" + "(" + temp +")" + " in decimal is " + result + " and NOT:" + "0"+decimalPortionOriginal+"(original)");
                            }
                        }
                        improperFraction=false;
                    }
                }
            }
            terminatingDecimal(denominator, numerator,decimalOriginal);
        }
    }
    
    public RepeatDecimalFractions(String[] testOne, long acceptedNumeratorLimit, int limitPrecision, long primeNumberCheckLimit)
    {
        this.acceptedNumeratorLimit=acceptedNumeratorLimit;
        this.testOne=testOne;
        this.limitPrecision=limitPrecision;
        this.primeNumberCheckLimit = primeNumberCheckLimit;
        fraction(testOne);
    }
}

public class Main
{
    public static void main(String[] args) 
    {
        String[] testOne = new String[2];
      
        testOne[0]="3.1425,0.74500000259999948,0.6,1.1,6.1,6.1,0.192367,0.10973,0.343,0.01100550275137568784,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,7.1111111111111111111";
        testOne[1]="22/7,987000200/1000000200,2/3,10/9,10/9,1-3/9,5343/27775,823/7500,1/3,22/1999,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";
        
        // 0.7777777777777787777  this is constantly timing out even upon reducing acceptedNumeratorLimit
        //1-777/100   reduced from test cases
        
        long primeNumberCheckLimit = 5;
        long acceptedNumeratorLimit=999999999;
        final int limitPrecision=19;
        
        System.out.println("********Welcome to Online IDE!! Happy Coding :)**********");
        System.out.println("NOTE:   Precision is limited to 19 digit wide...");
        System.out.println("NOTE: Since computational issues, reduction on decimal component EXCEEDING " + acceptedNumeratorLimit + " will lose its precision by 1 digit. ");
        System.out.println("NOTE: Value of acceptedNumeratorLimit = " + acceptedNumeratorLimit+". 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("******************");
        
        RepeatDecimalFractions rdf = new RepeatDecimalFractions(testOne,acceptedNumeratorLimit,limitPrecision,primeNumberCheckLimit);
    }
}