{
"llm" : {
"feedback" : "# Exercise: fractal\n\n### Correctness\n- In `Triangles.drawRec` (Basisfall `n == 0`) zeichnest du die dritte Kante mit `g.drawLine(x0, y0, x2, y2)` statt mit `g.drawLine(x2, y2, x0, y0)` – geometrisch ist das zwar die gleiche Linie, aber du erfüllst damit nicht ganz die Vorgabe „triangle mit g.drawLine(...) multiple times“ konsistent als geschlossene Kette (die Lösung erwartet explizit alle drei Kanten in Reihenfolge).\n- In `Triangles.drawRec` (rekursiver Fall) benutzt du für den Mittelpunkt der unteren Kante als y-Koordinate hart `y1`. Das stimmt nur, wenn diese Kante exakt horizontal ist; die Rekursion soll aber allgemein über Mittelpunkte der Kanten laufen (also auch über `y`-Mittelwerte), sonst werden bei anderen Ausgangsdreiecken falsche Teil-Dreiecke erzeugt.\n\n### Suggestion\n- Schau dir im Basisfall an, welche drei Punkte du verbinden musst, damit wirklich die drei Kanten des Dreiecks gezeichnet werden (jeweils „Punkt A zu Punkt B“, „B zu C“, „C zu A“).\n- Für die Rekursion: Berechne die drei Kanten-Mittelpunkte jeweils wirklich als Mittelwert der beiden Endpunkte (für **x und y**), und verwende dann diese drei Punkte, um die 3 Teil-Dreiecke zu definieren. Prüfe dabei besonders den Mittelpunkt der Kante zwischen `(x1,y1)` und `(x2,y2)`.\n\n### Code Style\n- In `Triangles.drawRec` rechnest du dieselben Mittelpunkte mehrfach direkt in den Parameterlisten aus; das macht den Code schwer lesbar und fehleranfällig. Lege die drei Mittelpunkte einmal in gut benannten Variablen ab und verwende sie dann in den rekursiven Aufrufen.\n- In `Boxes.drawRec` sind die Kommentare hilfreich, aber gemischte Sprache/Abkürzungen („rechts oben“, „recht unten“) könnten konsistenter benannt werden.\n\n\n# Exercise: knapsack\n\n### Correctness\n- In `pack(int i)` rufst du `pack(maxN - 1)` auf. Damit verwendest du `maxN` (Anzahl Kopien) fälschlicherweise als Index für den nächsten Gegenstand und überspringst/verdrehst damit die Item-Rekursion.\n- Deine Rekursion betrachtet pro Gegenstand effektiv nur die Fälle „0-mal“ oder „1-mal“ mitnehmen; die Anforderung ist aber, dass jeder Gegenstand bis zu `maxN`-mal mitgenommen werden kann.\n- `unloadItem(int i)` macht genau ein `loadItem` rückgängig. Falls du einen Gegenstand mehrfach lädst (was für `maxN` nötig wäre), wird dein Backtracking-Zustand (`currWeight/currValue`) nicht korrekt wiederhergestellt.\n\n### Suggestion\n- Überlege dir eine Rekursionsstruktur, in der `i` immer „welches Item bin ich gerade am Entscheiden?“ bedeutet (also `i`, `i+1`, …) und die Anzahl Kopien separat behandelt wird.\n- Für „bis zu `maxN`-mal“ brauchst du pro Item eine Schleife/mehrere rekursive Schritte, die das Item wiederholt einlädt (0, 1, 2, …, `maxN`), und dazwischen jeweils in das nächste Item verzweigt.\n- Achte beim Backtracking darauf, dass nach dem Durchprobieren aller Kopien eines Items der Zustand wieder exakt so ist wie vor dem Item (wenn du z.B. `k`-mal geladen hast, musst du auch `k`-mal bzw. um `k*weight`/`k*value` zurücksetzen).\n\n### Code Style\n- Die Kommentare `// TODO implement` sind in `pack` sowie bei `loadItem/unloadItem` nicht mehr passend, da dort bereits Logik steht; entferne oder aktualisiere sie.\n\n\n# Exercise: queens\n\n### Correctness\n- `QueensSolver.solve()` ist nicht implementiert und liefert immer `false`, damit wird nie eine Lösung gesucht/gefunden und das Board bleibt leer.\n- `QueensSolver.count()` ist nicht implementiert und liefert immer `0`, damit wird die Anzahl Lösungen nicht gezählt.\n\n### Suggestion\n- Für `solve()`: Überlege dir eine rekursive Backtracking-Funktion, die zeilenweise arbeitet (z.B. “platziere eine Dame in der aktuellen Zeile in einer gültigen Spalte und versuche dann die nächste Zeile”). Wichtig ist dabei auch das Rückgängigmachen der Platzierung, wenn der rekursive Versuch fehlschlägt.\n- Für `count()`: Nutze eine sehr ähnliche Rekursion wie bei `solve()`, aber statt beim ersten Treffer aufzuhören summierst du alle Treffer auf. Auch hier musst du nach jedem rekursiven Aufruf die gesetzte Dame wieder entfernen, bevor du die nächste Spalte probierst.\n\n### Code Style\n- In `Queens.main()` fehlt `static` und die `String[] args`-Signatur, dadurch ist es kein gültiger Java-Programmeinstiegspunkt (so wie es typischerweise erwartet wird).\n\n\n# Exercise: sudoku\n\n### Correctness\n- In `SudokuSolverImpl`, `solved(...)` is not implemented and always returns `false`, so the Sudoku is never solved as required.\n- In `SudokuSolverImpl`, `nofSolutions(...)` is not implemented and always returns `0`, so the required counting of solutions is missing.\n- In `Sudoku.java`, the entry point is not a valid Java `main` method (`void main()` instead of `public static void main(String[] args)`), so the application won’t start as intended.\n\n### Suggestion\n- For `solved(...)`: think of a recursive backtracking approach that walks through the fields in a fixed order (e.g., by `fieldNr`), skips pre-filled cells, tries values `1..size()`, checks validity with `checker.oneOK(...)`, and backtracks (clear the cell) when a path fails.\n- For `nofSolutions(...)`: reuse the same traversal/backtracking idea, but instead of stopping at the first found solution, accumulate a counter; also ensure you stop exploring further branches once you reached the given `max` bound.\n- For `Sudoku.java`: adjust the method signature so the JVM recognizes it as the program entry point; compare against the usual `main` signature used in Java applications.\n\n### Code Style\n- The `// TODO implement` placeholders should be removed once you implement the methods to avoid leaving “unfinished” markers in final code.\n- Indentation/bracing is a bit inconsistent (some methods use tabs, others spaces); pick one formatting style and apply it consistently across your changes.\n",
"status" : "SUCCESS"
},
"unitTest" : {
"tests" : [ {
"name" : "allZero()",
"status" : "PASSED",
"message" : null
}, {
"name" : "uselessStuff()",
"status" : "FAILED",
"message" : null
}, {
"name" : "random1()",
"status" : "FAILED",
"message" : null
}, {
"name" : "random2()",
"status" : "FAILED",
"message" : null
}, {
"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
} ]
}
}