Tracks
/
Factor
Factor
/
Übungen
/
Die Triage der Kassierer
Die Triage der Kassierer

Die Triage der Kassierer

Lernübung

Einführung

Ein Heap ist eine Sammlung, die immer ihr kleinstes Element kennt und aus der du dieses Element schnell entnehmen kannst. Er ist das natürliche Werkzeug für eine Prioritätswarteschlange: eine Warteschlange, in der das wichtigste Element als Nächstes bedient wird, nicht das, das am längsten gewartet hat. Heaps findest du im Vokabular heaps.

Einen Heap aufbauen

<min-heap> erzeugt einen leeren Heap, dessen kleinster Schlüssel zuerst herauskommt; <max-heap> ist das Spiegelbild.

<min-heap> ( -- min-heap )
<max-heap> ( -- max-heap )

Elemente hinzufügen

Jedes Element wird als Wert zusammen mit einem Schlüssel gespeichert, wobei der Schlüssel die Priorität ist, nach der Factor sortiert. heap-push fügt ein Element hinzu:

heap-push ( value key heap -- )
USING: heaps ;

<min-heap>
"alice" 5 pick heap-push   ! value "alice", priority 5
"bob"   2 pick heap-push   ! value "bob",   priority 2

Ein Heap ist veränderlich: heap-push ändert ihn an Ort und Stelle, anstatt einen neuen zurückzugeben. keep ist praktisch, um den Heap wieder auf den Stack zu bekommen, nachdem heap-push ihn verbraucht hat.

Das vorderste Element ansehen und entfernen

heap-peek gibt das vorderste Element zurück: den Wert mit dem kleinsten Schlüssel, ohne ihn zu entfernen. heap-pop gibt dieses Element zurück und entfernt es. heap-empty? meldet, ob noch etwas übrig ist, damit du weißt, wann du mit dem Entfernen aufhören musst. heap-pop-all entfernt alles auf einmal und gibt eine Assoziationsliste von { key value }-Paaren in Prioritätsreihenfolge zurück.

heap-peek    ( heap -- value key )
heap-pop     ( heap -- value key )
heap-empty?  ( heap -- ? )
heap-pop-all ( heap -- alist )
USING: assocs heaps kernel prettyprint ;

<min-heap>
"alice" 5 pick heap-push
"bob"   2 pick heap-push
dup heap-empty? .        ! => f      (two items waiting)
dup heap-peek drop .     ! => "bob"  (smallest key, still in the heap)
dup heap-pop drop .      ! => "bob"  (smallest key, now removed)
heap-pop-all .           ! => { { 5 "alice" } }

heap-pop und heap-empty? sind die Bausteine, um Elemente einzeln zu bedienen: Sieh dir das vorderste Element an oder entferne es, reagiere darauf und höre auf, sobald heap-empty? t zurückgibt. Die folgenden Aufgaben verwenden heap-pop-all, um die gesamte Warteschlange in einem Schritt zu leeren, aber dieselbe Reihenfolge ergibt sich, wenn du so lange Elemente entnimmst, bis der Heap leer ist.

Die Paare von heap-pop-all sind eine Assoziationsliste: values (in assocs) behält nur die Werte und lässt die Schlüssel weg.

Anleitung

Eine stark frequentierte Bank bedient wartende Kunden nach Priorität und nicht in der Reihenfolge, in der sie angekommen sind. Jeder Kunde zieht eine Wartenummer und bekommt dabei eine Prioritätsnummer. Der Schaltermitarbeiter bedient als Nächstes immer die niedrigste Nummer (1 ist am dringendsten). Ein Min-Heap ist die perfekte Warteschlange.

1. Die Warteschlange öffnen

Definiere new-queue, das keine Argumente entgegennimmt und eine neue, leere Prioritätswarteschlange zurückgibt.

new-queue
! => an empty priority queue

2. Einen Kunden hinzufügen

Definiere join-queue, das einen Kundennamen, eine Prioritätsnummer und eine Warteschlange entgegennimmt. Es fügt den Kunden zur Warteschlange hinzu und gibt die Warteschlange zurück, sodass du Kunden nacheinander hinzufügen kannst.

new-queue "alice" 5 rot join-queue "bob" 2 rot join-queue
! => the queue, now holding alice (5) and bob (2)

3. Wer ist als Nächstes dran?

Definiere next-name, das eine Warteschlange entgegennimmt und den Namen des Kunden zurückgibt, der als Nächstes bedient werden soll, also den Namen des Kunden mit der niedrigsten Prioritätsnummer, ohne ihn aus der Warteschlange zu entfernen.

new-queue "alice" 5 rot join-queue "bob" 2 rot join-queue next-name .
! => "bob"

4. Alle bedienen

Definiere serve-all, das eine Warteschlange entgegennimmt und die Namen aller wartenden Kunden in der Reihenfolge zurückgibt, in der sie bedient würden.

new-queue "alice" 5 rot join-queue "bob" 2 rot join-queue
"carol" 9 rot join-queue serve-all .
! => { "bob" "alice" "carol" }
Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab
Factor Exercism

Bereit, mit Die Triage der Kassierer zu starten?

Melde dich bei Exercism an, um Factor mit 47 Konzepte163 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.