Jedes Ergebnis des Ausrüstungsabgleichs erklären

RustBeginner
Jetzt üben

Einführung

Eine verlässliche Objektliste ist erst der Anfang einer Ausrüstungsprüfung. Das Team braucht für jeden Typ eine Erklärung: Wie viele Objekte sind intakt, welche sind beschädigt, was fehlt und was übersteigt den Plan? Ein nicht eingeplanter Gegenstand oder Bedarf null macht eine Eingabe nicht ungültig.

In diesem Lab implementierst du diese Abgleichlogik und liest ihren Bericht für zwei verschiedene Gruppen tatsächlicher Eingabedateien. Dies ist eine unabhängige Umgebung: Zustandsparser und Identitätssammlung aus dem vorherigen Lab sind bereits vorhanden. Du benötigst keine Dateien aus dessen VM. Du solltest dessen Regeln zu Identität und Konflikten sowie Rust-Strukturen, Enumerationen, HashMap, Result, Dateilesen und Schleifen kennen. Der Autor schätzt 45 Minuten einschließlich Lesen und üblicher Korrekturen; dies ist keine mit Anfängern gemessene Bearbeitungsdauer.

Jeden Typ und jedes Objekt abgleichen

In diesem Schritt baust du den Abgleich in drei Bearbeitungen auf: relevante Typen bestimmen, ihre vollständigen Objektmengen sammeln, dann Fehlmengen und Überschüsse berechnen. Öffne Terminal. Ergänze den Suchpfad dieser Shell um Cargo und wechsle in das unabhängig vorbereitete Projekt. Wiederhole den Export in einem neuen Terminal und cd, falls du dein Verzeichnis verlierst:

export PATH=/home/labex/.cargo/bin:$PATH
cd /home/labex/project/field-kit

Untersuche zuerst ein normales Ergebnis, das bereits funktioniert. Zustandsparser und Identitätssammlung sind in diesem Lab vorhanden:

cat data/plan.tsv
cargo run --quiet -- assets data/scans.tsv

Die Tabelle enthält sechs physische IDs statt sieben Scans. a, b und c sind intakte Objekte von light-a. d ist ein beschädigtes Objekt von light-b; e und f sind ein intaktes und ein beschädigtes Objekt des nicht eingeplanten Typs other. Der Anzeigename Flashlight gehört zu zwei unterschiedlichen geplanten Typ-IDs. Der Plan benötigt außerdem zwei Seile ohne Scans sowie null Ersatzgegenstände ohne Scans. Erhalte diese Unterschiede bei der Entscheidung, was ein vollständiger Bericht erklären muss.

Bearbeite nur src/readiness.rs und erhalte den öffentlichen Funktionsnamen sowie Parameter- und Rückgabetypen. Lasse die anderen Quelldateien, Cargo.toml, rust-toolchain.toml und jede Originaldatei unter data/ unverändert. Du wirst getrennte experimentelle Eingaben im Projektverzeichnis erstellen. Die Befehlsoberfläche liest die tatsächlich angegebenen Pfade und ersetzt sie nicht durch ein Beispiel.

Der kontrollierte TSV-Vertrag bleibt gleich: exakte Kopfzeilen mit drei Feldern type_id, name, required für Pläne und asset_id, type_id, condition für Scans, mit echten Tabulatoren dazwischen. IDs beginnen mit einem kleinen ASCII-Buchstaben und enthalten danach Kleinbuchstaben, Ziffern oder -. Namen im Plan sind nicht leere, druckbare ASCII-Texte einschließlich Leerzeichen. Mengen bestehen aus Dezimalziffern mit Werten von 0 bis 999; führende Nullen sind erlaubt. Typ-IDs im Plan dürfen sich nicht wiederholen, Anzeigenamen schon. Zustände lauten exakt good oder damaged. LF/CRLF, ein fehlender abschließender Zeilenumbruch und spätere vollständig leere Zeilen werden akzeptiert. Felder werden nicht beschnitten; reine Leerraumzeilen sind nicht leer und einzelne Wagenrückläufe sind keine Zeilenenden. Dies sind synthetische Textdatensätze, keine physischen Inspektionen.

Lies die bereitgestellten Typen und die unvollständige Funktion:

cat src/lib.rs
cat src/readiness.rs

