Un MapSet es una colección de valores únicos, que representan conjuntos en Elixir.
Puede contener valores de cualquier tipo, sin una noción de orden.
Ten en cuenta que el módulo Set también existe, pero está obsoleto en favor de MapSet.
Puedes crear conjuntos con MapSet.new/0, MapSet.new/1 y MapSet.new/2, y transformarlos en listas con 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]
Ten en cuenta que, como los MapSet no tienen una noción de orden, no se garantiza que MapSet.to_list/1 devuelva una lista ordenada.
Puedes añadir o eliminar elementos con MapSet.put/2 y MapSet.delete/2.
Puedes consultar el contenido de un conjunto con las funciones MapSet.size/1, MapSet.member?/2, y comparar conjuntos con MapSet.equal?/2, MapSet.subset?/2 y 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
Los MapSet se pueden combinar con MapSet.union/2, MapSet.intersection/2, MapSet.difference/2 y 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])
Puedes filtrar y dividir conjuntos con MapSet.filter/2, MapSet.reject/2 y 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])}
Tu nostalgia por las cartas Blorkemon™️ no muestra signos de disminuir: incluso has vuelto a coleccionarlas y estás consiguiendo que tus amigos se unan a ti.
En este ejercicio, una colección de cartas se representa con un MapSet, ya que las cartas duplicadas no son importantes cuando tu objetivo es conseguir todas las cartas existentes.
Quieres de verdad que tus amigos se sumen a tu locura por Blorkemon™️, y la mejor forma es arrancar su colección regalándoles una carta.
Implementa GottaSnatchEmAll.new_collection, que transforma una carta en una colección.
GottaSnatchEmAll.new_collection("Newthree")
# => MapSet.new(["Newthree"])
Una vez que tienes una colección, cobra vida propia y debe crecer.
Implementa GottaSnatchEmAll.add_card, que toma una carta y una colección, y devuelve una tupla con dos valores: un Boolean que indica si la carta ya estaba en la colección, y la colección con la carta añadida.
GottaSnatchEmAll.add_card("Scientuna", MapSet.new(["Newthree"]))
# => {false, MapSet.new(["Newthree", "Scientuna"])}
Ahora que tus amigos vuelven a estar locos por Blorkemon™️, puedes aprovecharlo para hacer crecer tu propia colección intercambiando cartas.
No todos los intercambios merecen la pena o pueden hacerse. No puedes intercambiar una carta que no tienes, y no deberías cambiar una carta por otra que ya tienes.
Implementa GottaSnatchEmAll.trade_card, que toma dos cartas para intercambiar (la tuya y la suya) y tu colección actual.
El valor devuelto es una tupla de dos valores: un Boolean que indica si el intercambio es posible y merece la pena, y la colección con la que acabarías si hicieras el intercambio (aunque en realidad no sea posible).
GottaSnatchEmAll.trade_card("Scientuna", "Newthree", MapSet.new(["Scientuna"]))
# => {true, MapSet.new(["Newthree"])}
Encuentras un viejo alijo de cartas en un mercadillo. Debes ordenar las cartas y eliminar los duplicados para comparar la lista con tu colección.
Implementa GottaSnatchEmAll.remove_duplicates, que ordenará una lista de cartas y devolverá una lista de cartas únicas y ordenadas.
GottaSnatchEmAll.remove_duplicates(["Newthree", "Newthree", "Newthree", "Scientuna"])
# => ["Newthree", "Scientuna"]
Es hora de sentirte bien con tu colección.
Implementa GottaSnatchEmAll.extra_cards, que toma tu colección y otra colección cualquiera, y devuelve el número de cartas que la otra colección no tiene.
GottaSnatchEmAll.extra_cards(MapSet.new(["Scientuna"]), MapSet.new(["Newthree", "Scientuna"]))
# => 0
Tú y tus amigos aficionados a Blorkemon™️ os reunís y os preguntáis qué cartas son las más comunes.
Implementa GottaSnatchEmAll.boring_cards, que toma una lista de colecciones y devuelve una lista ordenada de las cartas que tienen todas las colecciones.
GottaSnatchEmAll.boring_cards([MapSet.new(["Scientuna"]), MapSet.new(["Newthree", "Scientuna"])])
# => ["Scientuna"]
¿Tus amigos y tú tenéis, entre todos, todas las cartas de Blorkemon™️?
Implementa GottaSnatchEmAll.total_cards, que toma una lista de colecciones y devuelve el número total de cartas diferentes que hay en todas las colecciones.
GottaSnatchEmAll.total_cards([MapSet.new(["Scientuna"]), MapSet.new(["Newthree", "Scientuna"])])
# => 2
Tu sobrino viene a visitarte pronto y te apetece impresionarlo. A los niños les gustan las cosas brillantes, ¿verdad? ¡Las cartas Blorkemon™️ pueden ser brillantes!
Implementa GottaSnatchEmAll.split_shiny_cards, que toma una colección y devuelve una tupla con dos listas ordenadas de cartas: una con todas las cartas que empiezan por "Shiny" y otra con el resto de las cartas.
GottaSnatchEmAll.split_shiny_cards(MapSet.new(["Newthree", "Scientuna", "Shiny Scientuna"]))
# => {["Shiny Scientuna"], ["Newthree", "Scientuna"]}
Regístrate en Exercism para aprender y dominar Elixir con 58 conceptos168 ejercicios y mentoría humana real, todo gratis.