學習軌道
/
Prolog
Prolog
/
練習
/
全球定位系統
全球定位系統

全球定位系統

中等

簡介

你是 geocaching 的超級粉絲,這項活動結合了你對戶外活動的熱愛,以及對解謎的熱愛。 雖然當地的 geocaching 網站列出了所有寶藏的 GPS 座標,卻_不_支援規劃出一條有效率的路線來收集它們。 正好你的電腦上安裝了路徑規劃軟體,但它使用的 GPS 格式和 geocaching 網站不同。 為了把資料餵給這套路徑規劃軟體,你需要解析網站上每個 GPS 座標的緯度和經度的度數與半球。

說明

你的任務是解析 GPS 座標。 每個座標都使用帶有明確半球標示的十進位度數格式變體來表示:

<LATITUDE_DEGREES> <LATITUDE_HEMISPHERE>, <LONGITUDE_DEGREES> <LONGITUDE_HEMISPHERE>

以下是每個元件的允許值:

  • <LATITUDE_DEGREES>:範圍在 0 到 90(含)的浮點數
  • <LATITUDE_HEMISPHERE>:N或S
  • <LONGITUDE_DEGREES>:範圍在 0 到 180(含)的浮點數
  • <LONGITUDE_HEMISPHERE>:E或W

例如,"48.8584 N, 2.2945 E"會解析成:

  • <LATITUDE_DEGREES>:48.8584
  • <LATITUDE_HEMISPHERE>:N
  • <LONGITUDE_DEGREES>:2.2945
  • <LONGITUDE_HEMISPHERE>:E

這個練習共有 11 個任務,你會逐步解析 GPS 座標。 你會使用 Prolog 的定子句文法(DCG)支援,這是專門設計來解析結構化文字的。

Note

為了幫助你開始,起始檔案已經透過以下方式引入了 dcg/basics 函式庫:

:- use_module(library(dcg/basics)).

1. 解析逗號

實作 comma 規則來解析單一個逗號(","):

?- string_codes(",", Codes), phrase(comma, Codes).

2. 解析空格

實作 space 規則來解析單一個空格(" "):

?- string_codes(" ", Codes), phrase(space, Codes).

3. 支援所有空白(換行除外)

修改 space 規則,讓它能解析_所有_空白,但換行除外:

?- string_codes("\t", Codes), phrase(space, Codes).

?- string_codes("\n", Codes), phrase(space, Codes).
false.

4. 解析緯度的半球標示

緯度的半球標示可以是"N"或"S",且應解析成north或south原子。 實作 latitude_hemisphere 規則來解析緯度的半球標示:

?- string_codes("N", Codes), phrase(latitude_hemisphere(Hemisphere), Codes).
Hemisphere = north.

5. 解析經度的半球標示

經度的半球標示可以是"E"或"W",且應解析成east或west原子。 實作 longitude_hemisphere 規則來解析經度的半球標示:

?- string_codes("E", Codes), phrase(longitude_hemisphere(Hemisphere), Codes).
Hemisphere = east.

6. 解析度數

經度或緯度的度數定義為浮點數。 實作 degrees 規則來解析浮點數:

?- string_codes("748.012", Codes), phrase(degrees(Degrees), Codes).
Degrees = 748.012.

7. 解析緯度度數

緯度度數不只是浮點數,而是範圍在 0 到 90(含)的浮點數。 實作 latitude_degrees 規則,使用上述範圍來解析緯度度數:

?- 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. 解析經度度數

經度度數不只是浮點數,而是範圍在 0 到 180(含)的浮點數。 實作 longitude_degrees 規則,使用上述範圍來解析經度度數:

?- 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. 解析緯度

緯度有兩個部分:度數和半球標示,兩者以空格分隔。 實作 latitude 規則來解析緯度:

?- string_codes("56.101 N", Codes), phrase(latitude(Degrees, Hemisphere), Codes).
Degrees = 56.101,
Hemisphere = north.

10. 解析經度

經度有兩個部分:度數和半球標示,兩者以空格分隔。 實作 longitude 規則來解析經度:

?- string_codes("143.889 W", Codes), phrase(longitude(Degrees, Hemisphere), Codes).
Degrees = 143.889,
Hemisphere = west.

11. 解析座標

座標有兩個部分:緯度和經度,兩者以逗號加上一個空格分隔。 實作 coordinate 規則,同時解析緯度(度數和半球標示)和經度:

?- 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.
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Prolog Exercism

準備好開始 全球定位系統 了嗎?

註冊 Exercism,透過 109 個練習 和真人引導來學習並精通 Prolog,全部免費。