Need enthält Typ-ID, Name und Bedarfsmenge des Plans. Scan enthält Objekt-ID, Typ-ID, Zustand und Diagnosezeile. reconcile erhält &[Need] und &[Scan], geliehene Slices, die es nicht verändern darf. Die Objekte wurden bereits auf Format geprüft und nach Identität gesammelt; jede physische ID kommt deshalb einmal vor. Der zurückgegebene Vec<TypeSummary> muss die Vereinigung geplanter und gescannter Typen, vollständige Mengen intakter und beschädigter IDs, Bedarfsmenge, Fehlmenge und Überschuss enthalten. Die vorbereitete Formatierung ergänzt Anzeigenamen, sortiert Zeilen und ID-Listen und zeigt für jedes Objekt die Beziehung planned oder unplanned.

Erste Bearbeitung: relevante Typen erhalten

Betrachte einen Plan ohne gescannte Objekte. Positiver Bedarf bleibt eine Fehlmenge, Bedarf null bedeutet Fehlmenge null. Erstelle eine getrennte Eingabe ohne Scans; leere nicht das geschützte Original. printf gibt seine Formatzeichenkette aus und interpretiert \t als Tabulator und \n als Zeilenumbruch. Einfache Anführungszeichen erhalten diese Rückwärtsschrägstriche für printf, und > schreibt diese benannte experimentelle Datei. Ihre einzige Zeile ist die Kopfzeile:

printf 'asset_id\ttype_id\tcondition\n' > empty-scans.tsv
cat empty-scans.tsv

Sage vor der Codeänderung voraus, welche Typen diese Eingabe behalten soll: light-a, light-b, rope und zero, mit Bedarfsmengen 2, 1, 2 und 0. In dieser konkreten Eingabe existiert kein ausschließlich gescannter Typ. Die allgemeine Funktion muss Typen trotzdem aus beiden Slices ermitteln, damit die späteren tatsächlichen Scans other ergänzen können.

Lege einen Sicherungsstand nur für den Quelltext an. mktemp -d erstellt ein neues Verzeichnis, indem es die sechs X-Zeichen durch ein eindeutiges Suffix ersetzt; es verwendet keine frühere Sicherung erneut. $() erfasst den ausgegebenen Pfad in der Sitzungsvariablen. && führt cp -p nur nach erfolgreicher Verzeichniserstellung aus. Die Kopie erhält die Metadaten des Quelltexts und Anführungszeichen halten den Variablenpfad zusammen. Schlägt eine der Operationen fehl, lies den Fehler und erstelle vor der Bearbeitung eine Sicherung:

rs03_before_types=$(mktemp -d .edit-before-types.XXXXXX) && cp -p src/readiness.rs "$rs03_before_types/readiness.rs"

Öffne die vorhandene Datei mit nano; -c zeigt die Cursorposition:

nano -c src/readiness.rs

Nano verwendet ^ für Strg. Drücke Strg+W, suche nach pub fn reconcile und drücke Enter. Lies die öffnende und schließende Klammer der Funktion. Bearbeite mit Pfeiltasten und Rücktaste/Entf nur ihren Rumpf und die ungenutzten Parameterbindungen. Benenne _needs und _assets in needs und assets um und erhalte ihre Typen. Behalte den vorhandenen Import use crate::{Need, Scan, TypeSummary};; diese Phase verwendet Condition noch nicht.

Konstruiere diese erste Phase aus den Datenbeziehungen. Erstelle einen leeren Vektor types. Hänge jede geplante Typ-ID an. Besuche danach die Objekte und hänge eine Typ-ID nur an, wenn types.contains(&asset.type_id) falsch ist. Ein Plan hat bereits eindeutige Typ-IDs. .clone() kopiert eine Typ-ID-Zeichenkette mit eigenen Daten aus einem geliehenen Datensatz, damit dein Ergebnis sie besitzen kann.

Erstelle dann einen leeren Vektor summaries und besuche jede gesammelte Typ-ID. Beginne ihre Bedarfsmenge mit null und suche diesen Typ im Plan. usize::from(need.required) wandelt den Planwert vom Typ u16 in den für Vektorlängen verwendeten Zähltyp um. Verwende vorerst leere Vektoren good_ids und damaged_ids. Solange keine nutzbaren Objekte gezählt wurden, weise missing den Wert von required zu und setze surplus auf null. Hänge mit diesen Variablen einen TypeSummary an und verwende summaries als letzten Ausdruck der Funktion. Verkürzte Feldschreibweise wie type_id, required verwendet Variablen mit passenden Namen. Die Objektklassifikation hast du noch nicht implementiert.

Speichere mit Strg+O, Enter zum Bestätigen des aktuellen Dateinamens und Strg+X zum Beenden. Lies deine gespeicherte Funktion vor dem Ausführen:

