AutoFeedback API

Result 329b745b-384f-44ba-a8cb-2b33ca448080

{
  "llm" : {
    "feedback" : "# Exercise: fractal\n\n### Correctness\n- In `Triangles.drawRec` (Base-Case `n == 0`) zeichnest du die dritte Kante mit `g.drawLine(x0, y0, x2, y2)`; das verbindet zwar zwei Ecken, aber es ist nicht dieselbe Kante wie „von x2,y2 zurück zu x0,y0“ *plus* du zeichnest damit nicht explizit die Seite `x2 -> x0` im gleichen Muster wie die anderen beiden Seiten (in der Vorlage ist gemeint, dass alle drei Dreiecksseiten gezeichnet werden: `x0->x1`, `x1->x2`, `x2->x0`).\n- In `Triangles.drawRec` (Rekursionsfall) berechnest du beim zweiten rekursiven Aufruf einen Punkt `( (x1+x2)/2, y1 )`. Das ist nur dann wirklich der Mittelpunkt zwischen `(x1,y1)` und `(x2,y2)`, wenn `y1 == y2`. Bei den vorgegebenen Startpunkten stimmt das hier zwar zufällig (beide sind 790), aber allgemein ist das nicht korrekt und führt zu „verzogenen“ Dreiecken, sobald die Punkte nicht exakt horizontal liegen.\n\n### Suggestion\n- Für das Basis-Dreieck: Stell sicher, dass du wirklich die drei Kanten als geschlossene Kette zeichnest (Endpunkt der letzten Linie ist wieder der Startpunkt der ersten).\n- Für die Rekursion bei Triangles: Berechne die Mittelpunkte immer komponentenweise zwischen den jeweiligen Eckpunkten (also sowohl x- als auch y-Koordinate als Mittelwert der zugehörigen beiden Punkte), und verwende diese drei Mittelpunkte dann konsistent, um die 3 Teil-Dreiecke zu definieren.\n\n### Code Style\n- In `Triangles.drawRec` ist die Geometrie schwer lesbar, weil du die Mittelpunkt-Berechnungen mehrfach inline wiederholst. Lesbarer wäre es, die drei Mittelpunkte einmal in Variablen zu speichern und dann in den drei rekursiven Aufrufen zu verwenden.\n- In `Boxes.drawRec` sind die Kommentare hilfreich, aber die Aufruf-Reihenfolge ist etwas durcheinander (erst rechts oben, dann rechts unten, dann links oben). Einheitliche Reihenfolge (z.B. im Uhrzeigersinn) macht das einfacher zu prüfen und zu warten.\n\n\n# Exercise: knapsack\n\n### Correctness\n-  \n\n### Suggestion\n-  \n\n### Code Style\n- In `pack`, duplikierst du Logik mit `loadeditems` und zwei Schleifen (laden + mehrfach entladen). Das funktioniert, ist aber schwerer zu lesen als ein klarer “laden in einer Schleife, danach einmal gesammelt zurücksetzen”-Ansatz.\n- Benennung: `loadeditems` sollte in Java üblicherweise `loadedItems` heißen (CamelCase).\n- In `loadItem`/`unloadItem` kannst du kürzer schreiben (`+=` / `-=`), das verbessert Lesbarkeit.\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 auch kein Brett befüllt.\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 vorgeht: In jeder Zeile ausprobierst du alle Spalten, platzierst testweise eine Dame (wenn `checkPlacement` ok ist), gehst zur nächsten Zeile weiter und machst bei Misserfolg die Platzierung wieder rückgängig.\n- Für `count()`: Ähnlich wie `solve()`, aber statt beim ersten Fund abzubrechen, summierst du alle gültigen vollständigen Platzierungen. Achte darauf, dass du nach jedem rekursiven Versuch das Feld wieder zurücksetzt (Backtracking), sonst „verschmutzt“ das Board für weitere Versuche.\n\n### Code Style\n- In `Queens.java` ist `main()` nicht als Java-Startpunkt deklariert (`static void main(String[] args)` fehlt). Das ist nicht Teil der Solver-Aufgabe, aber so lässt sich das Programm typischerweise nicht direkt starten.\n\n\n# Exercise: sudoku\n\n### Correctness\n- `Sudoku.main` hat nicht die korrekte Signatur (`public static void main(String[] args)`), dadurch startet die Applikation so nicht wie erwartet.\n- In `SudokuSolverImpl.solved`: Die Abbruchbedingung `if (fieldNr > model.size()* model.size())` ist falsch (Off-by-one), dadurch wird der “alle Felder verarbeitet”-Fall nicht korrekt getroffen.\n- In `SudokuSolverImpl.solved`: Das Ergebnis des rekursiven Aufrufs wird ignoriert; du brichst nicht ab, wenn eine Lösung gefunden wurde, und gibst am Ende immer `false` zurück. Damit meldet die Methode nie “gelöst”.\n- In `SudokuSolverImpl.solved`: Bei gültigen Kandidaten räumst du das Feld nicht zuverlässig wieder auf, wenn der rekursive Pfad später scheitert (Backtracking unvollständig/inkonsistent).\n- `SudokuSolverImpl.nofSolutions` ist nicht implementiert und liefert immer `0`, erfüllt damit die Anforderung “Anzahl Lösungen zählen” nicht (inkl. Begrenzung durch `MAX` und Reset auf Initialzustand).\n\n### Suggestion\n- Schau dir bei der Rekursion an, wann genau “fertig” ist: Das ist typischerweise dann, wenn `fieldNr` genau die Anzahl Felder erreicht, nicht “größer als”.\n- Wenn du rekursiv weitergehst, musst du das Ergebnis nutzen: Sobald ein rekursiver Aufruf `true` liefert, solltest du diesen Erfolg nach oben propagieren und die Suche beenden.\n- Überlege dir eine klare Backtracking-Regel: “Setze Wert → prüfe → rekursiv versuchen → wenn nicht erfolgreich, Feld wieder leeren”. Achte darauf, dass das Leeren nicht nur beim lokalen `oneOK`-Fehlschlag passiert, sondern auch wenn tiefer in der Rekursion keine Lösung gefunden wurde.\n- Für `nofSolutions`: Denk an denselben Suchbaum wie bei `solved`, aber statt eines `boolean` sammelst du die Anzahl Treffer. Wichtig ist dabei, dass du die Zählung begrenzt (wenn `n` schon `max` erreicht hat, abbrechen) und beim Zurückkehren das Feld wieder leerst.\n- Beim Zählen solltest du das verbleibende “Budget” weiterreichen (z.B. `max - n`), damit du wirklich bei `MAX` kappen kannst, ohne unnötig weiter zu suchen.\n\n### Code Style\n- In `solved` wäre konsistenteres Klammer-Layout hilfreich (z.B. `} else { ... }` statt `} else model.clear(...)`), das reduziert Logikfehler bei Backtracking.\n- `if (checker.oneOK(...)) { solved(...); }` ohne Nutzung des Rückgabewerts ist ein typischer “Bug-Magnet” – auch stilistisch besser immer in einer Variablen speichern oder direkt zurückgeben.\n- In `Sudoku.java` fehlt `public static` bei `main`; das ist nicht nur korrektheitsrelevant, sondern auch ein Standard-Konventionspunkt für Java-Programme.\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
    } ]
  }
}