The aim of this puzzle is to find the closest defibrillators in a list. The main difficulty is that for each defibrillator of the list are given not only coordinates, but also a lot of useless information. That is why this puzzle involves a lot of string manipulation.
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h> #include <float.h> // represents a defibrillator struct defib { char* name; double lon; double lat; }; /* Returns the distance between a point A and a point B given their lat(itude) and lon(gitude)*/ double distance(double longA, double latA, double longB, double latB){ double x = (longB-longA)*cos((latA+latB)/2); double y = latB - latA; return (sqrt(x*x+y*y) * 6371.0); } // Parses a double in string 'str' using atof, and replacing , by . if needed double toDouble(char *str) { for(char *iter = str; *iter != '\0'; iter++) if (*iter == ',') *iter = '.'; return atof(str); } // Returns a pointer on next char 'c' in 'str' char *goToNext(char c, char *str) { for(; *str != c; str++); return str; } /* Reads the line 'str', and stores relevant fields in 'defib' pretty awful implementation, but necessary for speed*/ void getDefib(char *str, struct defib *res) { str = goToNext(';', str); res->name = ++str; for (int k = 0; k < 3; k++) { str = goToNext(';', str); *str = '\0'; str++; } char *lon = str; str = goToNext(',', str); *str = '.'; str = goToNext(';', str); char *lat = ++str; str = goToNext(',', str); *str = '.'; res->lon = atof(lon); res->lat = atof(lat); } int main(int argc, char** argv) { char strLon[50]; char strLat[50]; int N; scanf("%s\n%s\n%d\n", strLon, strLat, &N); double lon = toDouble(strLon); double lat = toDouble(strLat); // simple linear search amongst defibrillators double min = DBL_MAX; char output[100]; double d; char line[256]; struct defib res; for (int i = 0; i < N; i++) { getDefib(fgets(line, 256, stdin), &res); d = distance(lon, lat, res.lon, res.lat); if (d < min) { min = d; strcpy(output, res.name); } } printf("%s", output); return EXIT_SUCCESS; }
import java.util.*; import java.math.*; class Solution { /** Returns the distance between a point A and a point B * @param longA longitude of point A * @param latA latitude of point A * @param longB longitude of point B * @param latB latitude of point B * @return distance between A and B */ private static double distance(double longA, double latA, double longB, double latB){ double x = (longB-longA)*Math.cos((latA+latB)/2); double y = latB - latA; return Math.sqrt(Math.pow(x,2) + Math.pow(y,2)) * 6371; } public static void main(String args[]) { Scanner in = new Scanner(System.in); /* as the latitude and the longitude are given with , instead of . it isn't possible to use nextFloat()*/ Double lon = new Double(in.next().replace(',', '.')); Double lat = new Double(in.next().replace(',', '.')); int N = in.nextInt(); in.nextLine(); // simple min search amongst defibrillators double min = Double.POSITIVE_INFINITY; String res = ""; Double d; for (int i = 0; i < N; i++) { String[] defib = in.nextLine().replace(',', '.').split(";"); d = distance(lon, lat, new Double(defib[4]), new Double(defib[5])); if (d < min) { min = d; res = defib[1]; } } System.out.println(res); } }
import math def distance (longA, latA, longB, latB): ''' return the distance between point A and point B given their latitude and longitude ''' x = (longB-longA)*math.cos((latA+latB)/2) y = latB-latA return 6371 * math.sqrt(x*x+y*y) lon, lat, N = float(input().replace(",", ".")), float(input().replace(",", ".")), int(input()) # linear search amongst defibrillators min, res = None, None for i in range(N): defib = input().replace(",", ".").split(";") d = distance(lon, lat, float(defib[4]), float(defib[5])) if (min == None) or (d < min): min, res = d, defib[1] print(res)