AutoFeedback API

Result 64e78f23-aef9-486d-9fa1-92c1723fc8c6

{
  "llm" : {
    "feedback" : "# Exercise: fractal\n\n### Correctness\n- In `Triangles.drawRec` (rekursiver Fall) berechnest du für das mittlere Punktpaar zwischen `(x1,y1)` und `(x2,y2)` nur `x`, aber setzt `y` fix auf `y1`. Das ist nur dann korrekt, wenn die Kante wirklich horizontal ist (bei anderen Dreiecken wäre das falsch) und passt nicht zum allgemeinen Ansatz „Mittelpunkte aller Seiten“.\n- In `Triangles.drawRec` (Basisfall) zeichnest du die dritte Kante als `(x0,y0) -> (x2,y2)`. Das ist zwar eine Dreieckskante, aber du nutzt nicht dieselbe Reihenfolge wie bei den anderen beiden Linien (bei dir ist es „0-1, 1-2, 0-2“ statt „0-1, 1-2, 2-0“). Das ist funktional meist egal, aber falls die Aufgabe strikt „den Rand entlang“ erwartet, kann das als Abweichung gesehen werden.\n\n### Suggestion\n- Für den rekursiven Schritt bei den Dreiecken: Berechne die drei Mittelpunkte wirklich jeweils als Mittelwert der beiden Endpunkte der Kante – also sowohl für `x` als auch für `y`. Dann baust du die 3 Kind-Dreiecke aus den Original-Ecken und den passenden Mittelpunkten zusammen.\n- Für den Basisfall: Zeichne die drei Kanten so, dass jede Ecke genau zweimal vorkommt (Start/Ende) und du einmal „rundherum“ gehst. Das hilft dir auch beim Debuggen, ob du die richtigen Eckpunkte weitergibst.\n\n### Code Style\n- In `Boxes.drawRec` wäre es lesbarer, wenn du die vier Teilquadrate (oder zumindest `half = s/2`) einmal in Variablen packst, statt `s / 2` überall zu wiederholen.\n- In `Triangles.drawRec` (rekursiver Fall) sind die Midpoint-Berechnungen mehrfach inline wiederholt; das macht es schwer zu prüfen, ob du überall die richtigen Koordinaten verwendest. Benenne die Mittelpunkte (z.B. `m01`, `m12`, `m20`) als Variablen, dann sieht man die Geometrie sofort.\n\n\n# Exercise: knapsack\n\n### Correctness\n- \n\n### Suggestion\n- \n\n3. Code Style:\n- In `pack`, du verwendest `loadeditems` nur, um danach wieder zu entladen. Das ist okay, aber du könntest das Entladen konzeptionell näher an den Stellen halten, wo du geladen hast (Backtracking-Pattern), damit der Zustand weniger “über mehrere Schleifen verteilt” ist.\n- In `loadItem`/`unloadItem` könntest du die verkürzte Schreibweise (`+=`, `-=`) nutzen, um es kompakter und leichter lesbar zu machen.\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 der Lösungen nicht gezählt.\n- In `Queens.java` ist die `main`-Methode nicht als Einstiegspunkt verwendbar (Signatur stimmt nicht), d.h. das Programm startet so typischerweise nicht.\n\n### Suggestion\n- Für `solve()`: Du brauchst eine Backtracking-Rekursion, die zeilenweise (oder spaltenweise) eine Dame setzt, bei einem Konflikt zurücksetzt und dann die nächste Position probiert. Überlege dir eine Abbruchbedingung: Wann ist das Board vollständig gelöst?\n- Für `count()`: Nutze eine sehr ähnliche Rekursion wie bei `solve()`, aber statt beim ersten Fund aufzuhören, addierst du für jede gültige Platzierung die Anzahl der Lösungen der restlichen Zeilen. Wichtig: Nach dem rekursiven Aufruf die gesetzte Dame wieder entfernen (Backtracking).\n- Für `main`: Schau dir an, welche `main`-Signatur Java erwartet (statisch, mit `String[] args`), und passe sie entsprechend an.\n\n### Code Style\n- `getBoard()` gibt `this.board` zurück; das `this` ist hier nicht nötig (nicht falsch, aber inkonsistent mit dem Rest).\n- In `QueensSolver` sind die TODO-Kommentare ok, aber solange sie nicht implementiert sind, wirkt die Klasse unvollständig—entferne sie, sobald du fertig bist.\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 typischerweise nicht.\n- `SudokuSolverImpl.solved(...)` hat keine Verankerung/Abbruchbedingung für `fieldNr` (z.B. wenn alle Felder abgearbeitet sind); so läuft die Rekursion über das letzte Feld hinaus.\n- `solved(...)` berücksichtigt nicht, dass manche Felder schon vorgegeben sind (`model.get(i,j) != 0`) und darf diese nicht überschreiben.\n- `solved(...)` liefert immer `false`, selbst wenn eine Lösung gefunden würde; außerdem wird das Ergebnis des rekursiven Aufrufs nicht ausgewertet/weitergegeben.\n- `solved(...)` räumt nach einem Fehlschlag nicht korrekt auf (Backtracking): wenn kein Wert passt, muss das Feld wieder geleert werden (und nur dann).\n- In `solved(...)` verwendest du für Kandidatenwerte fix `1..9` statt `1..model.size()`.\n- `solved(...)` prüft mit `checker.allOK(model)` das ganze Sudoku nach jedem Setzen; für Backtracking ist gefordert/üblich, nur die lokale Konsistenz des neu gesetzten Feldes zu prüfen (sonst unnötig teuer).\n- `nofSolutions(...)` ist nicht implementiert, obwohl in der Aufgabe verlangt.\n\n### Suggestion\n- Schau dir als erstes die “Verankerung” (Basisfall) der Rekursion an: Was bedeutet es konkret, wenn `fieldNr` das letzte Feld überschritten hat, und welchen Rückgabewert erwartest du dann?\n- Rechne aus `fieldNr` wie bisher `i` und `j` aus, aber überlege dir eine Bedingung, wann du direkt zum nächsten Feld weitergehst (Hinweis: wenn das aktuelle Feld schon belegt ist).\n- Baue die Kandidatensuche so, dass du nach dem Setzen eines Wertes nur prüfst, ob **dieser** Schritt gültig ist (Tipp: dafür gibt es im Checker eine passendere Methode als `allOK`).\n- Wenn der rekursive Aufruf “Erfolg” meldet, solltest du diesen Erfolg sofort zurückgeben und nicht weiter Werte ausprobieren.\n- Wenn kein Kandidat funktioniert, muss das Feld wieder in den Ursprungszustand (leer) zurückversetzt werden, bevor du “kein Erfolg” zurückmeldest.\n- Für `nofSolutions`: übernimm die gleiche Traversierungslogik wie beim Lösen, aber statt “beim ersten Fund stoppen” addierst du Treffer; denk auch daran, wie du das `max`-Limit in die Rekursion “mitnimmst”, damit du früh abbrechen kannst.\n- Für die Startmethode: passe die `main`-Signatur an, damit du das Programm überhaupt testen kannst.\n\n### Code Style\n- Verwende konsequent `model.size()` statt magischer Zahl `9`, damit dein Solver auch für andere Sudoku-Größen korrekt skaliert.\n- In `solved(...)` wäre eine klarere Struktur (Basisfall → Feldkoordinaten → Fall “vorgegeben”/“leer”) leichter zu lesen und zu debuggen als die aktuelle Schleife ohne Rückgabewert-Nutzung.\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
    } ]
  }
}