ECOO 2014 Local - Problem #1: Martian Time

The problem:

A day on Mars is just a little bit longer than a day on Earth. One day on Mars lasts 24 hours 37 minutes and 22.663 seconds in Earth time. To make sure they can get the most out of the daylight hours on Mars, when NASA plans a Mars Rover mission, they put all of their employees on "Martian Time".

Martian time uses a 24-hour clock divided into minutes and seconds just like Earth time. But every Martian hour, minute and second has to be just a little bit longer than its Earth counterpart.

It just so happens that at 12:00 AM on January 1st, 2015 (aka Day 1) on Earth it will also be exactly 12:00 AM of Day 1 in Martian time at the place where the next Mars rover will touch down. So NASA has issued its employees Martian digital watches, synchronized so that Day 1 at midnight matches Day 1 at midnight on Earth. These watches report the day, hour and minute of the current time (they keep track of seconds as well, but don't report that number on the face of the watch).

DATA11.txt (DATA12.txt for the second try) will contain 10 test cases. Each test case will consist of three integers D, H, and M representing the Day, Hour and Minute of an exact time on Earth, where Day 1 is January 1st, 2015 (1 ≤ D ≤ 1000, 0 ≤ H ≤ 23 and 0 ≤ M ≤ 59). Your job is to output the current time on Mars as it would be shown on the Martian digital watch described above. Each time should be on a single line and formatted exactly as shown in the sample output below.

Sample Input
346 12 28
393 06 40
390 19 50
984 02 25
674 21 29
435 13 07
15 04 12
539 00 50
40 01 20
69 03 11
Sample Output
Day 337, 18:40
Day 383, 08:28
Day 380, 23:07
Day 959, 05:28
Day 657, 20:17
Day 424, 13:15
Day 14, 19:35
Day 525, 10:08
Day 39, 01:37
Day 67, 09:48

My solution (in Java):

Note: in my current solution, I only get the correct output when I add 36 minutes to whatever I calculated. I'm not sure why it works yet and what the problem is with the other part of my code, but I'm working on it. In both algorithm methods, I have
mins += 36; and marsSeconds += 2160;. One of them is commented out in each (alternating ones) so that it doesn't add 72 minutes in total, but I show boths ways of doing it just for different ways of thinking. One way is adding 36 minutes in seconds at the beginning, the other is adding 36 minutes in minutes after the minutes are already calculated.

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Scanner;
import java.io.File;

public class Problem_1_Martian_Time {

public static final double RATIO = 86400 / 88642.663; // earth day : mars day (in seconds)
public static final DecimalFormat DF = new DecimalFormat("00"); // just to format the output

public static void main(String[] args) {

try {
Scanner scanner = new Scanner(new File("F:\\data\\DATA11.txt"));
ArrayList<String> list = new ArrayList<String>();

// read in the file to the ArrayList
while (scanner.hasNextLine()) {
}

for (String line : list) {

String[] s = line.split("\\s+"); // split line by white space

int day = Integer.parseInt(s);
int hour = Integer.parseInt(s);
int minute = Integer.parseInt(s);

/* Convert Earth time from days, hours and minutes into seconds
then figure out that Mars time in seconds
then convert the Mars time from seconds to days, hours and minutes. */

// choose one or the other (both algorithms give the same output)
differenceAlgorithm(day, hour, minute);
moduloAlgorithm(day, hour, minute);
}
} catch (Exception e) {
e.printStackTrace();
}

}

/* Independent of moduloAlgorithm, this method is one solution */
public static void differenceAlgorithm(int d, int h, int m) {
// 60 seconds in a minute, 60 minutes in an hour, 24 hours in a day
double earthSeconds = d * 60 * 60 * 24 + h * 60 * 60 + m * 60;
double marsSeconds = earthSeconds * RATIO;

marsSeconds += 2160; // add 36 minutes (it works for some reason)

int days = (int)marsSeconds / 86400; // whole number of days
int daysInSeconds = days * 86400; // whole days represented in seconds

// seconds left to be distributed to the hours and minutes (days are done)
double secondsLeft = marsSeconds - daysInSeconds;

int hours = (int)(secondsLeft / 3600); // whole number of hours
int hoursInSeconds = hours * 3600; // whole hours represented in seconds

// seconds left to be distributed to the minutes (days and hours are done)
secondsLeft = marsSeconds - daysInSeconds - hoursInSeconds;

double minutes = secondsLeft / 60;

// minutes += 36; // add 36 minutes (it works for some reason)

// needs to be here in case the minutes get rounded up to an hour
if (minutes >= 59.5) {
hours += 1;
minutes -= 60;

if (hours >= 24) {
days += 1;
hours -= 24;
}
}

System.out.print("Day " + days + ", ");
System.out.print(DF.format(hours) + ":");
System.out.println(DF.format(Math.abs(minutes))); // absolute value so negative number rounded doesn't show negative sign
}

/* Independent of differenceAlgorithm, this method is one solution */
public static void moduloAlgorithm(int d, int h, int m) {
// 60 seconds in a minute, 60 minutes in an hour, 24 hours in a day
double earthSeconds = d * 60 * 60 * 24 + h * 60 * 60 + m * 60;
double marsSeconds = earthSeconds * RATIO;

// marsSeconds += 2160; // add 36 minutes (it works for some reason)

int days = (int)marsSeconds / 86400; // whole number of days

// remainder from factoring out the days
double secondsLeft = marsSeconds % 86400;

// whole number of hours
int hours = (int)(secondsLeft / 3600);

// remainder from factoring out the hours
secondsLeft %= 3600;

double minutes = secondsLeft / 60;

minutes += 36; // add 36 minutes (it works for some reason)

// needs to be here in case the minutes get rounded up to an hour
if (minutes >= 59.5) {
hours += 1;
minutes -= 60;

if (hours >= 24) {
days += 1;
hours -= 24;
}
}

System.out.print("Day " + days + ", ");
System.out.print(DF.format(hours) + ":");
System.out.println(DF.format(Math.abs(minutes))); // absolute value so negative number rounded doesn't show negative sign
}
}

My test cases (as .txt files):

Using their sample input:

346 12 28
393 06 40
390 19 50
984 02 25
674 21 29
435 13 07
15 04 12
539 00 50
40 01 20
69 03 11

And the output to that is:

Day 337, 18:40
Day 383, 08:28
Day 380, 23:07
Day 959, 05:28
Day 657, 20:17
Day 424, 13:15
Day 14, 19:35
Day 525, 09:32
Day 39, 01:37
Day 67, 09:48

Using their first judging test input:

477 09 44
19 22 59
120 02 48
390 09 45
880 23 24
797 15 27
809 14 34
242 19 49
313 05 46
168 00 59

And the output to that is:

Day 465, 08:27
Day 19, 11:28
Day 117, 02:28
Day 380, 13:18
Day 858, 17:04
Day 777, 11:43
Day 789, 03:34
Day 236, 16:58
Day 305, 08:10
Day 163, 19:33

And that is exactly the expected output.

Using their second judging test input:

225 11 38
917 10 12
57 01 49
70 19 19
31 05 57
463 10 43
63 11 07
205 07 08
119 10 26
703 14 12

And the output to that is:

Day 219, 19:19
Day 894, 05:44
Day 55, 15:46
Day 69, 00:55
Day 30, 11:35
Day 451, 17:55
Day 61, 21:11
Day 200, 03:05
Day 116, 10:31
Day 685, 19:35