Search code examples
javaloopswhile-loopinfinite-loop

Why is my Java program stuck in a infinite while-loop for some values?


I just started with java and while I was doing a exercise (about finding the next Friday 13th after a given date) when I got stuck with the following problem: When the input day (of the given date) is equal or bigger than 13, the program goes in a infinite loop. Any suggestions?

      public class NextFriday13 {
    public static void main(String[] args) {
        int d = Integer.parseInt(args[0]);
        int m = Integer.parseInt(args[1]);
        int y = Integer.parseInt(args[2]);

        //aqui colocaremos o total de dias em cada mes
        int[] DAYS = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        //fixaremos nosso ponto de referencia, 1/1/1600 foi um sabado.
        int dd = 1;
        int mm = 1;
        int yy = 1600;
        int day = 0;


        //descobriremos a proxima sexta-feira 13

        while (dd <= d || mm <= m || yy <= y || day != 6 || dd != 13){
            day++;
            day %= 7;

            boolean leapYear;
            if (yy % 400 == 0) leapYear = true;
            else if (yy % 100 == 0) leapYear = false;
            else leapYear = yy % 4 == 0;

            if (dd + 1 <= DAYS[mm] || (dd == 28 && leapYear))
                dd++;
            else{
                if (mm < 12) {
                    dd = 1;
                    mm++;
                }
                else {
                    dd = 1;
                    mm = 1;
                    yy++;
                }
            }

        }
        System.out.println("Next Friday 13th is " + dd + "/" + mm + "/"+ yy);

    }
}

Here are the following input-output i got: input:1 1 2000 output:Next Friday 13th is 13/4/2001

input:6 2 2011 output:Next Friday 13th is 13/4/2012

input:13 2 2003 output:(I had to close the program because it didnt end)

input:22 4 1998 output:(same thing as above)


Solution

  • You might want to adjust the condition for the while-loop. You want to continue adding a day under following circumstances:

    • Date mm/dd/yy is before m/d/y (not yet after the given date)
    • Date mm/dd/yy is no friday (day != 6)
    • Date mm/dd/yy is no 13th (dd != 13)

    The last two conditions are implemented the right way, but your check, if the date is in the "future", does not work correctly. You might try this:

    yy < y || (yy == y && mm < m) || (yy == y && mm == m && dd <= d)
    

    Thus the total condition you need is

    yy < y || (yy == y && mm < m) || (yy == y && mm == m && dd <= d) || day != 6 || dd != 13
    

    EDIT to explain why you run into an endless loop with d >= 13:

    Your condition has dd <= d and dd != 13. Thus dd needs to be equal to 13 and bigger than (at least) 13 (the provided d) for the condition to evaluate to false. This obviously will never be the case, thus you get an endless loop.