學習軌道
/
Elm
Elm
/
練習
/
Blorkemon 卡片
Blorkemon 卡片

Blorkemon 卡片

學習練習

簡介

比較

相等性

Elm 的型別可以用相等運算子(==)來檢查是否「相同」。 不等運算子則是(/=)(不是許多語言裡的!=)。 相等運算子可用於字面值、元組、記錄和自訂型別。

1 == 2
    --> False

1 /= 2
    --> True

(1, 2) == (2, 1)
    --> False

type alias MyRecord = { myInt : Int, myStrings : List String }
a : MyRecord
a = MyRecord (1 + 1) ["hello world"]

type alias MyOtherRecord = { myInt : Int, myStrings : List String }
myStrings =  (String.join " " ["hello", "world"]) :: []
b : MyOtherRecord
b = { myInt = 2, myStrings = myStrings}

a == b
    --> True

請注意,你絕對不該比較函式,因為這會讓程式在執行時崩潰。

大小比較

比較運算子(<)、(<=)、(>)、(>=)以及函式min、max、compare可用於comparable型別。 comparable是一種特殊的型別,它把所有可以互相比較的內建型別歸為一類:數字、字元、字串、由可比較項目組成的陣列,以及由可比較項目組成的元組。

1 < 1 + 1
    --> True

'x' < 'X'
    --> False

"abc" < "abz"
    --> True

"abc" < "abcd"
    --> True

"abc" < "b"
    --> True

min [1 , 2, 9000] [10]
    --> [1 , 2, 9000]

min (1, "hello") (3, "bye")
    --> (1, "hello")

其他型別的值,例如記錄或自訂型別,則無法直接比較。

有些內建型別要求其內容必須是comparable,例如Set或Dict的鍵,因為它們的結構依賴內部的排序。

comparable值的陣列可以用List.sort排序;而由可映射為可比較值的值所組成的陣列,則可以用List.sortBy排序。 如果你需要階層式的排序(先依某個屬性排序,再以另一個屬性打破平手),元組或陣列也可以搭配List.sortBy使用,因為元組和陣列是依字典順序排序的。

List.sort ["hi", "hello", "bye", "goodbye"]
    --> ["bye", "goodbye", "hello", "hi"]

List.sortBy String.length ["hi", "hello", "bye", "goodbye"]
    --> ["hi", "bye", "hello", "goodbye"]

-- sort by length, then alphabetically
List.sortBy (\str -> (String.length str, str)) ["hi", "mum", "hello", "sis", "bye", "dad"]
    --> ["hi", "bye", "dad", "mum", "sis", "hello"]

函式compare接受兩個comparable值,並回傳一個Order。 Order是一種型別,可以用單一操作判斷某個值是否大於(GT)、等於(EQ)或小於(LT)另一個值。

compare 1 2
    --> LT

compare "" ""
    --> EQ

compare [12] []
    --> GT

我們可以為任意型別建構比較函式,舉例來說,可以搭配List.sortWith來排序:

type Color = Red | Green | Blue

compareColors : Color -> Color -> Order
compareColors a b =
  case (a, b) of
    (Red, Red) -> EQ
    (Red, _) -> LT
    (_, Red) -> GT
    (Green, Green) -> EQ
    (Green, _) -> LT
    (_, Green) -> GT
    (Blue, Blue) -> EQ

List.sortWith compareColors [Blue, Red, Green, Green, Blue]
    --> [Red, Green, Green, Blue, Blue]

說明

你突然感受到一陣懷舊之情,強烈地想翻出你那些舊的 Blorkemon™️ 卡。Blorkemon™️ 卡是一款很棒的經典老派卡牌交換遊戲。每張Card上都畫著一隻 Blorkemon™️ 怪物,還有一個攻擊威力等級,運氣好的話,這張卡甚至可能還是閃亮的。

1. 比較威力等級

每張 Blorkemon™️ 卡看起來都比下一張更強大,但你最好還是確認一下。

實作isMorePowerful函式。如果它第一個引數的卡威力嚴格高於另一張,就回傳True,否則回傳False。

newthree = Card "Newthree" 120 False
scientuna = Card "Scientuna" 6 True

isMorePowerful newthree scientuna
    --> True

2. 找出最高威力

手握滿滿的 Blorkemon™️ 卡,你應該能準備出最具毀滅性的攻擊。

實作maxPower函式,它會回傳兩張卡中最高的威力等級。

maxPower newthree scientuna
    --> 120

3. 將卡片排序

你好像記得每種 Blorkemon™️ 至少都有一張卡,但距離你上次確認已經過了好一陣子,你應該把卡片排序,好跟 Pulpapedia 上的官方清單比對一下。

實作sortByMonsterName函式,它應該接收一個Cards陣列,並回傳依怪物名稱排序的陣列。

sortByMonsterName [newthree, scientuna]
    --> [Card "Newthree" 120 False, Card "Scientuna" 6 True]

4. 最酷的卡片優先

Blorkemon™️ 是有史以來最酷的東西。你可不是隨口說說,你有一套科學方法可以證明。

實作sortByCoolness函式,它會將卡片陣列排序,把最酷的排在最前面。一張卡的酷炫度首先取決於它的閃亮度:所有閃亮卡都比其他卡酷得多。第二個因素則是威力等級,越高越好。

sortByCoolness [newthree, scientuna]
    --> [Card "Scientuna" 6 True, Card "Newthree" 120 False]

5. 閃亮威力

閃亮不只是好看而已,在威力相當的 Blorkemon™️ 對戰中,閃亮的那一方永遠會勝出。這就叫做閃亮威力。

實作compareShinyPower函式,它將這個特性化為程式碼。兩張卡的Order在威力等級不同時由威力等級決定,但如果威力相同,閃亮的卡會更勝一籌。

compareShinyPower newthree scientuna
    --> GT

6. 下注吧

在 Blorkemon™️ 卡的對戰中,什麼事都可能發生,但威力更高的卡仍有較高的勝算。

實作expectedWinner函式,它會回傳最被看好會獲勝的怪物名稱,判斷依據是compareShinyPower的排序結果。這個函式應該回傳預期贏家的怪物名稱,如果兩個對手擁有相同的閃亮威力,則回傳 "too close to call"。

expectedWinner newthree scientuna
    --> "Newthree"
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Elm Exercism

準備好開始 Blorkemon 卡片 了嗎?

註冊 Exercism,透過 28 個概念110 個練習 和真人引導來學習並精通 Elm,全部免費。