{
"llm" : {
"feedback" : "# Exercise: fractal\n\n### Correctness\n- In `Boxes.drawRec` wird in jedem Rekursionsschritt sofort ein Rechteck gezeichnet; dadurch werden auch bei `n > 0` zusätzlich große „Eltern“-Boxen gezeichnet, was nicht dem üblichen Rekursionsaufbau mit klarer Basisbedingung entspricht.\n- In `Boxes.drawRec` fehlt ein rekursiver Aufruf für das bottom-left-Quadrat (du zeichnest nur top-left, top-right und bottom-right rekursiv).\n- In `Triangles.drawRec` wird in jedem Rekursionsschritt sofort das aktuelle Dreieck gezeichnet; damit zeichnest du bei `n > 0` ebenfalls „Eltern“-Dreiecke mit und nicht nur die Dreiecke der untersten Stufe (Basisfall).\n- In `Triangles.drawRec` ist die Abbruchbedingung `n < 0`; damit wird bei `n == 0` trotzdem weiter rekursiv aufgerufen (bis `-1`), was nicht der geforderten Basisfall-Logik entspricht.\n\n### Suggestion\n- Überlege dir für beide Formen einen klaren Basisfall (typisch: bei einer bestimmten Rekursionstiefe genau *ein* Element zeichnen) und nur sonst die Unterprobleme erzeugen.\n- Prüfe bei den Boxen, welche 4 Quadranten es nach dem Halbieren gibt, und ob du wirklich alle vier Bereiche entweder rekursiv behandelst oder gezielt „direkt“ zeichnest (je nach Vorgabe der Figur).\n- Bei den Dreiecken: entscheide, ob „Zeichnen“ nur im Basisfall passieren soll, und berechne dann die Mittelpunkte der Kanten einmal, um daraus die drei kleineren Dreiecke für den nächsten Rekursionsschritt zusammenzusetzen.\n- Passe die Abbruchbedingung so an, dass bei `n == 0` keine weiteren rekursiven Aufrufe mehr stattfinden.\n\n### Code Style\n- In beiden Klassen steht noch der `// TODO implement` Kommentar, obwohl schon implementiert wurde; den kannst du entfernen/aktualisieren.\n- In `Triangles.drawRec` ist eine auskommentierte Codezeile (`//drawRec(...)`) übrig geblieben; solche Reste besser entfernen, sobald du dich für eine Variante entschieden hast.\n- Das Muster „Parameter wie `s` überschreiben“ (z.B. `s = s / 2;`) kann die Lesbarkeit senken; ein neuer Variablenname für die Kind-Größe macht die Rekursion oft verständlicher.\n\n\n# Exercise: knapsack\n\n### Correctness\n- Du berücksichtigst `maxN` nicht: In deiner Rekursion wird jeder Gegenstand maximal einmal eingeladen (0/1-Knapsack), die Aufgabe verlangt aber, dass jeder Gegenstand bis zu `maxN`-mal mitgenommen werden kann.\n- Durch `unloadItem(i)` machst du genau ein Laden rückgängig; wenn du einen Gegenstand mehrfach laden würdest, müsste das Rückgängigmachen dazu passen, sonst bleibt der Zustand (`currWeight`, `currValue`) falsch für nachfolgende Rekursionszweige.\n\n### Suggestion\n- Überlege dir, wie du in `pack(i)` nicht nur die zwei Entscheidungen „nicht nehmen“ und „einmal nehmen“ abbildest, sondern „0, 1, 2, ..., maxN-mal nehmen“ für genau den Gegenstand `i` (z.B. über eine Schleife).\n- Achte darauf, dass nach dem Durchprobieren aller „n-mal nehmen“-Varianten für Item `i` der Rucksack-Zustand wieder exakt so ist wie vor dem ersten Laden dieses Items (sonst verfälscht das die weiteren Pfade der Suche).\n\n### Code Style\n- In `pack(int i)` sind noch viele `// TODO`-Kommentare, obwohl Code vorhanden ist; das macht es schwer zu lesen und sollte bereinigt/aktualisiert werden.\n- Die Kommentare sind teils unvollständig/umgangssprachlich („Welche Bedingungen müssen gelten, das“); lieber kurz und präzise beschreiben, was der Block macht (Base Case, Rekursionsschritt, etc.).\n\n\n# Exercise: sudoku\n\n### Correctness\n- In `solved(...)`: Wenn ein Feld bereits vorbelegt ist (`model.get(row,col) != 0`), rufst du zwar rekursiv `solved(model, fieldNr + 1)` auf, aber du ignorierst dessen Rückgabewert und gibst danach immer `true` zurück. Dadurch kann `solved` auch dann „erfolgreich“ melden, wenn später im Sudoku keine Lösung gefunden wird.\n- `nofSolutions(...)` ist noch nicht implementiert und gibt immer `0` zurück, damit ist Anforderung 4 nicht erfüllt (Lösungen zählen, bis maximal `MAX`).\n- Laut Interface-Vertrag soll bei `solved(...) == false` das Model auf den Initialzustand zurückgesetzt sein. Durch das aktuelle Verhalten beim „vorbelegtes Feld“-Zweig kann es passieren, dass tiefere Rekursionen Felder verändert haben, aber trotzdem `true` zurückkommt bzw. das Reset-Verhalten bei „kein Erfolg“ nicht sauber greift.\n\n### Suggestion\n- Schau dir im „vorbelegtes Feld“-Fall an, was das Ergebnis des rekursiven Aufrufs bedeutet: Du solltest diese Information nach oben weiterreichen statt sie zu verwerfen.\n- Für `nofSolutions`: Denk an dieselbe Backtracking-Struktur wie bei `solved`, aber statt beim ersten Treffer abzubrechen, musst du weiter suchen und mitzählen. Eine Abbruch-/Cutoff-Bedingung brauchst du zusätzlich, sobald du `MAX` erreicht hast (oder „max“ im rekursiven Parameter aufgebraucht ist).\n- Um den Zustand des Models korrekt zu halten: Überprüfe, an welchen Stellen du ein Feld wieder leeren musst, wenn ein Versuch nicht klappt, und ob das auch in allen Rückgabepfaden passiert.\n\n### Code Style\n- In `solved(...)` sind viele „TODO/Notizen“-Kommentare im Code; wenn du fertig bist, wäre es besser, diese zu entfernen oder in kurze, erklärende Kommentare umzuwandeln.\n- Vermeide Magic Numbers wie `81` und feste `9` in der Solver-Logik; nutze stattdessen `model.size()` (und `size*size`), dann funktioniert dein Solver auch für andere Sudoku-Grössen, falls das Framework das zulässt.\n- In `Sudoku.java` ist `main()` nicht `public static void main(String[] args)`, wodurch das Programm so typischerweise nicht direkt startbar ist (auch wenn das nicht Teil der Solver-Aufgabe ist, ist es für Tests praktisch).\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" : "PASSED",
"message" : null
}, {
"name" : "uselessStuff()",
"status" : "PASSED",
"message" : null
}, {
"name" : "random1()",
"status" : "FAILED",
"message" : "expected: <190> but was: <174>"
}, {
"name" : "random2()",
"status" : "FAILED",
"message" : "expected: <340> but was: <279>"
}, {
"name" : "random3()",
"status" : "FAILED",
"message" : "expected: <558> but was: <357>"
}, {
"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" : "Board must contain exactly N queens ==> expected: <8> but was: <0>"
}, {
"name" : "boardSizeIsCorrectForN4()",
"status" : "PASSED",
"message" : null
}, {
"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" : "N=4 has exactly 2 solutions ==> expected: <2> but was: <0>"
}, {
"name" : "countN5()",
"status" : "FAILED",
"message" : "N=5 has exactly 10 solutions ==> expected: <10> but was: <0>"
}, {
"name" : "countN6()",
"status" : "FAILED",
"message" : "N=6 has exactly 4 solutions ==> expected: <4> but was: <0>"
}, {
"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" : "N=8 has valid queen placements ==> expected: <true> but was: <false>"
}, {
"name" : "solveReturnsFalseForN2()",
"status" : "PASSED",
"message" : null
}, {
"name" : "solveReturnsFalseForN3()",
"status" : "PASSED",
"message" : null
} ]
}
}