Search code examples
javaalgorithmruntime-error

Kattis keeps giving me a Runtime Error on heliocentric


Kattis gives me a Runtime Error for heliocentric upon submission. I changed parts of the code and asked my friends and we all have no idea what is wrong. Does anyone have an idea as to what I am missing?

import java.util.Scanner;

public class heliocentric {

  public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    int inE;
    int inM;
    boolean collin;
    int days;

    for (int i = 1; i < 10; i++) {
      days = 0;
      collin = false;
      inE = scan.nextInt();
      inM = scan.nextInt();
      if (inE < 0 || inM < 0) {
        collin = true;
      }

      while (collin != true) {
        if (inE == 0 && inM == 0) {
          break;
        }
        inE++;
        if (inE == 365) {
          inE = 0;
        }
        inM++;
        if (inM == 687) {
          inM = 0;
        }
        days++;
        if (inE == 0 && inM == 0) {
          collin = true;
        }
      }
      System.out.println("Case " + i + ": " + days);
    }
    scan.close();
  }
}

Input

0 0
364 686
360 682
0 1
1 0

Output

Case 1: 0
Case 2: 1
Case 3: 5
Case 4: 239075
Case 5: 11679

Solution

  • Your logic is OK, but your I/O isn't, which is often the problem with Kattis submissions.

    The description says "at most 10" but the first test case only has 5 lines of input, so your code will probably throw a java.util.InputMismatchException.

    You can use the following pattern to exit cleanly:

    var scanner = new java.util.Scanner(System.in);
    
    while (scanner.hasNextInt()) {
        // read the ints
    }
    
    scanner.close();
    

    ...or slap a try/catch around your code. That's ugly, but works as a quick way to test a hypothesis.

    As an aside, variables with names like collin are confusing. This variable isn't necessary; just break as soon as you're done with the loop instead of adding more state to have to manage.

    There's no need to forward-declare variables. Declare them where you use them, as tightly scoped as possible. This reduces the mental burden it takes to understand the code.

    Cleaner:

    public class heliocentric {
        public static void main(String[] args) {
            var scanner = new java.util.Scanner(System.in);
    
            for (int i = 1; scanner.hasNextInt(); i++) {
                int days = 0;
                int e = scanner.nextInt();
                int m = scanner.nextInt();
    
                while (e != 0 || m != 0) {
                    e = (e + 1) % 365;
                    m = (m + 1) % 687;
                    days++;
                }
    
                System.out.println("Case " + i + ": " + days);
            }
    
            scanner.close();
        }
    }
    

    There's probably a better mathematical solution to this problem...