Tracks
/
Elixir
Elixir
/
Übungen
/
Gotta Snatch'Em All
Gotta Snatch'Em All

Gotta Snatch'Em All

Lernübung

Einführung

MapSets

Ein MapSet ist eine Sammlung eindeutiger Werte und stellt Mengen in Elixir dar. Es kann Werte jeder Art enthalten und kennt keine Reihenfolge.

Beachte, dass es auch das Modul Set gibt, das aber zugunsten von MapSet veraltet ist.

Du kannst Mengen mit MapSet.new/0, MapSet.new/1 und MapSet.new/2 erstellen und sie mit MapSet.to_list/1 in Listen umwandeln.

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]

Beachte, dass MapSets keine Reihenfolge kennen, deshalb ist nicht garantiert, dass MapSet.to_list/1 eine sortierte Liste zurückgibt.

Du kannst Elemente mit MapSet.put/2 und MapSet.delete/2 hinzufügen oder entfernen.

Du kannst den Inhalt einer Menge mit den Funktionen MapSet.size/1 und MapSet.member?/2 abfragen und Mengen mit MapSet.equal?/2, MapSet.subset?/2 und MapSet.disjoint?/2 vergleichen.

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

MapSets lassen sich mit MapSet.union/2, MapSet.intersection/2, MapSet.difference/2 und MapSet.symmetric_difference/2 kombinieren.

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

Du kannst Mengen mit MapSet.filter/2, MapSet.reject/2 und MapSet.split_with/2 filtern und aufteilen.

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

Anleitung

Deine Nostalgie für Blorkemon™️-Karten wird einfach nicht schwächer. Du hast sogar wieder angefangen, sie zu sammeln, und bringst auch deine Freunde dazu, mitzumachen.

In dieser Übung wird eine Kartensammlung durch ein MapSet dargestellt, denn doppelte Karten sind nicht wichtig, wenn dein Ziel ist, alle existierenden Karten zu bekommen.

1. Starte eine Sammlung

Du willst unbedingt, dass deine Freunde bei deinem Blorkemon™️-Wahnsinn mitmachen, und der beste Weg ist, ihre Sammlung mit einer einzigen Karte zu starten.

Implementiere GottaSnatchEmAll.new_collection, was eine Karte in eine Sammlung umwandelt.

GottaSnatchEmAll.new_collection("Newthree")
# => MapSet.new(["Newthree"])

2. Lass die Sammlung wachsen

Sobald du eine Sammlung hast, entwickelt sie ein Eigenleben und muss wachsen.

Implementiere GottaSnatchEmAll.add_card. Die Funktion nimmt eine Karte und eine Sammlung und gibt ein Tupel mit zwei Werten zurück: einen booleschen Wert, der angibt, ob die Karte schon in der Sammlung war, und die Sammlung mit der hinzugefügten Karte.

GottaSnatchEmAll.add_card("Scientuna", MapSet.new(["Newthree"]))
# => {false, MapSet.new(["Newthree", "Scientuna"])}

3. Fang an zu tauschen

Jetzt, wo deine Freunde wieder verrückt nach Blorkemon™️ sind, kannst du das nutzen, um deine eigene Sammlung durch Kartentauschen zu vergrößern.

Nicht jeder Tausch lohnt sich, und manche sind gar nicht möglich. Du kannst keine Karte tauschen, die du nicht hast, und du solltest keine Karte gegen eine tauschen, die du schon hast.

Implementiere GottaSnatchEmAll.trade_card. Die Funktion nimmt zwei Karten zum Tauschen (deine und ihre) und deine aktuelle Sammlung. Der Rückgabewert ist ein Tupel aus zwei Werten: ein boolescher Wert, der angibt, ob der Tausch möglich und lohnenswert ist, und die Sammlung, die du nach dem Tausch hättest (auch wenn der Tausch gar nicht möglich ist).

GottaSnatchEmAll.trade_card("Scientuna", "Newthree", MapSet.new(["Scientuna"]))
# => {true, MapSet.new(["Newthree"])}

4. Von jeder Karte gibt es nur eine

Auf einem Flohmarkt findest du einen alten Vorrat an Karten. Du musst die Karten sortieren und die Duplikate entfernen, um die Liste mit deiner Sammlung zu vergleichen.

Implementiere GottaSnatchEmAll.remove_duplicates. Die Funktion sortiert eine Liste von Karten und gibt eine Liste sortierter, eindeutiger Karten zurück.

GottaSnatchEmAll.remove_duplicates(["Newthree", "Newthree", "Newthree", "Scientuna"])
# => ["Newthree", "Scientuna"]

5. Karten, die sie nicht haben

Zeit, dich über deine Sammlung zu freuen.

Implementiere GottaSnatchEmAll.extra_cards. Die Funktion nimmt deine Sammlung und eine andere Sammlung und gibt die Anzahl der Karten zurück, die die andere Sammlung nicht hat.

GottaSnatchEmAll.extra_cards(MapSet.new(["Scientuna"]), MapSet.new(["Newthree", "Scientuna"]))
# => 0

6. Karten, die alle haben

Du und deine Blorkemon™️-begeisterten Freunde trefft euch und fragt euch, welche Karten am häufigsten sind.

Implementiere GottaSnatchEmAll.boring_cards. Die Funktion nimmt eine Liste von Sammlungen und gibt eine Liste sortierter Karten zurück, die alle Sammlungen haben.

GottaSnatchEmAll.boring_cards([MapSet.new(["Scientuna"]), MapSet.new(["Newthree", "Scientuna"])])
# => ["Scientuna"]

7. Alle Karten

Besitzt du zusammen mit deinen Freunden alle Blorkemon™️-Karten?

Implementiere GottaSnatchEmAll.total_cards. Die Funktion nimmt eine Liste von Sammlungen und gibt die Gesamtzahl der verschiedenen Karten in allen Sammlungen zurück.

GottaSnatchEmAll.total_cards([MapSet.new(["Scientuna"]), MapSet.new(["Newthree", "Scientuna"])])
# => 2

8. Glänzend zum Sieg

Dein Neffe kommt dich bald besuchen, und du willst ihn beeindrucken. Kinder mögen glänzende Dinge, oder? Blorkemon™️-Karten können glänzend sein!

Implementiere GottaSnatchEmAll.split_shiny_cards. Die Funktion nimmt eine Sammlung und gibt ein Tupel mit zwei Listen sortierter Karten zurück: eine mit allen Karten, die mit "Shiny" beginnen, und eine mit den übrigen Karten.

GottaSnatchEmAll.split_shiny_cards(MapSet.new(["Newthree", "Scientuna", "Shiny Scientuna"]))
# => {["Shiny Scientuna"], ["Newthree", "Scientuna"]}
Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab
Elixir Exercism

Bereit, mit Gotta Snatch'Em All zu starten?

Melde dich bei Exercism an, um Elixir mit 58 Konzepte168 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.