{
"llm" : {
"feedback" : "# Exercise: fractal\n\n### Correctness\n- In `Triangles.drawRec` (Basisfall `n == 0`) zeichnest du die dritte Kante als `g.drawLine(x0, y0, x2, y2)`; gefordert ist ein geschlossenes Dreieck aus drei Seiten, d. h. die dritte Linie muss die beiden übrigen Endpunkte verbinden (bei dir ist es nicht die “fehlende” Kante zwischen den passenden Punkten).\n- In `Triangles.drawRec` (Rekursion) ist der 2. rekursive Aufruf geometrisch inkonsistent: Du verwendest als dritten Punkt `( (x1+x2)/2, y1 )` und setzt dabei `y1` fest statt den Mittelpunkt zwischen `(x1,y1)` und `(x2,y2)` zu nehmen. Dadurch ist das Teil-Dreieck nicht korrekt aus den Seitenmittelpunkten konstruiert und die Fraktalform wird verzerrt.\n\n### Suggestion\n- Prüfe im Basisfall, welche drei Kanten ein Dreieck wirklich hat: Jede Kante verbindet genau zwei der drei Eckpunkte, und am Ende muss ein geschlossener Umlauf entstehen. Vergleiche deine drei `drawLine`-Aufrufe damit.\n- Für die Rekursion: Berechne zuerst die drei Seitenmittelpunkte (für jede Dreiecksseite jeweils Mittelwert von x **und** y der beiden Endpunkte). Verwende dann diese drei Punkte, um die drei kleineren Dreiecke zu definieren (oben, unten links, unten rechts). Achte darauf, nicht bei einem Mittelpunkt “einfach y1 zu übernehmen”, sondern wirklich zu mitteln.\n\n### Code Style\n- In `Boxes.drawRec` sind die deutschen Inline-Kommentare ok, aber mische nicht Kommentar und Code-Formatierung: z. B. bei `g.drawRect(x,y+(s/2),s/2,s/2);` wären konsistente Leerzeichen wie im restlichen File besser lesbar.\n- In `Triangles.drawRec` werden viele Ausdrücke wie `(x1 + x0) / 2` mehrfach wiederholt; lege die Seitenmittelpunkte einmal in Variablen ab (verbessert Lesbarkeit und reduziert Fehlerquellen).\n\n\n# Exercise: knapsack\n\n### Correctness\n- \n\n### Suggestion\n- \n\n### Code Style\n- In `pack`, du führst das “Zurücknehmen” (unload) über `loadeditems` in einer zweiten Schleife aus. Das funktioniert, ist aber unnötig umständlich und fehleranfälliger als das Zurücknehmen direkt passend zur Stelle zu koppeln (z.B. klarer strukturierte Backtracking-Schritte).\n- In `loadItem`/`unloadItem` verwendest du Zuweisungen wie `currWeight = currWeight + ...`; das ist korrekt, aber `+=`/`-=` wäre lesbarer und üblicher.\n- Variablennamen sind gemischt (z.B. `loadeditems`): in Java ist `loadedItems` (camelCase) der Standard.\n\n\n# Exercise: queens\n\n### Correctness\n- `QueensSolver.solve()` ist nicht implementiert und liefert immer `false`, dadurch wird keine Lösung gesucht/gefunden.\n- `QueensSolver.count()` ist nicht implementiert und liefert immer `0`, dadurch wird die Anzahl Lösungen nicht gezählt.\n- In `Queens.main()` fehlt die geforderte Java-Startsignatur (`static void main(String[] args)`); so startet das Programm in Java nicht automatisch.\n\n### Suggestion\n- Für `solve()`: Überlege dir eine rekursive Backtracking-Funktion, die zeilenweise vorgeht: in einer Zeile jede Spalte testen, bei gültiger Position setzen, nächste Zeile versuchen, und bei Misserfolg wieder zurücksetzen.\n- Für `count()`: Nutze ein ähnliches Backtracking wie bei `solve()`, aber statt beim ersten Treffer abzubrechen, sammelst du alle Treffer (z.B. Summe der Rückgabewerte aus den rekursiven Aufrufen), und vergiss dabei das “Zurücksetzen” des Bretts nach jedem Versuch nicht.\n- Für `main()`: Prüfe, welche Methodensignatur Java als Einstiegspunkt erwartet und passe die Methode entsprechend an, damit dein Programm überhaupt läuft.\n\n### Code Style\n- Die `// TODO implement`-Marker sind ok während der Arbeit, aber sobald du fertig bist, sollten sie entfernt/ersetzt werden.\n- `getBoard()` gibt `this.board` zurück; `this` ist hier nicht nötig (kein Fehler, aber unnötig).\n\n\n# Exercise: sudoku\n\n### Correctness\n- `Sudoku.main` hat nicht die geforderte Java-Startsignatur (`public static void main(String[] args)`), dadurch startet die Applikation typischerweise nicht.\n- `SudokuSolverImpl.solved(...)` liefert aktuell immer `false`, auch wenn rekursiv eine Lösung gefunden wurde.\n- In `solved(...)` wird das Ergebnis des rekursiven Aufrufs bei einem gültigen gesetzten Wert ignoriert (du rufst zwar weiter, aber verwendest den Rückgabewert nicht), dadurch stoppt das Backtracking nicht beim Finden einer Lösung.\n- Beim Backtracking räumst du das Feld im falschen Moment auf: Du `clear`st direkt im `else`-Zweig von `checker.oneOK(...)`, aber nicht zwingend dann, wenn ein tieferer Rekursionszweig scheitert. Dadurch bleibt ggf. ein gesetzter Wert stehen, obwohl er in späteren Rekursionsschritten als Sackgasse erkannt wurde.\n- `nofSolutions(...)` ist noch nicht implementiert (gibt immer `0` zurück), erfüllt damit die Anforderung “Anzahl Lösungen zählen” nicht.\n\n### Suggestion\n- Für `main`: Schau dir an, welche Methodensignatur die JVM als Einstiegspunkt sucht (Stichworte: `public`, `static`, Parameter).\n- In `solved(...)`: Überlege dir, wann du `true` zurückgeben musst, damit die Rekursion “nach oben” abbricht, sobald eine vollständige Lösung erreicht ist.\n- Wenn du rekursiv weitergehst, brauchst du eine Möglichkeit, das Ergebnis des Rekursionsaufrufs zu übernehmen und ggf. sofort aus Schleife/Methode auszusteigen, sobald eine Lösung gefunden ist.\n- Beim Aufräumen (Backtracking): Denk daran, dass ein gesetzter Wert erst dann wieder entfernt werden soll, wenn **alle** Möglichkeiten darunter ausprobiert wurden und keine zum Ziel geführt hat (nicht nur wenn `oneOK` sofort fehlschlägt).\n- Für `nofSolutions(...)`: Das Grundgerüst ist sehr ähnlich zu `solved(...)`, aber statt “beim ersten Treffer stoppen” musst du Treffer zählen und zusätzlich das `max`-Limit berücksichtigen (z.B. indem du es bei rekursiven Aufrufen herunterzählst).\n\n### Code Style\n- In `solved(...)` ist die Struktur mit vielen verschachtelten `if/else` und einem finalen `return false` schwer nachvollziehbar; versuch die Rückgabepfade klarer zu machen (z.B. indem du an den Stellen returnst, wo du das Ergebnis kennst).\n- Die Variablennamen `i/j/k` sind ok für Schleifen, aber bei Backtracking hilft oft ein sprechenderer Name als `k` (z.B. “candidate”), damit man die Logik schneller lesen kann.\n",
"status" : "SUCCESS"
},
"unitTest" : {
"tests" : [ {
"name" : "allZero()",
"status" : "PASSED",
"message" : null
}, {
"name" : "uselessStuff()",
"status" : "PASSED",
"message" : null
}, {
"name" : "random1()",
"status" : "PASSED",
"message" : null
}, {
"name" : "random2()",
"status" : "PASSED",
"message" : null
}, {
"name" : "random3()",
"status" : "PASSED",
"message" : null
}, {
"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
} ]
}
}