{
"llm" : {
"feedback" : "# Exercise: floodfill\n\n### Correctness\n- `Coord` überschreibt `hashCode()`, aber liefert `super.hashCode()` zurück (Identitäts-Hash). Damit können `HashSet`-basierte Worklists (`WorkHashSet`) gleiche Koordinaten nicht zuverlässig als “gleich” erkennen → Flood-Fill kann massiv mehrmals dieselben Pixel einplanen und das Verhalten der `WorkHashSet`-Variante entspricht nicht der Aufgabenidee.\n- In `Coord` fehlt außerdem `equals(...)`. Für Sets/Maps (HashSet/TreeSet) ist das notwendig, damit Duplikate wirklich verhindert werden.\n- `IterativeFloodFill.fill(...)` fügt den Startpunkt zur Worklist hinzu, **bevor** du prüfst, ob `newColor` und `oldColor` gleich sind. Wenn beides gleich ist, bleibt mindestens ein Element in der Worklist liegen; beim nächsten Fill-Aufruf wird dann potentiell “alter Müll” mitverarbeitet.\n- `IterativeFloodFill` benutzt eine `WorkList` als Feld und leert sie nicht explizit am Anfang. Wenn ein früherer Aufruf Elemente übrig lässt (z.B. durch obigen Fall), beeinflusst das spätere Fills.\n- In `WorkTree.remove()` verwendest du `coords.removeFirst()`. `TreeSet` hat diese Methode nicht (Compile-Error). Du brauchst dort einen Iterator-/First-Element-Ansatz, der zu `TreeSet` passt.\n- Die Anzeige des aktuell gewählten Algorithmus in `drawFooter()` benutzt bei `IterativeFloodFill` `i.coords.toString()` (also die WorkList), statt die geforderte `toString()`-Schnittstelle des Algorithmus selbst konsistent zu nutzen; damit erfüllst du die “Algorithmus per toString anzeigen”-Anforderung nur teilweise bzw. nicht wie vorgesehen.\n\n### Suggestion\n- Überlege dir für `Coord`: Wann sind zwei Koordinaten “gleich”? Implementiere dazu passend `equals` und einen `hashCode`, der aus `x` und `y` berechnet wird, damit `HashSet`/`HashMap` korrekt deduplizieren können.\n- Sorge in `IterativeFloodFill.fill(...)` dafür, dass du gar nicht erst mit der Worklist arbeitest, wenn es nichts zu tun gibt (Startfarbe == neue Farbe). Achte dabei besonders darauf, wann du das erste Element hinzufügst.\n- Stell sicher, dass pro `fill(...)`-Aufruf die Worklist in einem definiert leeren Zustand startet. Entweder durch “neu erzeugen” pro Fill oder durch garantiertes Leeren (je nach Design).\n- Für `WorkTreeSet`: Schau nach, wie man aus einem `TreeSet` das “erste” Element holt und entfernt, ohne eine nicht existierende Methode zu verwenden (Iterator oder `first()` + remove).\n- Für die Statuszeile: Lass eher den aktuell selektierten `FillAlgorithm` selbst einen sinnvollen Text liefern (ggf. inkl. verwendeter WorkList) und verwende dann einfach diesen String im Footer, statt in `DrawingApp` per `instanceof` Speziallogik zu bauen.\n\n### Code Style\n- Viele Felder/Konstruktoren/Methoden sind package-private ohne klaren Grund (`Coord.x/y`, `IterativeFloodFill.coords`, `Coord(...)`): kapsle Daten eher (private + Getter/Methoden), damit du nicht überall direkt auf Felder zugreifen musst.\n- In `DrawingApp` ist `int it = 0;` sehr nichtssagend; ein Name wie `algorithmIndex` wäre verständlicher.\n- `FillAlgorithm`-Methodensignatur: das `public` im Interface ist redundant.\n- In `Coord.compareTo(...)` nutzt du Subtraktion (`y - c.y`), was bei großen Werten unsauber sein kann; üblicher ist `Integer.compare(...)`.\n- `Coord` implementiert `Comparable`, aber ohne `equals` ist das Zusammenspiel mit `TreeSet` schwer vorhersagbar; bei sortierten Sets sollte `compareTo` konsistent zu `equals` sein.\n\n\n# Exercise: flashcard\n\n### Correctness\n- Duplikate werden nicht zuverlässig verhindert: Du fügst Karten immer in Fach 1 hinzu, prüfst aber nicht, ob die Karte eventuell schon in einem anderen Fach existiert; ein `Set` pro Fach verhindert nur Duplikate *innerhalb* dieses einen Fachs.\n- Beim Hinzufügen setzt du `group` der Karte nicht passend zum Startfach (alle Karten sollen in Fach 1 starten, bei dir steht `group` initial auf `0`, aber das ist nur implizit „Fach 1“, und es wird nicht aktiv synchronisiert).\n- `promoteCard`: Du verwendest `Math.min(card.group + 1, groups.size())` und greifst danach auf `groups.get(card.group)` zu; sobald `card.group == groups.size()` passiert, ist das ein ungültiger Index (letztes Fach wäre `groups.size() - 1`).\n- `demoteCard`: Falsch beantwortete Karten sollen zurück in Fach 1; bei dir gehen sie nur ein Fach zurück (`group - 1`), nicht direkt zurück ganz nach unten.\n- Die Session-Ziehlogik entspricht nicht dem beschriebenen Beispiel-Muster (z. B. bei 3 Fächern 8/4/2). Deine Formel `1 << (groups.size() - i)` liefert bei 3 Fächern eher 8/4/2, aber nur wenn die Indizes/Zuordnung genau stimmen; aktuell zieht sie aus dem *ersten* Listenfach am meisten, aber es ist unklar/inkonsistent, welches Fach „1“ ist (Index 0 vs. Fach 1). Außerdem ist das Muster in der Aufgabenbeschreibung ein Beispiel, aber deine Implementierung sollte sauber an „Fach 1, Fach 2, …“ gekoppelt sein.\n\n### Suggestion\n- Wenn du Duplikate über alle Fächer verhindern willst, überlege dir eine Methode, die vor `addCard` alle Sets durchsucht und nur dann einfügt, wenn die Karte nirgends vorhanden ist (die Aufgabe beschreibt genau diese O(f)-Suche).\n- Entscheide dich konsequent, ob `group == 0` „Fach 1“ bedeutet und halte diese Abbildung überall ein (bei Erstellung, Hinzufügen, Promote/Demote, und beim Ziehen der Karten).\n- Beim Promoten: prüfe, was der größte erlaubte Index für `groups.get(...)` ist, und klemme `card.group` auf diesen Wert, nicht auf die Anzahl Fächer.\n- Beim Demoten: vergleiche die geforderte Regel „falsch => zurück in Fach 1“ mit deiner aktuellen Umsetzung und passe die Zielgruppe entsprechend an.\n- Für die Session-Verteilung: mach dir explizit klar, aus welchem Fach wie viele Karten kommen sollen (z. B. abhängig vom Fachindex). Teste das mit kleinem Setup (z. B. 3 Fächer, je 10 Karten) und gib dir debugweise aus, aus welchen Fächern wie viele gezogen wurden.\n\n### Code Style\n- In `FlashCard` fehlt `hashCode()` passend zu `equals()`; auch wenn es „manchmal“ zu funktionieren scheint, ist das bei Sets/Hash-basierten Collections ein Muss.\n- Viele Felder/Konstruktoren sind package-private (`String front`, `String back`, `int group`, Konstruktor), was die Kapselung schwächt; überlege `private` + Getter/Methoden statt direktem Zugriff.\n- In `FlashCardSystem` sind Felder ebenfalls nicht gekapselt (`groups`); besser `private` und über Methoden arbeiten.\n- Parsing im `add`-Command ist fragil (`split(\"/\")` ohne Limit/Trim); außerdem bleiben Leerzeichen in `front` typischerweise drin. Das ist nicht direkt eine Anforderung, aber es macht die Bedienung unnötig fehleranfällig.\n- `ArrayList<LinkedHashSet<FlashCard>> groups = new ArrayList<>();;` enthält ein doppeltes Semikolon.\n\n\n# Exercise: imagestats\n\n### Correctness\n- Du hast das Problem direkt behoben (durch Implementieren von `hashCode()`), obwohl die Übung explizit sagt, dass du das Problem **nicht lösen musst**, sondern es **finden, eingrenzen und mit einem Minimalbeispiel reproduzieren** sollst.\n- In deiner Abgabe fehlt ein eigenes **Minimalbeispiel-Programm**, das das fehlerhafte Verhalten reproduziert (z.B. mit `HashMap`/`HashSet` und zwei logisch gleichen `Color`-Objekten).\n\n### Suggestion\n- Lass den Code so, dass das Fehlverhalten noch auftritt, und versuche dann ein wirklich kleines Snippet zu schreiben, das **ohne Bildverarbeitung** zeigt, dass Duplikate in einer `HashMap`/`HashSet` nicht erkannt werden.\n- Konzentriere dich darauf, welche Methoden bei `HashMap`/`HashSet` für „Duplikat-Erkennung“ relevant sind (Tipp: es ist nicht nur `equals`), und prüfe, ob dein Minimalbeispiel genau diesen Mechanismus triggert.\n\n### Code Style\n- Du hast in `Color.java` einen auskommentierten alternativen `hashCode`-Return stehen (`// return 256 * ...`); solche auskommentierten Reste besser entfernen oder klar begründen, damit die Abgabe fokussiert bleibt.\n- `equals` ist nicht mit `@Override` annotiert; das ist keine Pflicht, aber eine sehr sinnvolle Konvention, weil der Compiler dann sofort meckert, falls du die Signatur aus Versehen falsch schreibst.\n",
"status" : "SUCCESS"
}
}