The challenge
In John’s car the GPS records every s
seconds the distance travelled from an origin (distances are measured in an arbitrary but consistent unit). For example, below is part of a record with s = 15
:
x = [0.0, 0.19, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25]
The sections are:
0.0-0.19, 0.19-0.5, 0.5-0.75, 0.75-1.0, 1.0-1.25, 1.25-1.50, 1.5-1.75, 1.75-2.0, 2.0-2.25
We can calculate John’s average hourly speed on every section and we get:
[45.6, 74.4, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0]
Given s
and x
the task is to return as an integer the *floor*
of the maximum average speed per hour obtained on the sections of x
. If x length is less than or equal to 1 return `` since the car didn’t move.
Example:
with the above data your function gps(s, x)
should return 74
Note
With floats it can happen that results depends on the operations order. To calculate hourly speed you can use:
(3600 * delta_distance) / s
.
The solution in Java code
Option 1:
import java.util.*;
import java.util.stream.*;
public class GpsSpeed {
public static int gps(int s, double[] x) {
double maxSpeed = IntStream
.range(0, x.length - 1)
.mapToDouble(i -> (x[i+1] - x[i]) * 3600.0 / (double) s )
.max().orElse(0.0);
return (int) Math.floor(maxSpeed);
}
}
Option 2:
public class GpsSpeed {
public static int gps(int s, double[] x) {
double maxDiff = 0.0;
for(int i = 0; i < x.length -1; i++){
maxDiff = Math.max(x[i+1] - x[i], maxDiff);
}
return (int)Math.floor(maxDiff*3600.0/s);
}
}
Option 3:
public class GpsSpeed {
public static int gps(int s, double[] x) {
int maxSpeed = 0;
for ( int i=0; i<x.length-1; i++ ) {
int avrSpeed = (int) ( 3600 * ( x[i+1] - x[i] ) / s );
maxSpeed = ( maxSpeed < avrSpeed ) ? avrSpeed : maxSpeed;
}
return maxSpeed;
}
}
Test cases to validate our solution
import static org.junit.Assert.*;
import org.junit.Test;
public class GpsSpeedTest {
private static void testing(long actual, long expected) {
assertEquals(expected, actual);
}
@Test
public void test1() {
System.out.println("Fixed Tests: gps");
double[] x = new double[] {0.0, 0.23, 0.46, 0.69, 0.92, 1.15, 1.38, 1.61};
testing(GpsSpeed.gps(20, x), 41);
x = new double[] {0.0, 0.11, 0.22, 0.33, 0.44, 0.65, 1.08, 1.26, 1.68, 1.89, 2.1, 2.31, 2.52, 3.25};
testing(GpsSpeed.gps(12, x), 219);
x = new double[] {0.0, 0.18, 0.36, 0.54, 0.72, 1.05, 1.26, 1.47, 1.92, 2.16, 2.4, 2.64, 2.88, 3.12, 3.36, 3.6, 3.84};
testing(GpsSpeed.gps(20, x), 80);
}
}