MapSet은 고유한 값들의 모음으로, Elixir에서 집합을 나타내요.
어떤 종류의 값이든 담을 수 있고, 순서라는 개념은 없어요.
Set 모듈도 존재하지만, MapSet을 쓰도록 권장되면서 더 이상 사용되지 않아요.
MapSet.new/0, MapSet.new/1, MapSet.new/2로 집합을 만들 수 있고, MapSet.to_list/1로 배열로 바꿀 수 있어요.
MapSet.new()
# => MapSet.new([])
MapSet.new([2, 3, 3, 3, 1, 1, 2, "hello"])
# => MapSet.new([1, 2, 3, "hello"])
MapSet.new([2, 3, 3, 3, 1, 1, 2], fn n -> 10 * n end)
# => MapSet.new([10, 20, 30])
[2, 3, 3, 3, 1, 1, 2] |> MapSet.new() |> MapSet.to_list()
# => [1, 2, 3]
MapSet에는 순서라는 개념이 없기 때문에, MapSet.to_list/1이 정렬된 배열을 반환한다고 보장할 수는 없어요.
MapSet.put/2와 MapSet.delete/2로 원소를 추가하거나 삭제할 수 있어요.
MapSet.size/1, MapSet.member?/2 함수로 집합의 내용을 확인할 수 있고, MapSet.equal?/2, MapSet.subset?/2, MapSet.disjoint?/2로 집합을 비교할 수 있어요.
a = MapSet.new([1, 10])
b = MapSet.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
MapSet.size(b)
# => 10
MapSet.member?(a, 10)
# => true
MapSet.subset?(a, b)
# => true
MapSet.disjoint?(a, b)
# => false
MapSet은 MapSet.union/2, MapSet.intersection/2, MapSet.difference/2, MapSet.symmetric_difference/2로 결합할 수 있어요.
a = MapSet.new([1, 10, 100])
b = MapSet.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
MapSet.union(a, b)
# => MapSet.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100])
MapSet.intersection(a, b)
# => MapSet.new([1, 10])
MapSet.difference(a, b)
# => MapSet.new([100])
MapSet.difference(b, a)
# => MapSet.new([2, 3, 4, 5, 6, 7, 8, 9])
MapSet.symmetric_difference(b, a)
# => MapSet.new([2, 3, 4, 5, 6, 7, 8, 9, 100])
MapSet.filter/2, MapSet.reject/2, MapSet.split_with/2로 집합을 걸러내거나 나눌 수 있어요.
a = MapSet.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
even = fn n -> rem(n, 2) == 0 end
MapSet.filter(a, even)
# => MapSet.new([2, 4, 6, 8, 10])
MapSet.reject(a, even)
# => MapSet.new([1, 3, 5, 7, 9])
MapSet.split_with(a, even)
# => {MapSet.new([2, 4, 6, 8, 10]), MapSet.new([1, 3, 5, 7, 9])}
Blorkemon™️ 카드에 대한 향수가 좀처럼 가라앉지 않네요. 다시 카드를 모으기 시작했고, 친구들까지 함께 끌어들이고 있어요.
이 연습 문제에서 카드 컬렉션은 MapSet으로 표현해요. 목표가 존재하는 모든 카드를 모으는 것이기 때문에 중복된 카드는 중요하지 않거든요.
친구들이 Blorkemon™️ 열풍에 함께하길 정말 바라죠. 가장 좋은 방법은 카드 한 장을 선물해서 친구의 컬렉션을 시작해 주는 거예요.
GottaSnatchEmAll.new_collection을 구현해요. 이 함수는 카드 한 장을 컬렉션으로 바꿔 줘요.
GottaSnatchEmAll.new_collection("Newthree")
# => MapSet.new(["Newthree"])
컬렉션을 한 번 만들면 컬렉션은 스스로 자라나기 시작해요.
GottaSnatchEmAll.add_card를 구현해요. 카드 한 장과 컬렉션을 받아서 두 값을 담은 튜플을 반환해요. 첫 번째는 카드가 이미 컬렉션에 있었는지 알려 주는 불리언이고, 두 번째는 카드를 추가한 컬렉션이에요.
GottaSnatchEmAll.add_card("Scientuna", MapSet.new(["Newthree"]))
# => {false, MapSet.new(["Newthree", "Scientuna"])}
이제 친구들이 다시 Blorkemon™️에 푹 빠졌으니, 카드를 교환하면서 자기 컬렉션을 키울 수 있어요.
모든 교환이 가치 있는 것도 아니고, 아예 할 수 없는 교환도 있어요. 가지고 있지 않은 카드는 교환할 수 없고, 이미 가지고 있는 카드와 교환해서도 안 돼요.
GottaSnatchEmAll.trade_card를 구현해요. 교환할 카드 두 장(내 카드와 상대 카드)과 현재 컬렉션을 받아요.
반환값은 두 값을 담은 튜플이에요. 교환이 가능하고 가치가 있는지 알려 주는 불리언과, 교환을 한다면 최종적으로 갖게 될 컬렉션이에요(실제로 교환이 불가능하더라도요).
GottaSnatchEmAll.trade_card("Scientuna", "Newthree", MapSet.new(["Scientuna"]))
# => {true, MapSet.new(["Newthree"])}
벼룩시장에서 오래된 카드 더미를 발견했어요. 카드를 정렬하고 중복을 제거해서 내 컬렉션과 비교해야 해요.
GottaSnatchEmAll.remove_duplicates를 구현해요. 카드 목록을 정렬하고, 정렬된 고유 카드 목록을 반환해요.
GottaSnatchEmAll.remove_duplicates(["Newthree", "Newthree", "Newthree", "Scientuna"])
# => ["Newthree", "Scientuna"]
이제 내 컬렉션에 뿌듯해할 시간이에요.
GottaSnatchEmAll.extra_cards를 구현해요. 내 컬렉션과 다른 컬렉션을 받아서, 상대 컬렉션에는 없는 카드의 개수를 반환해요.
GottaSnatchEmAll.extra_cards(MapSet.new(["Scientuna"]), MapSet.new(["Newthree", "Scientuna"]))
# => 0
Blorkemon™️에 열광하는 친구들과 모여서 어떤 카드가 가장 흔한지 궁금해해요.
GottaSnatchEmAll.boring_cards를 구현해요. 컬렉션 목록을 받아서, 모든 컬렉션이 가지고 있는 카드를 정렬한 목록을 반환해요.
GottaSnatchEmAll.boring_cards([MapSet.new(["Scientuna"]), MapSet.new(["Newthree", "Scientuna"])])
# => ["Scientuna"]
나와 친구들이 힘을 합치면 모든 Blorkemon™️ 카드를 가지고 있는 걸까요?
GottaSnatchEmAll.total_cards를 구현해요. 컬렉션 목록을 받아서, 모든 컬렉션에 있는 서로 다른 카드의 총개수를 반환해요.
GottaSnatchEmAll.total_cards([MapSet.new(["Scientuna"]), MapSet.new(["Newthree", "Scientuna"])])
# => 2
조카가 곧 놀러 온다죠. 한번 멋진 모습을 보여주고 싶어요. 아이들은 반짝이는 걸 좋아하잖아요? Blorkemon™️ 카드도 반짝일 수 있어요!
GottaSnatchEmAll.split_shiny_cards를 구현해요. 컬렉션을 받아서 정렬된 카드 목록 두 개를 담은 튜플을 반환해요. 하나는 "Shiny"로 시작하는 카드들이고, 다른 하나는 나머지 카드들이에요.
GottaSnatchEmAll.split_shiny_cards(MapSet.new(["Newthree", "Scientuna", "Shiny Scientuna"]))
# => {["Shiny Scientuna"], ["Newthree", "Scientuna"]}
Exercism에 가입하고 Elixir 트랙을 개념 58개연습 문제 168개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.