Coding competitions frequently feature problems for which you are given one set of time units and ask to produce another. Consider, for example, the Lockheed Martin problem "Mission to Mars," in which we are given a distance in millions of miles (the first number on each line) between Earth and Mars and a speed in miles per hour (the second number on each line) and ask to print the number of days, hours, minutes and seconds it would take to travel that distance.
The input and output files for this problem are shown below:
Sample Input:
3
34.8 36000
250 36000.1
150 23500
Sample Output:
Time to Mars: 40 days, 6 hours, 40 minutes, 0 seconds
Time to Mars: 289 days, 8 hours, 25 minutes, 31 seconds
Time to Mars: 265 days, 22 hours, 58 minutes, 43 seconds
You are encouraged to try this problem right now before proceeding with this chapter. You may find it surprisingly tricky. The issue you will run into is that because the input numbers can be in integer or decimal format, you will produce rounding errors in your solution that are frequently associated with decimal arithmetic. Attempts to get around these errors with Math.round() or by casting will not succeed. The video, below, shows how to avoid these traps and produce the right solution.
In summary, here is the right algorithm to solve this problem. Notice how we convert our input data to seconds at the beginning and only use integer arithmetic throughout the rest of the method.
private static void calculate(double distance, double speed) {
int remainingSeconds = (int)Math.round((distance*1000000)/speed*3600); // (miles / miles/hr) * 3600 = seconds
int day = remainingSeconds / (24 * 3600);
remainingSeconds = remainingSeconds % (24 * 3600); // take out the days
int hour = remainingSeconds / 3600;
remainingSeconds %= 3600; // take out the hours
int minutes = remainingSeconds / 60 ;
remainingSeconds %= 60; // take out the minutes
int seconds = remainingSeconds;
System.out.println("Time to Mars: " + day + " days, " + hour + " hours, "
+ minutes + " minutes, " + seconds + " seconds");
}
When converting money units, avoid the temptation to use floating point arithmetic. Instead, if amounts are given in dollars and cents, multiply the input data by 100 and use integer arithmetic for all calculations. Translate back to dollars and cents afterwards if necessary. For a good example of this, try the Lockheed Martin problem, "Where's My Change," which can be found on their CodeQuest Academy website.
The solution to this problem is shown below.
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int trials = Integer.parseInt(scan.nextLine());
for (int i = 0; i < trials ; i++) {
double money = Double.parseDouble(scan.nextLine());
int pennies = (int)(money*100);
makeChange(pennies);
}
}
private static void makeChange(int pennies) {
List<Integer> denom = new ArrayList<>(Arrays.asList(10000, 5000, 2000,
1000, 500, 200, 100, 25, 10, 5, 1));
String answer = "";
for (int i = 0; i < denom.size(); i++) {
answer += pennies / denom.get(i);
pennies %= denom.get(i);
System.out.println(answer);
}
}
}