-
-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
global-positioning-system
exercise (#444)
- Loading branch information
1 parent
d6e2316
commit 33a2836
Showing
8 changed files
with
428 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
exercises/practice/global-positioning-system/.docs/hints.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Hints | ||
|
||
## General | ||
|
||
- [Wikipedia's Definite Clause Grammar page](https://en.wikipedia.org/wiki/Definite_clause_grammar) gives a great overview of DCGs | ||
- The [Prolog DCG Primer](https://www.metalevel.at/prolog/dcg) has a very useful introduction to Prolog DCGs | ||
- The [SWIPL dcg/basics docs](https://www.swi-prolog.org/pldoc/doc/_SWI_/library/dcg/basics.pl) lists the built-in primitives you can use | ||
|
||
## 3. Support all whitespace (except newlines) | ||
|
||
- There is a [built-in primitive](https://www.swi-prolog.org/pldoc/doc/_SWI_/library/dcg/basics.pl) you can use for this | ||
|
||
## 4. Parse the latitude's hemisphere | ||
|
||
- DCG rules can have variables like regular facts or rules | ||
- DCG rules can have multiple declarations like regular facts or rules | ||
|
||
## 5. Parse the longitude's hemisphere | ||
|
||
- DCG rules can have variables like regular facts or rules | ||
- DCG rules can have multiple declarations like regular facts or rules | ||
|
||
## 6. Parse degrees | ||
|
||
- There is a [built-in primitive](https://www.swi-prolog.org/pldoc/doc/_SWI_/library/dcg/basics.pl) you can use for this | ||
|
||
## 7. Parse latitude degrees | ||
|
||
- You can re-use the `degrees` rule | ||
- The `{}//1` language construct can be used to invoke Prolog predicates from within a rule | ||
|
||
## 9. Parse latitude | ||
|
||
- The format for a latitude is: `<LATITUDE_DEGREES> <LATITUDE_HEMISPHERE>` | ||
- Re-use the rules you've already implemented | ||
|
||
## 10. Parse longitude | ||
|
||
- The format for a longitude is: `<LONGITUDE_DEGREES> <LONGITUDE_HEMISPHERE>` | ||
- Re-use the rules you've already implemented | ||
|
||
## 11. Parse coordinate | ||
|
||
- The format for a coordinate is: `<LATITUDE_DEGREES> <LATITUDE_HEMISPHERE>, <LONGITUDE_DEGREES> <LONGITUDE_HEMISPHERE>` | ||
- Re-use the rules you've already implemented |
151 changes: 151 additions & 0 deletions
151
exercises/practice/global-positioning-system/.docs/instructions.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
# Instructions | ||
|
||
Your task is to parse GPS coordinates. | ||
Each coordinate is formatted using the [Decimal Degrees format](https://en.wikipedia.org/wiki/Decimal_degrees) variant with explicit hemispheres: | ||
|
||
```text | ||
<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>`: E | ||
|
||
You have 11 tasks, in which you'll incrementally parse GPS coordinates. | ||
You'll be using Prolog's [Definite Clause Grammar](https://en.wikipedia.org/wiki/Definite_clause_grammar) (DCG) support, which are designed to parse structured text. | ||
|
||
````exercism/note | ||
To help you get started, the stub file already includes the [`dcg/basics` library](https://www.swi-prolog.org/pldoc/doc/_SWI_/library/dcg/basics.pl) via: | ||
```prolog | ||
:- use_module(library(dcg/basics)). | ||
``` | ||
```` | ||
|
||
## 1. Parse a comma | ||
|
||
Implement the `comma` rule to parse a single comma (`","`): | ||
|
||
```prolog | ||
?- string_codes(",", Codes), phrase(comma, Codes). | ||
``` | ||
|
||
## 2. Parse a space | ||
|
||
Implement the `space` rule to parse a single space (`" "`): | ||
|
||
```prolog | ||
?- string_codes(" ", Codes), phrase(space, Codes). | ||
``` | ||
|
||
## 3. Support all whitespace (except newlines) | ||
|
||
Modify the `space` rule to parse _all_ whitespace, except for newlines: | ||
|
||
```prolog | ||
?- string_codes("\t", Codes), phrase(space, Codes). | ||
?- string_codes("\n", Codes), phrase(space, Codes). | ||
false. | ||
``` | ||
|
||
## 4. Parse the latitude's hemisphere | ||
|
||
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: | ||
|
||
```prolog | ||
?- string_codes("N", Codes), phrase(latitude_hemisphere(Hemisphere), Codes). | ||
Hemisphere = north. | ||
``` | ||
|
||
## 5. Parse the longitude's hemisphere | ||
|
||
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: | ||
|
||
```prolog | ||
?- string_codes("E", Codes), phrase(longitude_hemisphere(Hemisphere), Codes). | ||
Hemisphere = east. | ||
``` | ||
|
||
## 6. Parse degrees | ||
|
||
The degrees of a longitude or latitude ire defined as a floating-point number. | ||
Implement the `degrees` rule to parse floating-point numbers: | ||
|
||
```prolog | ||
?- string_codes("748.012", Codes), phrase(degrees(Degrees), Codes). | ||
Degrees = 748.012. | ||
``` | ||
|
||
## 7. Parse latitude degrees | ||
|
||
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: | ||
|
||
```prolog | ||
?- string_codes("48.745", Codes), phrase(latitude_degrees(Degrees), Codes). | ||
Degrees = 48.745. | ||
?- string_codes("117.844", Codes), phrase(latitude_degrees(Degrees), Codes). | ||
false. | ||
``` | ||
|
||
## 8. Parse longitude degrees | ||
|
||
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: | ||
|
||
```prolog | ||
?- string_codes("178.773", Codes), phrase(longitude_degrees(Degrees), Codes). | ||
Degrees = 178.773. | ||
?- string_codes("-22.523", Codes), phrase(longitude_degrees(Degrees), Codes). | ||
false. | ||
``` | ||
|
||
## 9. Parse latitude | ||
|
||
Latitudes have two parts: their degrees and hemisphere, which are separated by a space. | ||
Implement the `latitude` rule to parse a latitude: | ||
|
||
```prolog | ||
?- string_codes("56.101 N", Codes), phrase(latitude(Degrees, Hemisphere), Codes). | ||
Degrees = 56.101, | ||
Hemisphere = north. | ||
``` | ||
|
||
## 10. Parse longitude | ||
|
||
Latitudes have two parts: their degrees and hemisphere, which are separated by a space. | ||
Implement the `latitude` rule to parse a latitude: | ||
|
||
```prolog | ||
?- string_codes("143.889 W", Codes), phrase(longitude(Degrees, Hemisphere), Codes). | ||
Degrees = 143.889, | ||
Hemisphere = west. | ||
``` | ||
|
||
## 11. Parse coordinate | ||
|
||
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): | ||
|
||
```prolog | ||
?- 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. | ||
``` |
6 changes: 6 additions & 0 deletions
6
exercises/practice/global-positioning-system/.docs/introduction.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Introduction | ||
|
||
You're a huge fan of [geocaching](https://en.wikipedia.org/wiki/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. |
17 changes: 17 additions & 0 deletions
17
exercises/practice/global-positioning-system/.meta/config.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"authors": [ | ||
"erikschierboom" | ||
], | ||
"files": { | ||
"solution": [ | ||
"global_positioning_system.pl" | ||
], | ||
"test": [ | ||
"global_positioning_system_tests.plt" | ||
], | ||
"example": [ | ||
".meta/global_positioning_system.example.pl" | ||
] | ||
}, | ||
"blurb": "Parse GPS coordinates into their individual components" | ||
} |
20 changes: 20 additions & 0 deletions
20
exercises/practice/global-positioning-system/.meta/global_positioning_system.example.pl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
:- use_module(library(dcg/basics)). | ||
|
||
comma --> ",". | ||
space --> white. | ||
|
||
latitude_hemisphere(north) --> "N". | ||
latitude_hemisphere(south) --> "S". | ||
|
||
longitude_hemisphere(east) --> "E". | ||
longitude_hemisphere(west) --> "W". | ||
|
||
degrees(Degrees) --> float(Degrees). | ||
latitude_degrees(Degrees) --> degrees(Degrees), { Degrees >= 0, Degrees =< 90 }. | ||
longitude_degrees(Degrees) --> degrees(Degrees), { Degrees >= 0, Degrees =< 180 }. | ||
|
||
latitude(Degrees, Hemisphere) --> latitude_degrees(Degrees), space, latitude_hemisphere(Hemisphere). | ||
longitude(Degrees, Hemisphere) --> longitude_degrees(Degrees), space, longitude_hemisphere(Hemisphere). | ||
|
||
coordinate(Latitude, LatitudeHemisphere, Longitude, LongitudeHemisphere) --> | ||
latitude(Latitude, LatitudeHemisphere), comma, space, longitude(Longitude, LongitudeHemisphere). |
16 changes: 16 additions & 0 deletions
16
exercises/practice/global-positioning-system/global_positioning_system.pl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
:- use_module(library(dcg/basics)). | ||
|
||
comma. | ||
space. | ||
|
||
latitude_hemisphere(Hemisphere). | ||
longitude_hemisphere(Hemisphere). | ||
|
||
degrees(Degrees). | ||
latitude_degrees(Degrees). | ||
longitude_degrees(Degrees). | ||
|
||
latitude(Degrees, Hemisphere). | ||
longitude(Degrees, Hemisphere). | ||
|
||
coordinate(Latitude, LatitudeHemisphere, Longitude, LongitudeHemisphere). |
Oops, something went wrong.