{
"llm" : {
"feedback" : "# Exercise: fractal\n\n### Correctness\n- In `Triangles.drawRec` (Rekursionsfall) berechnest du für das „mittlere“ Dreieck teilweise Punkte mit festem `y1` (z.B. `(x1 + x2) / 2, y1`). Das ist nur korrekt, wenn die Kante zwischen `(x1,y1)` und `(x2,y2)` horizontal ist. Allgemein musst du den Mittelpunkt immer aus beiden y-Koordinaten berechnen, sonst entstehen bei anderen Dreieckslagen falsche Teil-Dreiecke.\n- In `Triangles.drawRec` (Basisfall) zeichnest du die dritte Kante als `g.drawLine(x0, y0, x2, y2)`. Das schliesst zwar das Dreieck, aber du zeichnest damit nicht die Kante `x2 -> x0` analog zu den anderen beiden (bei manchen Vergleichen/Checks kann das relevant sein, wenn exakt die drei Seiten in konsistenter Reihenfolge erwartet werden).\n\n### Suggestion\n- Schau dir an, wie du die drei Mittelpunkte der Seiten eines Dreiecks berechnest: Für jede Seite brauchst du den Mittelwert von **beiden** Endpunkten (also sowohl x als auch y). Überlege dir dann, welche 3 kleineren Dreiecke du mit diesen drei Mittelpunkten + den Original-Ecken rekursiv zeichnen willst.\n- Wenn du die Basis zeichnet, nutze gedanklich „jede Ecke verbindet sich mit der nächsten“: (0→1), (1→2), (2→0). So stellst du sicher, dass genau die drei Dreiecksseiten gezeichnet werden.\n\n### Code Style\n- In `Boxes.drawRec` mischst du Rekursion und direktes Zeichnen (`g.drawRect(...)`) im selben Rekursionszweig. Das ist zwar ok, aber für Lesbarkeit/Einheitlichkeit wäre es klarer, entweder überall rekursiv zu arbeiten oder den „direkt gezeichneten“ Teil explizit als Basisfall/Abkürzung zu kommentieren (warum genau dort nicht weiter rekursiv).\n- In `Triangles.drawRec` werden viele Ausdrücke wie `(x1 + x0) / 2` mehrfach inline wiederholt. Lege diese Mittelpunkte einmal in Variablen ab (wie `mid01x`, `mid01y`, …), dann wird die Geometrie nachvollziehbarer und weniger fehleranfällig.\n\n\n# Exercise: knapsack\n\n### Correctness\n- `pack(int i)` ist nicht implementiert; damit wird nie eine Lösung berechnet und `maxValue` bleibt immer 0, Tests können so nicht bestehen.\n- Die aktuelle Logik in `unloadItem(int i)` macht nur ein einzelnes Exemplar rückgängig; für „bis zu n gleiche Gegenstände“ musst du beim Backtracking sicherstellen, dass du genau die Anzahl wieder entfernst, die du zuvor für dieses Item geladen hast (sonst stimmt der Zustand `currWeight/currValue` nach der Rekursion nicht mehr).\n\n### Suggestion\n- Implementiere `pack(i)` als rekursives Durchprobieren aller Möglichkeiten pro Item: für jedes Item „0-mal bis maxN-mal einpacken“ (solange das Gewicht es erlaubt) und dann mit `i+1` weitermachen.\n- Achte darauf, wo du `maxValue` aktualisierst: typischerweise dann, wenn du alle Items betrachtet hast (Basisfall) und das aktuelle Gewicht zulässig ist.\n- Überlege dir für das „Entladen“: Entweder entlädst du in einer Schleife genauso oft, wie du geladen hast, oder du merkst dir die Anzahl geladener Exemplare pro Item und machst genau diese Änderungen rückgängig.\n\n### Code Style\n- `loadItem`/`unloadItem` sind ok, aber ohne implementiertes `pack()` sind sie aktuell ungenutzt; sobald du `pack()` fertig hast, prüfe, dass alle Hilfsmethoden wirklich verwendet werden.\n- In `KnapsackN` fehlt bei `main` die übliche Signatur `main(String[] args)` (kann je nach Test-/Runner-Setup wichtig sein).\n\n\n# Exercise: queens\n\n### Correctness\n- `QueensSolver.solve()` ist nicht implementiert und liefert immer `false`, damit wird keine Lösung 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- In `Queens` ist `main()` nicht als Einstiegspunkt verwendbar (Signatur passt nicht für Java-Programmstart), dadurch läuft das Programm typischerweise nicht wie gefordert an.\n\n### Suggestion\n- Für `solve()`: Überlege dir eine rekursive Backtracking-Funktion, die zeilenweise (oder spaltenweise) genau eine Dame platziert und beim Fehlschlag wieder entfernt (Undo-Schritt), bis alle Zeilen belegt sind.\n- Für `count()`: Ähnlich wie bei `solve()`, aber statt beim ersten Treffer zu stoppen, sammelst du die Anzahl aller vollständigen Platzierungen (Basisfall “alle Zeilen belegt” liefert 1).\n- Für `main()`: Prüfe, welche `main`-Methoden-Signatur Java erwartet, damit dein Programm beim Starten tatsächlich ausgeführt wird.\n\n### Code Style\n- In `getBoard()` ist `return this.board;` zwar ok, aber im Rest des Codes wird `this` nicht verwendet; entscheide dich konsistent für eine Variante.\n- Die TODO-Kommentare in `solve()`/`count()` sind ok während der Entwicklung, sollten aber nach der Implementierung entfernt werden.\n\n\n# Exercise: sudoku\n\n### Correctness\n- In `SudokuSolverImpl`, both `solved(...)` and `nofSolutions(...)` are still unimplemented (`return false` / `return 0`), so the Sudoku is never solved and the number of solutions is always reported as 0.\n- `Sudoku.java` has no valid entry point for a Java application: `main()` is missing `public static` and the `String[] args` parameter, so the program won’t start as required.\n\n### Suggestion\n- For the solver: think in terms of backtracking over a linear “field index” from `0` to `size*size - 1`: compute `(i, j)` from `fieldNr`, skip pre-filled fields, otherwise try values `1..size`, check validity with the checker, recurse, and undo (clear) when a value doesn’t lead to success.\n- For counting solutions: use the same recursion, but instead of stopping at the first found solution, accumulate a counter; also stop early once you reach the given `max` bound (and make sure the model ends up reset to the initial state after counting).\n- For `Sudoku.java`: adjust the `main` signature to the standard Java entry-point form so the GUI can be launched by the runtime.\n\n### Code Style\n- Leaving `// TODO implement` with hardcoded `return false` / `return 0` is fine temporarily, but once you start implementing, remove the TODOs and ensure the methods’ structure clearly separates base case vs. recursive step (readability for backtracking benefits a lot from that).\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: <0>"
}, {
"name" : "random2()",
"status" : "FAILED",
"message" : "expected: <340> but was: <0>"
}, {
"name" : "random3()",
"status" : "FAILED",
"message" : "expected: <558> but was: <0>"
}, {
"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
} ]
}
}