トラック
/
Elm
Elm
/
演習
/
Gotta Snatch'Em All
Gotta Snatch'Em All

Gotta Snatch'Em All

学習演習

はじめに

Set

Set aは、型aの一意な値の並びです。 値はcomparable型である必要があります(Int、Float、Time、Char、String、およびcomparable型のタプルやリスト)。

Set.toListとSet.fromListを使うと、リストと集合を相互に変換できます。 Setの内部構造のため、Set.fromListから得られるリストはソートされていることが保証されています。

Set.fromList [2, 3, 3, 3, 1, 1, 2]
    --> Set.fromList [1, 2, 3]

Set.toList (Set.fromList [2, 3, 3, 3, 1, 1, 2])
    --> [1, 2, 3]

Set.empty、Set.singleton、Set.insert、Set.removeを使うと、集合を作成して要素を追加できます。

Set.empty
    --> Set.fromList []

Set.singleton "hi"
    --> Set.fromList ["hi"]

eightyEight = Set.singleton 88

Set.insert 88 eightyEight
    --> Set.fromList [88]

Set.insert 89 eightyEight
    --> Set.fromList [88, 89]

Set.remove 88 eightyEight
    --> Set.fromList []

Set.remove 89 eightyEight
    --> Set.fromList [88]

Set.member、Set.isEmpty、Set.sizeという関数を使うと、集合の中身を調べられます。

Set.member 88 eightyEight
    --> True

Set.isEmpty eightyEight
    --> False

Set.size eightyEight
    --> 1

集合はSet.union、Set.intersect、Set.diffで組み合わせることができます。

a = Set.fromList [1, 10, 100]
b = Set.fromList [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Set.union a b
    --> Set.fromList [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100]

Set.intersect a b
    --> Set.fromList [1, 10]

Set.diff a b
    --> Set.fromList [100]

Set.diff b a
    --> Set.fromList [2, 3, 4, 5, 6, 7, 8, 9]

集合を絞り込んだり、分割したりすることもできます。

even n = modBy 2 n == 0

Set.filter even b
    --> Set.fromList [2, 4, 6, 8, 10]

Set.partition even b
    --> (Set.fromList [2, 4, 6, 8, 10], Set.fromList [1, 3, 5, 7, 9])

説明

Blorkemon™️のカードへの懐かしさはとどまるところを知らず、また集め始めてしまいましたね。友人たちも巻き込んでいます。

この演習では、CardのコレクションはSet Cardで表します。というのも、存在するカードをすべて集めることが目標なら、重複したカードは重要ではないからです。

1. コレクションを始めよう

友人たちにもBlorkemon™️の熱狂に加わってほしいですよね。その一番の方法は、カードを1枚あげてコレクションのきっかけを作ることです。

newCollectionを実装しましょう。これはカードをコレクションに変換します。

newCollection "Newthree"
    --> Set.fromList ["Newthree"]

2. コレクションを育てよう

コレクションができると、それは独りでに生き始め、育てていく必要があります。

addCardを実装しましょう。これはCardとコレクションを受け取り、2つの値を持つTupleを返します。1つはCardがすでにコレクションに入っていたかを示すBool、もう1つはカードを追加したコレクションです。

addCard "Scientuna" (Set.fromList ["Newthree"])
    --> (False, Set.fromList ["Newthree", "Scientuna"])

3. 交換を始めよう

友人たちがまたBlorkemon™️に夢中になったので、カードを交換して自分のコレクションを育てられます。

すべての交換が価値があるわけでも、そもそもできるわけでもありません。持っていないカードは交換に出せませんし、すでに持っているカードと交換するべきでもありません。

tradeCardを実装しましょう。これは交換する2枚のカード(自分のものと相手のもの)と、現在のコレクションを受け取ります。戻り値は2つの値を持つTupleです。1つはその交換が可能で価値があるかを示すBool、もう1つは交換した場合に最終的に手に入るコレクションです(実際には不可能であっても)。

tradeCard "Scientuna" "Newthree" (Set.fromList ["Scientuna"])
    --> (True, Set.fromList ["Newthree"])

4. それぞれ1枚しか存在しない

フリーマーケットで古いカードの隠し場所を見つけました。カードを並べ替えて重複を取り除き、そのリストと自分のコレクションを比べる必要があります。

removeDuplicatesを実装しましょう。これはカードのリストを並べ替え、並べ替え済みで重複のないカードのリストを返します。

removeDuplicates ["Newthree", "Newthree", "Newthree", "Scientuna"]
    --> ["Newthree", "Scientuna"]

5. 相手が持っていないカード

自分のコレクションを誇りに思う時です。

extraCardsを実装しましょう。これは自分のコレクションと他のコレクションを受け取り、他のコレクションが持っていないカードの数を返します。

extraCards (Set.fromList ["Scientuna"]) (Set.fromList ["Newthree", "Scientuna"])
    --> 0

6. みんなが持っているカード

Blorkemon™️好きの友人たちと集まって、どのカードが一番よくあるのか気になりました。

boringCardsを実装しましょう。これはコレクションのリストを受け取り、すべてのコレクションが持っているカードを並べ替えたリストを返します。

boringCards [Set.fromList ["Scientuna"], Set.fromList ["Newthree", "Scientuna"]]
    --> ["Scientuna"]

7. すべてのカード

あなたと友人たちは、合わせてBlorkemon™️のカードを全部持っているでしょうか?

totalCardsを実装しましょう。これはコレクションのリストを受け取り、すべてのコレクションにある異なるカードの合計数を返します。

totalCards [Set.fromList ["Scientuna"], Set.fromList ["Newthree", "Scientuna"]]
    --> 2

8. キラキラで勝負を決めよう

もうすぐ甥っ子が遊びに来ます。彼を驚かせたくなりました。子どもはキラキラしたものが好きですよね? Blorkemon™️のカードはキラキラにできるんです!

splitShinyCardsを実装しましょう。これはコレクションを受け取り、2つの並べ替え済みカードリストを持つTupleを返します。1つは"Shiny"で始まるすべてのカード、もう1つはそれ以外のカードです。

splitShinyCards (Set.fromList ["Newthree", "Scientuna", "Shiny Scientuna"])
    --> (["Shiny Scientuna"], ["Newthree", "Scientuna"])
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Elm Exercism

Gotta Snatch'Em Allを始める準備はできましたか?

Exercismに登録すれば、28個のコンセプト110個の演習、そして本物の人間によるメンタリングとともに、Elmを学んでマスターできます。すべて無料です。