cat src/readiness.rs

cargo run kompiliert und startet das Programm; --quiet verbirgt Cargo-Fortschritt, und -- übergibt die folgenden Argumente an das Programm. Teste den begrenzten Fall ohne Scans:

cargo run --quiet -- check data/plan.tsv empty-scans.tsv

Erwarte diese vier geplanten Typen, null intakte Objekte und leere ID-Mengen, Fehlmengen 2, 1, 2 und 0 sowie null Überschuss. Nach der Kopfzeile ASSET sollten keine Objektdatenzeilen stehen. Diese erste Phase ist nur für diese Beobachtung ohne Scans korrekt. Sie ist keine vollständige Implementierung für eine nicht leere Objektliste. Deute einen Exit-Status null nicht als Beweis, dass alle Abgleichregeln fertig sind.

Zweite Bearbeitung: vollständige Zustandsmengen erhalten

Sage nun die vollständigen Mengen der tatsächlichen Scans voraus: light-a hat intakte IDs a,b,c; light-b hat die beschädigte ID d; other hat die intakte ID e und die beschädigte ID f. rope und zero benötigen auch ohne Objekte weiterhin eigene Zusammenfassungen. Behalte jede Menge, statt ein bevorzugtes „zusätzliches“ Objekt auszuwählen.

Sichere deine funktionierende Phase der Typvereinigung:

rs03_before_sets=$(mktemp -d .edit-before-sets.XXXXXX) && cp -p src/readiness.rs "$rs03_before_sets/readiness.rs"
nano -c src/readiness.rs

Ergänze am Anfang im crate-Import die Enumeration, die du nun verwendest:

use crate::{Condition, Need, Scan, TypeSummary};

Dies ist eine ausdrückliche Quelltextänderung: Der ursprüngliche Ausgangscode importiert Condition nicht. crate bezeichnet diese Bibliothek; use macht ihre Namen in diesem Modul verfügbar. Den Import gleichzeitig mit seiner ersten Verwendung zu ergänzen vermeidet außerdem eine Warnung wegen ungenutzten Imports in der früheren Phase.

Suche nach pub fn reconcile. Behalte die Logik für Typvereinigung und Bedarfsmenge. Mache good_ids und damaged_ids veränderbar, weil du IDs anhängen wirst. Besuche innerhalb der Schleife jedes Typs alle Objekte, wähle diejenigen mit der aktuellen type_id aus und unterscheide ihren Zustand mit match. Hänge für die Variante Good eine Kopie der Objekt-ID an den Vektor intakter IDs an, für Damaged an den beschädigten Vektor. Beide Varianten sind gültige Eingabe. Lösche keine beschädigten oder nicht eingeplanten Objekte. Lasse die zwei vorläufigen Zuweisungen für Fehlmenge und Überschuss bis zur nächsten Bearbeitung unverändert.

Speichere, beende und verwende die tatsächlichen Scans:

cargo run --quiet -- check data/plan.tsv data/scans.tsv

Lies Typ-IDs, Bedarfsmengen, intakte Anzahlen, vollständige ID-Mengen und ASSET-Zeilen. Sie sollten deiner Vorhersage entsprechen, einschließlich other. Die Spalten für Fehlmenge und Überschuss sind noch vorläufig und keine gültigen allgemeinen Ergebnisse. Beispielsweise kann die vorläufige Fehlmenge von light-a weiterhin 2 anzeigen, obwohl seine drei intakten IDs nun vorhanden sind. Erkläre, warum dies kein fertiger Bericht sein kann. Als Nächstes korrigierst du diese zwei Berechnungen; behaupte nicht, dass diese Zwischentabelle die Endprüfung besteht.

Dritte Bearbeitung: Fehlmengen und Überschüsse nur aus intakten Objekten berechnen

Nur eindeutige intakte Objekte decken Bedarf. Für light-a bedeuten Bedarf 2 und intakt 3: Fehlmenge 0, Überschuss 1. Für light-b deckt sein beschädigtes Objekt den Bedarf nicht: Fehlmenge 1, Überschuss 0. Bei rope fehlen 2. zero bleibt bei 0/0. Das nicht eingeplante other hat Bedarf null und ein intaktes Objekt, also Überschuss 1; seine beschädigte ID bleibt erhalten, erhöht aber nicht den Überschuss.

Sichere die Phase, die bereits die korrekten Mengen sammelt:

