學習軌道
/
F#
F#
/
練習
/
Tisbury 尋寶之旅
Tisbury 尋寶之旅

Tisbury 尋寶之旅

學習練習

簡介

元組

元組是一種_不可變_的群組,由未命名但有序的值組成。 元組可以容納任何(或多個)資料型態,也包括其他元組。

元組的定義方式,是在(和)字元之間以逗號分隔的值:(<element_1>, ... , <element_n>)。

("one", 2) // Tuple pair (2 values)
("one", 2, true) // Tuple triplet (3 values)

只有長度相同、型別相同(且順序相同)的元組才能互相比較。 元組具有結構相等性,也就是說,只有在所有值都相等時,兩個元組才會相等。

(1, 2) = (1, 2) // Same length, same types, same values, same order
// => true

(1, 2) = (2, 1) // Same length, same types, same values, different order
// => false

(1, 2) = (1, "2") // Same length, different types
// compiler error

(1, 2) = (1, 2, 3) // Different length
// compiler error

你可以用三種方式從元組中取出值:

  • fst 和 snd 函式
  • 元組解構
  • 模式比對
let person = ("Jordan", 170)

// Option 1: fst/snd
let name1 = fst person
let length2 = snd person

// Option 2: deconstruction
let (name2, length2) = person
// => name2 = "Jordan"
// => length2 = 170

// Option 3: pattern matching
match person with
| name3, length3 -> printf "%s: %d" name3 length3

說明

Azara 和 Rui 是隊友,正一起參加一場海盜主題的尋寶比賽。 其中一人有一份標著地圖座標的寶藏清單,另一人則有一份同樣標著地圖座標的地點名稱清單。 他們還拿到空白地圖,上頭標著「你在這裡」的起點。

Azara 的清單 Rui 的清單
Treasure Coordinates
Amethyst Octopus 1F
Angry Monkey Figurine 5B
Antique Glass Fishnet Float 3D
Brass Spyglass 4B
Carved Wooden Elephant 8C
Crystal Crab 6A
Glass Starfish 6D
Model Ship in Large Bottle 8A
Pirate Flag 7F
Robot Parrot 1C
Scrimshaw Whale's Tooth 2A
Silver Seahorse 4E
Vintage Pirate Hat 7E
Location Name Coordinates Quandrant
Seaside Cottages (1, 'C') Blue
Aqua Lagoon (Island of Mystery) (1, 'F') Yellow
Deserted Docks (2, 'A') Blue
Spiky Rocks (3, 'D') Yellow
Abandoned Lighthouse (4, 'B') Blue
Hidden Spring (Island of Mystery) (4, 'E') Yellow
Stormy Breakwater (5, 'B') Purple
Old Schooner (6, 'A') Purple
Tangled Seaweed Patch (6, 'D') Orange
Quiet Inlet (Island of Mystery) (7, 'E') Orange
Windswept Hilltop (Island of Mystery) (7, 'F') Orange
Harbor Managers Office (8, 'A') Purple
Foggy Seacave (8, 'C') Purple

不過情況有點混亂:Azara 的座標格式和排序方式似乎和 Rui 的不同,他們得在兩份清單之間來回查看,才能弄清楚哪些寶藏對應哪些地點。 身為剛入門的 F# 愛好者,他們來找你幫忙寫一個小程式(其實就是幾個函式),好把尋寶資訊整理得更有條理。

1. 擷取座標

實作getCooordinate()函式,它會接收 Azara 清單中的一個(treasure, coordinate)配對,並只回傳擷取出的地圖座標。

getCoordinate ("Scrimshaw Whale's Tooth", "2A")
// "2A"

2. 格式化座標

實作convertCoordinate()函式,它會接收格式為「2A」的座標,並回傳格式為(2, 'A')的元組。

convertCoordinate "2A"
// (2, 'A')

3. 比對座標

實作compareRecords()函式,它會接收一個(treasure, coordinate)配對和一個(location, coordinate, quadrant)記錄,並比較兩者的座標。 如果座標「相符」,回傳 true;如果不同,則回傳 false。 視需要重新格式化座標,以便準確比較。

compareRecords ("Brass Spyglass", "4B") ("Seaside Cottages", (1, 'C'), "blue")
// false

compareRecords ("Model Ship in Large Bottle", "8A") ("Harbor Managers Office", (8, 'A'), "purple")
// true

4. 合併相符的記錄

實作createrecord()函式,它會接收 Azara 清單中的一個(treasure, coordinate)配對和 Rui 清單中的一個(location, coordinate, quadrant)記錄,並且在座標相符時回傳(coordinate, location, quadrant, treasure)。 如果座標_不_相符,則回傳形狀相同、但內容填滿""的元組。 視需要重新格式化座標,以便準確比較。

createRecord ("Brass Spyglass", "4B") ("Abandoned Lighthouse", (4, 'B'), "Blue")
// ("4B", "Abandoned Lighthouse", "Blue", "Brass Spyglass")

createRecord ("Brass Spyglass", "4B") ("Seaside Cottages", (1, 'C'), "Blue")
// ("", "", "", "")
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
F# Exercism

準備好開始 Tisbury 尋寶之旅 了嗎?

註冊 Exercism,透過 18 個概念148 個練習 和真人引導來學習並精通 F#,全部免費。