{
"llm" : {
"feedback" : "# Exercise: fractal\n\n### Correctness\n- In `Triangles.drawRec` zeichnest du im Basisfall (`n == 0`) die dritte Kante mit `g.drawLine(x0, y0, x2, y2)`. Damit wird zwar ein Dreieck geschlossen, aber die Kante ist nicht dieselbe wie in der Aufgaben-Vorgabe (“mehrere drawLine(...) um ein Dreieck zu zeichnen”): Es sollte die Kante zwischen Punkt 2 und Punkt 0 sein (also von `(x2,y2)` nach `(x0,y0)`), nicht erneut von `(x0,y0)` aus; je nach späterer Rekursion/Orientierung kann das zu falsch “verdrehten” Teil-Dreiecken führen.\n\n### Suggestion\n- Schau dir im Basisfall genau an, welche drei Kanten ein Dreieck mit den Punkten `(x0,y0)`, `(x1,y1)`, `(x2,y2)` hat: es sind die Verbindungen 0–1, 1–2 und 2–0. Vergleiche das mit deinen drei `drawLine`-Aufrufen und prüfe, ob du wirklich die Paare (0,1), (1,2), (2,0) verwendest.\n\n### Code Style\n- In `Triangles.drawRec` wiederholst du sehr oft Ausdrücke wie `(x1 + x0) / 2` usw. Lesbarer wird es, wenn du die Mittelpunkte einmal in gut benannten Variablen speicherst (so wie du es implizit schon machst, nur ohne Variablen).\n- In `Boxes.drawRec` sind die Kommentare “rechts/recht” etc. etwas inkonsistent (“recht unten” vs. “rechts oben”) – einheitliche Benennung hilft beim Nachvollziehen der Quadranten.\n\n\n# Exercise: knapsack\n\n### Correctness\n\n\n### Suggestion\n\n\n### Code Style\n- In `loadItem`/`unloadItem` kannst du Schreibweisen wie `currWeight += weights[i];` und `currValue -= values[i];` verwenden; das macht die Methoden kürzer und besser lesbar.\n- Die Variable `loadeditems` könnte nach Java-Konvention `loadedItems` heißen (camelCase).\n\n\n# Exercise: queens\n\n### Correctness\n- `QueensSolver.solve()` ist nicht implementiert und liefert immer `false`, damit wird keine 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 nie korrekt gezählt.\n\n### Suggestion\n- Für `solve()`: Überlege dir eine rekursive Backtracking-Funktion, die zeilenweise (row für row) versucht, eine Dame in einer erlaubten Spalte zu platzieren, und bei Misserfolg die Platzierung wieder rückgängig macht (Backtracking).\n- Für `count()`: Ähnlich wie bei `solve()`, aber statt beim ersten Fund aufzuhören, sollst du alle gültigen Platzierungen weiter durchsuchen und die Anzahl gefundener vollständiger Belegungen aufsummieren; wichtig ist auch hier, nach dem rekursiven Aufruf die Dame wieder zu entfernen.\n\n### Code Style\n- In `getBoard()` ist `return this.board;` unnötig mit `this` (kann man weglassen), ist aber Geschmackssache.\n- In `Queens.java` fehlt die übliche `static void main(String[] args)`-Signatur; falls das im Framework nicht speziell behandelt wird, startet das Programm so nicht direkt.\n\n\n# Exercise: sudoku\n\n### Correctness\n- In `Sudoku.java` ist `main()` nicht als `public static void main(String[] args)` deklariert; so startet die Applikation nicht über den üblichen Java-Entry-Point.\n- `solved(SudokuModel model)` erfüllt die Anforderung „false: no solution found, model was reset to its initial state“ nicht: Wenn keine Lösung existiert, bleiben durch das Backtracking evtl. Änderungen in bereits zuvor korrekt gesetzten Feldern bestehen (insbesondere wenn ein Feld „vordefiniert“ war und später tiefere Rekursion scheitert).\n- `nofSolutions(...)` zählt mit `max` nicht korrekt: du gibst in der Rekursion immer denselben `max`-Wert weiter, statt das verbleibende Budget zu berücksichtigen. Dadurch kann die Gesamtanzahl der gezählten Lösungen `MAX` überschreiten bzw. der Abbruch ist nicht global korrekt.\n\n### Suggestion\n- Für `main`: Überlege dir, welche Signatur die JVM als Startmethode erkennt (Stichworte: `public`, `static`, Parameter `String[]`).\n- Für das Reset-Verhalten bei `solved`: Wenn ein Pfad scheitert, muss beim Zurückgehen (Backtracking) sichergestellt werden, dass alle Änderungen an Feldern, die nicht ursprünglich vorgegeben waren, wieder entfernt werden – auch wenn das Scheitern erst „weiter hinten“ passiert. Prüfe, an welchen Stellen du aktuell nur das „aktuelle“ Feld clearst, aber frühere Entscheidungen bestehen bleiben könnten.\n- Für `nofSolutions` mit Limit: Denke bei jedem rekursiven Abstieg daran, wie viele Lösungen du in diesem Teilbaum noch „finden darfst“, wenn bereits `solutions` Lösungen gefunden wurden. Der Parameter `max` sollte sich pro rekursivem Aufruf entsprechend reduzieren, damit das Limit insgesamt eingehalten wird.\n\n### Code Style\n- Unused import: `import ch.fhnw.prog1.exercise.sudoku.framework.SudokuSample;` in `SudokuSolverImpl` wird nicht verwendet.\n- In `solved` hast du teils doppelte `model.clear(i, j)`-Logik (im `else`-Zweig und nach einem fehlgeschlagenen Rekursionsversuch); das lässt sich vereinfachen, um die Lesbarkeit zu verbessern.\n- In `nofSolutions` ist das manuelle Backup/Restore okay, aber recht viel Code; wenn du es beibehältst, könntest du das Kopieren/Zurückschreiben in kleine Hilfsmethoden auslagern, um die Kernlogik des Zählens besser sichtbar zu machen.\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
} ]
}
}