rs03_before_totals=$(mktemp -d .edit-before-totals.XXXXXX) && cp -p src/readiness.rs "$rs03_before_totals/readiness.rs"
nano -c src/readiness.rs

Suche nach pub fn reconcile und ersetze dann nur die vorläufigen Ausdrücke für Fehlmenge und Überschuss. len() eines Vektors liefert seine Anzahl. saturating_sub subtrahiert ohne unter null zu gehen und vermeidet einen Unterlauf vorzeichenloser Zahlen. Die Regeln lauten missing = max(required - good, 0) und surplus = max(good - required, 0); wende sie auf good_ids.len() an, niemals auf die Zahl der Rohscans oder beschädigten IDs. Erhalte Typvereinigung und vollständige Vektoren. Speichere mit Strg+O, Enter, dann Strg+X.

cargo run --quiet -- check data/plan.tsv data/scans.tsv
TYPE	type_id	name	required	good	missing	surplus	good_ids	damaged_ids
TYPE	light-a	Flashlight	2	3	0	1	a,b,c	-
TYPE	light-b	Flashlight	1	0	1	0	-	d
TYPE	other	-	0	1	0	1	e	f
TYPE	rope	Rope	2	0	2	0	-	-
TYPE	zero	Spare	0	0	0	0	-	-
ASSET	asset_id	type_id	condition	plan
ASSET	a	light-a	good	planned
ASSET	b	light-a	good	planned
ASSET	c	light-a	good	planned
ASSET	d	light-b	damaged	planned
ASSET	e	other	good	unplanned
ASSET	f	other	damaged	unplanned

Jede Menge ist nun zurückverfolgbar: light-b behält die beschädigte ID d, hat aber eine Fehlmenge; other behält beide IDs, aber nur e erzeugt Überschuss. Der wiederholte Scan von a erzeugte nie ein weiteres physisches Objekt. Wiederhole die frühere Prüfung der leeren Quelle mit der fertigen Funktion:

cargo run --quiet -- check data/plan.tsv empty-scans.tsv

Ihre vier geplanten Typen und Fehlmengen ohne Scans müssen weiterhin korrekt sein. Erst jetzt soll die vollständige Abgleichprüfung dieses Schritts bestehen. Gleichwertige interne Sammlungsreihenfolgen bleiben gültig, weil die vorbereitete Formatierung angezeigte Zeilen und ID-Listen sortiert.

Eine Quelltextänderung ohne Zurücksetzen des Projekts reparieren

Cargos Fehler nennt Datei und Zeile. Öffne diese Datei erneut, suche die Funktion mit Strg+W und repariere die angegebene Änderung. Wurde eine versehentliche Änderung noch nicht gespeichert, verwirfst du sie mit Strg+X, dann N bei der Speicherfrage; dies macht keine frühere gespeicherte Bearbeitung rückgängig.

Wähle nur zum Beheben eines gespeicherten Fehlers den Sicherungsstand der Phase, die du wiederholen möchtest: .edit-before-types.* enthält den Ausgangscode, .edit-before-sets.* die Typvereinigung und .edit-before-totals.* die vollständigen ID-Mengen vor den Endberechnungen. Wiederhole in einem neuen Terminal PATH und cd und liste tatsächliche Sicherungsnamen auf:

ls -d .edit-before-*

-d listet Verzeichnisnamen statt ihrer Inhalte, und * trifft auf erzeugte Suffixe zu. Führe den folgenden Befehl aus; füge einen exakt ausgegebenen Verzeichnisnamen ein, während die Shell wartet, und drücke Enter. read speichert deine Auswahl in dieser Sitzungsvariablen:

read rs03_restore

Bestätige vor dem Kopieren den ausgewählten Quelltext:

cat "$rs03_restore/readiness.rs"

Sind Pfad oder Phase falsch, wiederhole Auswahl und Prüfung. Gibt es keine passende Sicherung, repariere die Funktion anhand ihrer Referenz, statt einen Pfad zu erraten. Nach dem Bestätigen der beabsichtigten Phase ersetzt dieser Befehl gezielt nur den erlaubten Abgleichquelltext:

cp -p "$rs03_restore/readiness.rs" src/readiness.rs

Wiederhole danach die betroffenen Bearbeitungen und Tests; ein Quelltextsicherungsstand ändert deine Eingaben nicht. Ändere den Originalplan niemals, um ihn an einen falschen Algorithmus anzupassen. Die folgende Referenz dient nach deinem Versuch zum Vergleich eines bestimmten Teils, nicht als standardmäßiger Ersatz der ganzen Datei.

