You're a huge fan of geocaching, which combines your love for the outdoors with a love for solving puzzles. Whilst the local geocaching website lists the GPS coordinates of all caches, it does not support creating an efficient route for gathering them. It so happens you have pathfinding software installed on your machine, but it uses a different GPS format from the geocaching website. To feed the data into the pathfinding software, you'll need to parse the degrees and hemisphere for both the latitude and longitude of each GPS coordinate on the website.
Your task is to parse GPS coordinates. Each coordinate is formatted using the Decimal Degrees format variant with explicit hemispheres:
<LATITUDE_DEGREES> <LATITUDE_HEMISPHERE>, <LONGITUDE_DEGREES> <LONGITUDE_HEMISPHERE>
These are the allowed values for each individual component:
<LATITUDE_DEGREES>
: a floating-point number in the range 0..90 (inclusive)<LATITUDE_HEMISPHERE>
: either N
or S
<LONGITUDE_DEGREES>
: a floating-point number in the range 0..180 (inclusive)<LONGITUDE_HEMISPHERE>
: either E
or W
For example, "48.8584 N, 2.2945 E"
parses into:
<LATITUDE_DEGREES>
: 48.8584<LATITUDE_HEMISPHERE>
: N<LONGITUDE_DEGREES>
: 2.2945<LONGITUDE_HEMISPHERE>
: EYou have 11 tasks, in which you'll incrementally parse GPS coordinates. You'll be using Prolog's Definite Clause Grammar (DCG) support, which are designed to parse structured text.
To help you get started, the stub file already includes the dcg/basics
library via:
:- use_module(library(dcg/basics)).
Implement the comma
rule to parse a single comma (","
):
?- string_codes(",", Codes), phrase(comma, Codes).
Implement the space
rule to parse a single space (" "
):
?- string_codes(" ", Codes), phrase(space, Codes).
Modify the space
rule to parse all whitespace, except for newlines:
?- string_codes("\t", Codes), phrase(space, Codes).
?- string_codes("\n", Codes), phrase(space, Codes).
false.
The hemisphere of the latitude can be either "N"
or "S"
, which should be parsed to the north
or south
atom.
Implement the latitude_hemisphere
rule to parse the latitude's hemisphere:
?- string_codes("N", Codes), phrase(latitude_hemisphere(Hemisphere), Codes).
Hemisphere = north.
The hemisphere of the longitude can be either "E"
or "W"
, which should be parsed to the east
or west
atom.
Implement the longitude_hemisphere
rule to parse the longitude's hemisphere:
?- string_codes("E", Codes), phrase(longitude_hemisphere(Hemisphere), Codes).
Hemisphere = east.
The degrees of a longitude or latitude ire defined as a floating-point number.
Implement the degrees
rule to parse floating-point numbers:
?- string_codes("748.012", Codes), phrase(degrees(Degrees), Codes).
Degrees = 748.012.
Latitude degrees are not just floating-point numbers, but floating-point numbers in the range 0..90 (inclusive).
Implement the latitude_degrees
rule to parse latitude degrees using the above range:
?- string_codes("48.745", Codes), phrase(latitude_degrees(Degrees), Codes).
Degrees = 48.745.
?- string_codes("117.844", Codes), phrase(latitude_degrees(Degrees), Codes).
false.
Longitude degrees are not just floating-point numbers, but floating-point numbers in the range 0..180 (inclusive).
Implement the longitude_degrees
rule to parse longitude degrees using the above range:
?- string_codes("178.773", Codes), phrase(longitude_degrees(Degrees), Codes).
Degrees = 178.773.
?- string_codes("-22.523", Codes), phrase(longitude_degrees(Degrees), Codes).
false.
Latitudes have two parts: their degrees and hemisphere, which are separated by a space.
Implement the latitude
rule to parse a latitude:
?- string_codes("56.101 N", Codes), phrase(latitude(Degrees, Hemisphere), Codes).
Degrees = 56.101,
Hemisphere = north.
Latitudes have two parts: their degrees and hemisphere, which are separated by a space.
Implement the latitude
rule to parse a latitude:
?- string_codes("143.889 W", Codes), phrase(longitude(Degrees, Hemisphere), Codes).
Degrees = 143.889,
Hemisphere = west.
Coordinates have two parts: their latitude and longitude, which are separated by a comma followed by a space.
Implement the coordinate
rule to parse both the latitude (degrees and hemisphere):
?- string_codes("48.8584 N, 2.2945 E", Codes), phrase(coordinate(Latitude, LatitudeHemisphere, Longitude, LongitudeHemisphere), Codes).
Latitude = 48.8584,
LatitudeHemisphere = north,
Longitude = 2.2945,
LongitudeHemisphere = east.
Sign up to Exercism to learn and master Prolog with 109 exercises, and real human mentoring, all for free.