Rutas
/
Elixir
Elixir
/
Ejercicios
/
Gotta Snatch'Em All
Gotta Snatch'Em All

Gotta Snatch'Em All

Ejercicio de aprendizaje

Introducción

MapSets

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])}

Instrucciones

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.

1. Empieza una colección

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"])

2. Haz crecer la colección

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"])}

3. Empieza a intercambiar

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"])}

4. Solo puede haber una de cada

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"]

5. Cartas que no tienen

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

6. Cartas que todos tienen

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"]

7. Todas las cartas

¿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

8. Brillantes para ganar

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"]}
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Elixir Exercism

¿Listo para empezar Gotta Snatch'Em All?

Regístrate en Exercism para aprender y dominar Elixir con 58 conceptos168 ejercicios y mentoría humana real, todo gratis.