Vollständige Abgleichreferenz für Vergleich und Wiederherstellung
use crate::{Condition, Need, Scan, TypeSummary};

pub fn reconcile(needs: &[Need], assets: &[Scan]) -> Vec<TypeSummary> {
    let mut types = Vec::new();
    for need in needs {
        types.push(need.type_id.clone());
    }
    for asset in assets {
        if !types.contains(&asset.type_id) {
            types.push(asset.type_id.clone());
        }
    }
    let mut summaries = Vec::new();
    for type_id in types {
        let mut required = 0;
        for need in needs {
            if need.type_id == type_id {
                required = usize::from(need.required);
            }
        }
        let mut good_ids = Vec::new();
        let mut damaged_ids = Vec::new();
        for asset in assets {
            if asset.type_id == type_id {
                match asset.condition {
                    Condition::Good => good_ids.push(asset.asset_id.clone()),
                    Condition::Damaged => damaged_ids.push(asset.asset_id.clone()),
                }
            }
        }
        let missing = required.saturating_sub(good_ids.len());
        let surplus = good_ids.len().saturating_sub(required);
        summaries.push(TypeSummary {
            type_id, required, good_ids, damaged_ids, missing, surplus,
        });
    }
    summaries
}

Teilweise Deckung mit einer anderen Quelle erklären

In diesem Schritt verwendest du andere Eingabepfade, um teilweise Fehlmengen und einen nicht eingeplanten Typ mit ausschließlich beschädigten Objekten zu untersuchen. Arbeite weiter in Terminal unter /home/labex/project/field-kit. Behalte alle Originaldateien in data/ bei und erstelle stattdessen die folgenden beiden getrennten Testdateien.

Die folgenden kurzen Eingabeblöcke verwenden ein Here-Dokument. cat erhält die folgenden Zeilen als Eingabe, > schreibt die benannte experimentelle Datei, und <<'TSV' beginnt wörtliche Eingabe bis zu einer Zeile, die nur TSV enthält. Der zitierte Begrenzer verhindert Shell-Erweiterungen des Inhalts. Kopiere beide Begrenzungszeilen und erhalte die echten Tabulatoren. Dies sind kleine Testeingaben, kein Ersatz für ein Rust-Modul. Der Name Water filter enthält ein Leerzeichen innerhalb eines Feldes; Tabulatoren trennen Felder.

cat > trial-plan.tsv <<'TSV'
type_id	name	required
lamp	Lamp	2
filter	Water filter	5
zero	Spare	0
TSV
cat > trial-scans.tsv <<'TSV'
asset_id	type_id	condition
l-one	lamp	good
l-two	lamp	damaged
f-one	filter	good
f-two	filter	good
u-one	unplanned	damaged
TSV

Sage vor dem Ausführen die Lampen- und Filterfehlmengen voraus. Überlege auch, ob der ausschließlich beschädigte nicht eingeplante Typ enthalten bleibt. Gib nun diese tatsächlichen Dateien an:

cargo run --quiet -- check trial-plan.tsv trial-scans.tsv
TYPE	type_id	name	required	good	missing	surplus	good_ids	damaged_ids
TYPE	filter	Water filter	5	2	3	0	f-one,f-two	-
TYPE	lamp	Lamp	2	1	1	0	l-one	l-two
TYPE	unplanned	-	0	0	0	0	-	u-one
TYPE	zero	Spare	0	0	0	0	-	-
ASSET	asset_id	type_id	condition	plan
ASSET	f-one	filter	good	planned
ASSET	f-two	filter	good	planned
ASSET	l-one	lamp	good	planned
ASSET	l-two	lamp	damaged	planned
ASSET	u-one	unplanned	damaged	unplanned

Sage vor dem Interpretieren des Berichts die Lampen- und Filterfehlmengen anhand ihrer intakten Objekte voraus, nicht anhand der Scanzahl. Trotz zweier Scan-Zeilen fehlt eine Lampe. Zwei intakte Filter decken nur zwei der fünf benötigten ab, sodass drei fehlen. Das beschädigte, nicht eingeplante Objekt bleibt sichtbar, mit null intakten Objekten und null Überschuss. zero bleibt enthalten, obwohl kein Testscan es erwähnt.

Versuche eine kontrollierte Änderung, ohne Originaldaten oder deine ersten Testscans zu bearbeiten. cp -p erstellt eine Kopie und erhält dabei die Metadaten der kopierten Datei. Verwende diesen getrennten neuen Dateinamen; hast du ihn bereits bei einem früheren Versuch verwendet, erhalte diese Arbeit oder wähle einen anderen ungenutzten Namen und verwende ihn in den folgenden Befehlen durchgehend.

