AutoFeedback API

Result 1552f209-3c68-42ff-9193-28c394aaafc3

{
  "llm" : {
    "feedback" : "# Exercise: fractal\n\n### Correctness\n- In `Triangles.drawRec` ist das untere mittlere Dreieck nicht korrekt berechnet: Du setzt beim zweiten und dritten rekursiven Aufruf jeweils den y-Wert eines Mittelpunkts einfach auf `y1`. Der Mittelpunkt zwischen `(x1,y1)` und `(x2,y2)` (bzw. zwischen anderen Punkten) braucht aber sowohl x *und* y als Durchschnitt der beiden Eckpunkte.\n- In `Triangles.drawRec` (Basisfall) zeichnest du die dritte Kante als `(x0,y0) -> (x2,y2)`. Das ist zwar eine Dreieckskante, aber achte darauf, dass du wirklich alle drei Kanten zwischen den drei Punkten zeichnest (also die Kanten sollten konsistent genau zwischen den drei Eckpunkten liegen).\n\n### Suggestion\n- Berechne für die Rekursion zuerst die drei Seiten-Mittelpunkte explizit (jeweils `((xa+xb)/2, (ya+yb)/2)`), speichere sie in Variablen und verwende diese dann in den drei rekursiven Aufrufen. Dann vermeidest du auch, dass du aus Versehen einen y-Wert „hart“ von einem Eckpunkt übernimmst.\n- Kontrolliere gedanklich/gezeichnet, welche drei kleineren Dreiecke bei einem Schritt entstehen sollen: jedes hat als Eckpunkte immer Kombinationen aus einem Original-Eckpunkt und zwei passenden Mittelpunkten. Wenn ein Punkt wie `( (x1+x2)/2, y1 )` vorkommt, ist das ein Hinweis, dass ein Mittelpunkt falsch berechnet wurde.\n\n### Code Style\n- In `Triangles.drawRec` rechnest du dieselben Mittelpunkte mehrfach direkt im Methodenaufruf aus. Lesbarer und weniger fehleranfällig ist es, diese einmal in Variablen zu speichern und dann zu verwenden.\n- Kommentar-Sprache/Format in `Boxes` ist ok, aber achte auf einheitliche Abstände (z.B. `g.drawRect(x, y + (s / 2), s / 2, s / 2);`) für bessere Lesbarkeit.\n\n\n# Exercise: knapsack\n\n### Correctness\n- In `pack(int i)` rufst du innerhalb der `for (j < maxN)`-Schleife zuerst `pack(i + 1)` auf und lädst das Item erst danach (`loadItem(i)`). Dadurch wird für die Fälle “1x, 2x, …, maxN mal mitnehmen” die Rekursion nicht mit dem entsprechend erhöhten Gewicht/Wert ausgeführt, sondern immer mit dem alten Zustand.\n- Durch die aktuelle Reihenfolge wird der Fall “maxN-mal mitnehmen” gar nicht in Kombination mit den folgenden Items geprüft (nach dem letzten `loadItem` kommt kein `pack(i+1)` mehr), d.h. es fehlt mindestens die Variante, bei der du das Item genau `maxN` mal nimmst und danach weiterpackst.\n\n### Suggestion\n- Überlege dir für ein Item `i`: Welche Zustände willst du an `pack(i+1)` übergeben? (0-mal, 1-mal, 2-mal, …, maxN-mal). Stelle sicher, dass vor jedem rekursiven Aufruf der Zustand (`currWeight/currValue`) genau zu diesem “n-mal genommen”-Fall passt.\n- Prüfe speziell den Ablauf für `n = maxN`: Gibt es in deinem Code einen rekursiven Aufruf, der *nachdem* du das Item `maxN`-mal geladen hast, noch `pack(i+1)` ausführt? Wenn nicht, fehlt dieser Fall.\n- Ein einfacher mentaler Test: Setze `maxN = 1`. Dann sollte dein Code auf das normale 0/1-Knapsack hinauslaufen. Verfolge, ob der “1x genommen”-Fall tatsächlich vor dem rekursiven Weitergehen entsteht.\n\n### Code Style\n- Der `Logger log` wird nirgends verwendet; entweder Logging einbauen oder die Imports/Felder entfernen, damit der Code schlank bleibt.\n- In `loadItem/unloadItem` kannst du die Kurzschreibweise (`+=`, `-=`) verwenden, das macht es lesbarer.\n\n\n# Exercise: queens\n\n### Correctness\n- `QueensSolver.solve()` ist nicht implementiert und liefert immer `false`, damit wird nie eine Lösung gefunden/platziert.\n- `QueensSolver.count()` ist nicht implementiert und liefert immer `0`, damit wird die Anzahl Lösungen nicht gezählt.\n- In `Queens.main()` fehlt die korrekte Java-`main`-Signatur (`static void main(String[] args)`), so startet das Programm typischerweise nicht über den normalen Java-Startpunkt.\n\n### Suggestion\n- Für `solve()`: Überlege dir eine rekursive Backtracking-Funktion, die zeilenweise arbeitet: in einer Zeile eine Spalte testen, Dame setzen, nächste Zeile versuchen, und bei Misserfolg die Dame wieder entfernen (Backtrack).\n- Für `count()`: Nutze eine sehr ähnliche Rekursion wie bei `solve()`, aber statt beim ersten Fund abzubrechen, summierst du alle vollständigen Platzierungen (Basisfall: alle Zeilen belegt → +1).\n- Für `main()`: Schau dir an, wie eine Java-Applikation üblicherweise gestartet wird und passe die Methodensignatur entsprechend an (Stichworte: `static`, `String[] args`).\n\n### Code Style\n- In `getBoard()` ist `return this.board;` zwar ok, aber in der Vorlage/üblichen Konvention wird oft einfach `return board;` verwendet (einheitlicher Stil).\n- Die TODO-Kommentare sind noch vorhanden; sobald implementiert, entfernen oder durch aussagekräftige Kommentare ersetzen.\n\n\n# Exercise: sudoku\n\n### Correctness\n- In `SudokuSolverImpl`, `solved(model, int)` is not implemented and always returns `false`, so the Sudoku will never be solved.\n- In `SudokuSolverImpl`, `nofSolutions(model, int, int)` is not implemented and always returns `0`, so the number of solutions is always reported as 0.\n- In `Sudoku.java`, the `main` method signature is wrong (`void main()` instead of a proper Java entry point), so the application won’t start when run normally.\n\n### Suggestion\n- For `solved(...)`: think in terms of backtracking with a field index (`fieldNr`) from 0 to `size*size - 1`: if a field is pre-filled, skip to the next; otherwise try values `1..size`, check validity with `checker.oneOK(...)`, and recurse; if none work, undo the assignment (clear the field) before returning.\n- For `nofSolutions(...)`: use almost the same recursion as in `solved`, but instead of stopping at the first valid completion, count how many completions you can generate; when you reach the end, that contributes `1` solution. Also use the `max` parameter to stop exploring once you already found enough solutions.\n- For `Sudoku.java`: adjust the method signature to the standard Java entry point so the JVM can call it (also make it `public` and `static`, and accept the `String[]` argument).\n\n### Code Style\n- Remove the `// TODO implement` comments once the methods are implemented (or replace them with meaningful comments about the recursion/base case), otherwise it looks like unfinished code.\n",
    "status" : "SUCCESS"
  },
  "unitTest" : {
    "tests" : [ {
      "name" : "allZero()",
      "status" : "FAILED",
      "message" : "Error occurred in server thread; nested exception is: \n\tjava.lang.NoClassDefFoundError: org/slf4j/LoggerFactory"
    }, {
      "name" : "uselessStuff()",
      "status" : "FAILED",
      "message" : "Error occurred in server thread; nested exception is: \n\tjava.lang.NoClassDefFoundError: org/slf4j/LoggerFactory"
    }, {
      "name" : "random1()",
      "status" : "FAILED",
      "message" : "Error occurred in server thread; nested exception is: \n\tjava.lang.NoClassDefFoundError: org/slf4j/LoggerFactory"
    }, {
      "name" : "random2()",
      "status" : "FAILED",
      "message" : "Error occurred in server thread; nested exception is: \n\tjava.lang.NoClassDefFoundError: org/slf4j/LoggerFactory"
    }, {
      "name" : "random3()",
      "status" : "FAILED",
      "message" : "Error occurred in server thread; nested exception is: \n\tjava.lang.NoClassDefFoundError: org/slf4j/LoggerFactory"
    }, {
      "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
    } ]
  }
}