Un MapSet es una colección de valores únicos que representa conjuntos en Elixir.
Puede contener valores de cualquier tipo, sin una noción de orden.
Ten en cuenta que también existe el módulo Set, 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 agregar 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 tarjetas Blorkemon™️ no muestra señales de disminuir; incluso comenzaste a coleccionarlas de nuevo y estás animando a tus amigos a que se unan.
En este ejercicio, una colección de tarjetas se representa con un MapSet, ya que las tarjetas duplicadas no importan cuando tu objetivo es conseguir todas las tarjetas que existen.
De verdad quieres que tus amigos se unan a tu locura por Blorkemon™️, y la mejor forma de arrancar su colección es regalarles una tarjeta.
Implementa GottaSnatchEmAll.new_collection, que transforma una tarjeta en una colección.
GottaSnatchEmAll.new_collection("Newthree")
# => MapSet.new(["Newthree"])
Una vez que tienes una colección, esta cobra vida propia y debe crecer.
Implementa GottaSnatchEmAll.add_card, que recibe una tarjeta y una colección, y devuelve una tupla con dos valores: un Boolean que indica si la tarjeta ya estaba en la colección, y la colección con la tarjeta agregada.
GottaSnatchEmAll.add_card("Scientuna", MapSet.new(["Newthree"]))
# => {false, MapSet.new(["Newthree", "Scientuna"])}
Ahora que tus amigos volvieron a enloquecer con Blorkemon™️, puedes aprovecharlo para hacer crecer tu propia colección intercambiando tarjetas.
No todo intercambio vale la pena, ni todos son posibles. No puedes intercambiar una tarjeta que no tienes, y no deberías dar una tarjeta a cambio de otra que ya tienes.
Implementa GottaSnatchEmAll.trade_card, que recibe dos tarjetas para intercambiar (la tuya y la suya) y tu colección actual.
El valor de retorno es una tupla con dos valores: un Boolean que indica si el intercambio es posible y vale la pena, y la colección que tendrí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 tarjetas en un mercado de pulgas. Debes ordenar las tarjetas y eliminar los duplicados para comparar la lista con tu colección.
Implementa GottaSnatchEmAll.remove_duplicates, que ordena una lista de tarjetas y devuelve una lista de tarjetas únicas y ordenadas.
GottaSnatchEmAll.remove_duplicates(["Newthree", "Newthree", "Newthree", "Scientuna"])
# => ["Newthree", "Scientuna"]
Es momento de sentirte bien con tu colección.
Implementa GottaSnatchEmAll.extra_cards, que recibe tu colección y otra colección, y devuelve el número de tarjetas 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™️ se reúnen y se preguntan cuáles tarjetas son las más comunes.
Implementa GottaSnatchEmAll.boring_cards, que recibe una lista de colecciones y devuelve una lista de tarjetas ordenadas que todas las colecciones tienen.
GottaSnatchEmAll.boring_cards([MapSet.new(["Scientuna"]), MapSet.new(["Newthree", "Scientuna"])])
# => ["Scientuna"]
¿Entre tú y tus amigos tienen todas las tarjetas Blorkemon™️?
Implementa GottaSnatchEmAll.total_cards, que recibe una lista de colecciones y devuelve el número total de tarjetas 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 tienes ganas de impresionarlo. A los niños les gustan las cosas brillantes, ¿no? ¡Las tarjetas Blorkemon™️ pueden ser brillantes!
Implementa GottaSnatchEmAll.split_shiny_cards, que recibe una colección y devuelve una tupla con dos listas de tarjetas ordenadas: una con todas las tarjetas que empiezan con "Shiny" y otra con las demás tarjetas.
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.