{
"llm" : {
"feedback" : "# Exercise: fractal\n\n### Correctness\n- In `Boxes.drawRec(...)` zeichnest du in jedem Rekursionsschritt sofort ein Rechteck und gehst dann weiter, bis `n < 0` ist. Dadurch wird auch für `n == 0` weiter rekursiv gezeichnet (weil du erst bei `< 0` stoppst) und die Rekursionstiefe/Anzahl Rechtecke passt nicht zur üblichen Definition „bei n==0 nur ein Quadrat zeichnen, sonst weiter aufteilen“.\n- In `Boxes.drawRec(...)` fehlt der vierte Teil-Quadrant (unten links). Du rufst nur drei rekursive Unterquadrate auf (oben links, oben rechts, unten rechts), aber nicht unten links.\n- In `Triangles.drawRec(...)` zeichnest du das Dreieck in jedem Rekursionsschritt und rufst dann weiter rekursiv auf, bis `n < 0`. Damit wird ebenfalls für `n == 0` noch weiter rekursiv gezeichnet und du zeichnest deutlich mehr Linien als gefordert (Basisfall vs. Rekursionsfall ist nicht getrennt).\n- In `Triangles.drawRec(...)` erzeugst du dadurch auch nicht die „Sierpinski“-artige Struktur (nur im Basisfall Linien, sonst in drei Teildreiecke zerlegen), sondern überzeichnest ständig die großen Dreiecke erneut.\n\n### Suggestion\n- Überlege dir für beide Formen eine klare Abbruchbedingung: Was soll *genau* passieren, wenn `n == 0`? (Typischerweise: nur die primitive Form zeichnen und **nicht** weiter rekursiv aufrufen.)\n- Trenne in `Boxes` gedanklich „Rekursionsfall“ und „Basisfall“: Im Rekursionsfall teilst du in vier Quadrate gleicher Größe auf; prüfe dann, ob du wirklich alle vier Positionen abdeckst (x/y-Offsets für alle Quadranten).\n- In `Triangles`: Berechne die drei Mittelpunkte der Dreiecksseiten (machst du schon implizit) und rufe dann rekursiv **nur** auf den drei äußeren Teildreiecken auf. Zeichne die Linien erst im Basisfall, nicht bei jedem rekursiven Aufruf.\n- Teste mit kleinen `n` (0, 1, 2): Wenn bei `n=0` schon „zu viel“ gezeichnet wird oder die Rekursion weiterläuft, ist die Abbruchbedingung noch nicht passend.\n\n### Code Style\n- In beiden Klassen sind die Kommentare `// TODO implement` noch drin, obwohl du schon implementiert hast – entweder entfernen oder anpassen.\n- Das Muster `if (n < 0) return;` ist hier irritierend, weil `n` aus der UI nie negativ sein sollte und du eigentlich einen semantischen Basisfall (`n == 0`) ausdrücken willst; das erhöht die Lesbarkeit, wenn du die Bedingung an die Problemdefinition koppelst.\n- In `Triangles` ist eine auskommentierte `drawRec(...)`-Zeile enthalten; solche Reste besser entfernen, sobald du dich für eine Variante entschieden hast.\n\n\n# Exercise: knapsack\n\n### Correctness\n- In `pack(int i)` entlädst du am Ende immer `maxN + 1`-mal (`for (j = 0; j <= maxN; j++)`), obwohl du im Aufbau-Teil höchstens `maxN`-mal geladen hast; dadurch wird `currWeight/currValue` zu weit reduziert (kann negativ werden) und die Zustände der Rekursion stimmen nicht mehr.\n- Deine Entlade-Logik ist nicht an die tatsächlich geladene Anzahl gekoppelt: Wenn du wegen `currWeight > maxWeight` frühzeitig `return` machst, wird in diesem Rekursionszweig nicht mehr “aufgeräumt”, obwohl ggf. bereits Items geladen wurden (das kann den Zustand für nachfolgende Zweige verfälschen).\n\n### Suggestion\n- Überlege dir eine Invariante: Wenn `pack(i)` zurückkehrt, müssen `currWeight` und `currValue` exakt wieder so sein wie beim Eintritt in `pack(i)`. Prüfe, ob deine Lade-/Entlade-Schleifen das wirklich garantieren.\n- Zähle konkret nach, wie oft du in deinem ersten `for`-Block `loadItem(i)` ausführst (in Abhängigkeit von `maxN`) und sorge dafür, dass du genau dieselbe Anzahl wieder entfernst – nicht mehr und nicht weniger.\n- Wenn du bei Übergewicht sofort abbrichst: Stelle sicher, dass du entweder gar nicht erst überladen kannst (vor dem Laden prüfen) oder dass du vor dem Return den Zustand wieder korrekt zurücksetzt.\n\n### Code Style\n- Entferne die vielen `// TODO implement` und auskommentierten “TODO Base Case”-Hinweise, wenn du die Logik bereits umgesetzt hast; das macht den Code unnötig unübersichtlich.\n- Die zweite Schleife zum Entladen wirkt “magisch”; lesbarer wäre es, die Anzahl geladener Items explizit zu tracken (z.B. über eine Variable) und dann genau diese Anzahl zu entladen.\n\n\n# Exercise: sudoku\n\n### Correctness\n- In `Sudoku.java` ist die `main`-Methode nicht als Java-Entry-Point implementiert (`public static void main(String[] args)` fehlt), dadurch startet das Programm so nicht.\n- In `nofSolutions(...)` wird das `max`-Limit nicht korrekt “weitergereicht”: Du rufst rekursiv immer mit dem gleichen `max` auf, wodurch insgesamt mehr als `MAX` Lösungen gezählt/gesucht werden können (das Abbrechen passiert dann ggf. zu spät bzw. nicht zuverlässig global).\n- `nofSolutions(...)` setzt das Modell nicht sicher in jedem Rückkehrpfad wieder auf den Ursprungszustand zurück: Beim Fall `zähler >= max` wird zwar das aktuelle Feld geleert, aber weiter oben liegende Felder bleiben ggf. gesetzt, weil du vor dem frühen `return` nicht garantiert aufräumst (Anforderung: “model was reset to its initial state”).\n\n### Suggestion\n- Schau dir die Methodensignatur an, die Java als Startpunkt erwartet, und vergleiche sie mit deiner `main()`-Methode.\n- Überlege bei `nofSolutions`, wie viele Lösungen du **bereits** gefunden hast, und wie viele du **noch** maximal finden darfst; genau diese Restmenge solltest du an den rekursiven Aufruf übergeben.\n- Für das “Model reset”: Achte darauf, dass du beim Verlassen eines Rekursions-Levels (egal ob normal oder per frühem Abbruch) immer alle von diesem Level gesetzten Werte wieder entfernst. Ein guter Ansatz ist, das Zurücksetzen strukturell so zu platzieren, dass es nicht von einem bestimmten `if`-Zweig abhängt.\n\n### Code Style\n- Mischsprache und Tippfehler in Kommentaren/Bezeichnern (z.B. `zähler`, “Cheken”, “Umrechunng”, “filedNr”) machen es unnötig schwer zu lesen; konsistente englische oder deutsche Begriffe und korrekte Schreibweise helfen.\n- Umlaute in Variablennamen (`zähler`) können je nach Tooling/Encoding Probleme machen; besser ASCII-only Namen verwenden.\n- Mehrfaches `model.clear(row, col)` innerhalb der Schleife in `solved(...)` ist funktional ok, aber etwas “verstreut”; eine klarere Struktur (setzen → testen → rekursiv → am Ende zurücksetzen) verbessert die Lesbarkeit.\n\n\n# Exercise: queens\n\nLlm Evaluation ist für diese Aufgabe deaktiviert. Entferne die .llmignore Datei vom Package der Aufgabe.\n",
"status" : "SUCCESS"
},
"unitTest" : {
"tests" : [ {
"name" : "allZero()",
"status" : "FAILED",
"message" : "Connection refused to host: 172.25.0.6; nested exception is: \n\tjava.net.ConnectException: Connection refused"
}, {
"name" : "uselessStuff()",
"status" : "FAILED",
"message" : "Connection refused to host: 172.25.0.7; nested exception is: \n\tjava.net.ConnectException: Connection refused"
}, {
"name" : "random1()",
"status" : "FAILED",
"message" : "expected: <190> but was: <150>"
}, {
"name" : "random2()",
"status" : "FAILED",
"message" : "expected: <340> but was: <246>"
}, {
"name" : "random3()",
"status" : "FAILED",
"message" : "expected: <558> but was: <544>"
}, {
"name" : "boardIsValidAfterSolveN4()",
"status" : "FAILED",
"message" : "Board must contain exactly N queens ==> expected: <4> but was: <0>"
}, {
"name" : "boardIsValidAfterSolveN5()",
"status" : "FAILED",
"message" : "Board must contain exactly N queens ==> expected: <5> but was: <0>"
}, {
"name" : "boardIsValidAfterSolveN8()",
"status" : "FAILED",
"message" : "Connection refused to host: 172.25.0.8; nested exception is: \n\tjava.net.ConnectException: Connection refused"
}, {
"name" : "boardSizeIsCorrectForN4()",
"status" : "FAILED",
"message" : "Connection refused to host: 172.25.0.9; nested exception is: \n\tjava.net.ConnectException: Connection refused"
}, {
"name" : "boardSizeIsCorrectForN8()",
"status" : "PASSED",
"message" : null
}, {
"name" : "countN1()",
"status" : "FAILED",
"message" : "N=1 has exactly 1 solution ==> expected: <1> but was: <0>"
}, {
"name" : "countN2()",
"status" : "PASSED",
"message" : null
}, {
"name" : "countN3()",
"status" : "PASSED",
"message" : null
}, {
"name" : "countN4()",
"status" : "FAILED",
"message" : "Connection refused to host: 172.25.0.10; nested exception is: \n\tjava.net.ConnectException: Connection refused"
}, {
"name" : "countN5()",
"status" : "FAILED",
"message" : "N=5 has exactly 10 solutions ==> expected: <10> but was: <0>"
}, {
"name" : "countN6()",
"status" : "FAILED",
"message" : "Connection refused to host: 172.25.0.11; nested exception is: \n\tjava.net.ConnectException: Connection refused"
}, {
"name" : "countN8()",
"status" : "FAILED",
"message" : "N=8 has exactly 92 solutions ==> expected: <92> but was: <0>"
}, {
"name" : "solveReturnsTrueForN1()",
"status" : "FAILED",
"message" : "N=1 has exactly one solution ==> expected: <true> but was: <false>"
}, {
"name" : "solveReturnsTrueForN4()",
"status" : "FAILED",
"message" : "N=4 has valid queen placements ==> expected: <true> but was: <false>"
}, {
"name" : "solveReturnsTrueForN8()",
"status" : "FAILED",
"message" : "Connection refused to host: 172.25.0.12; nested exception is: \n\tjava.net.ConnectException: Connection refused"
}, {
"name" : "solveReturnsFalseForN2()",
"status" : "PASSED",
"message" : null
}, {
"name" : "solveReturnsFalseForN3()",
"status" : "FAILED",
"message" : "Connection refused to host: 172.25.0.13; nested exception is: \n\tjava.net.ConnectException: Connection refused"
} ]
}
}