cp -p trial-scans.tsv trial-scans-one-repair.tsv
nano -c trial-scans-one-repair.tsv

Drücke Strg+W, suche nach l-two und drücke Enter. Ersetze nur in dieser Zeile mit Pfeiltasten und Rücktaste/Entf das Zustandswort damaged durch good. Erhalte Objekt-ID, Typ-ID, Kopfzeile und echte Tabulatoren als Trennzeichen. Speichere mit Strg+O, Enter und beende mit Strg+X. Dies ist eine beabsichtigte Bearbeitung deines getrennten Experiments, keine Reparatur geschützter Belege.

Sage vor dem Ausführen die zwei betroffenen Berichtszeilen voraus: TYPE lamp sollte nun zwei intakte IDs, keine beschädigten IDs, Fehlmenge null und Überschuss null haben. ASSET l-two sollte seinen Zustand in intakt ändern und weiterhin eingeplant bleiben. Alle anderen Typ- und Objektzeilen sollten unverändert sein; Filterbedarf und beschädigtes nicht eingeplantes Objekt haben sich nicht geändert.

cargo run --quiet -- check trial-plan.tsv trial-scans-one-repair.tsv

Lies diese zwei Zeilen und bestätige, dass die anderen weiterhin übereinstimmen. Hat sich mehr geändert, untersuche deine Kopie mit cat und korrigiere das versehentlich geänderte Feld; ändere den Algorithmus nicht bloß wegen einer unbeabsichtigten Eingabebearbeitung. Kehre zu deiner unveränderten ersten Testquelle zurück:

cargo run --quiet -- check trial-plan.tsv trial-scans.tsv

Die Lampenfehlmenge sollte wieder eins betragen, mit l-two als beschädigt. Die zwei Berichte unterscheiden sich, weil ihre tatsächlich benannten Eingaben verschieden sind; keine Quelle wird stillschweigend ersetzt. Dieselbe fertige Abgleichimplementierung muss beide Fälle erklären.

Ein Eingabefehler darf weder zu einem Fehlmengenbericht werden noch stillschweigend auf das Originalbeispiel zurückfallen. Der nächste falsche Dateiname ist beabsichtigt und soll einen Status ungleich null liefern:

cargo run --quiet -- check trial-plans.tsv trial-scans.tsv

Die Fehlermeldung nennt die nicht vorhandene Datei trial-plans.tsv. Korrigiere die versehentliche Pluralendung und führe den Befehl erneut aus:

cargo run --quiet -- check trial-plan.tsv trial-scans.tsv

Verwende für einen absichtlichen Formatfehler das vorhandene Beispiel mit unbekanntem Zustand. Auch dieser Befehl soll einen Status ungleich null liefern und data/bad-status.tsv mit seiner Zeile nennen:

cargo run --quiet -- check trial-plan.tsv data/bad-status.tsv

broken ist ein ungültiges Wort, während damaged ein gültiger Zustand ist, der keinen Bedarf deckt. Wähle die gültigen Testscans erneut, um fortzufahren:

cargo run --quiet -- check trial-plan.tsv trial-scans.tsv

Kehre zuletzt zu den ursprünglichen Eingaben zurück:

cargo run --quiet -- check data/plan.tsv data/scans.tsv

Der ursprüngliche Bericht erscheint wieder, weil das Programm die tatsächlichen Pfade liest und weder einen zwischengespeicherten Bericht noch ein fest kodiertes Bereitschaftsmerkmal verwendet. Originale und Testquellen bleiben vollständig erhalten. Du kannst jede mit cat ansehen. Falls du versehentlich eine Testdatei bearbeitest, wiederhole ihren vollständigen Erstellungsblock oben. Die geschützten Originaldateien dienen nicht dazu, einen Codefehler zu beheben.

Zusammenfassung

Du hast den vollständigen Typabgleich aus einem Plan und eindeutigen Objektdatensätzen implementiert. Nur intakte Objekte deckten den Bedarf; teilweise Deckung ließ weiterhin Fehlmengen übrig, und beschädigte sowie überschüssige Ausrüstung blieb nachvollziehbar. Du hast ein weiteres Paar tatsächlicher Eingabepfade getestet, gewöhnliche Fehler behandelt und alle Quellen erhalten. In der Challenge kombinierst du Identitätssammlung und Abgleich für eine andere Reiseausrüstung.