AutoFeedback API

Result 8778135f-71b4-4ab9-be33-bd7e62beab70

{
  "llm" : {
    "feedback" : "# Exercise: fractal\n\n### Correctness\n- In `Boxes.drawRec` fehlt ein rekursiver Aufruf für das unten-links Teilquadrat; dadurch wird bei `n > 0` nur in drei Quadranten weiter unterteilt und die entstehende Form entspricht nicht der geforderten rekursiven Box-Struktur.\n- In `Boxes.drawRec` zeichnest du bei `n > 0` zusätzlich das große Quadrat (vor den rekursiven Aufrufen). Dadurch entstehen extra Linien, die in der rekursiven Ziel-Figur typischerweise nicht gezeichnet werden (es sollen die kleinsten Kästchen im Basisfall entstehen).\n- In `Triangles.drawRec` zeichnest du bei `n > 0` jedes Mal das aktuelle (große) Dreieck erneut. Das führt zu zusätzlichen Linien und entspricht nicht der üblichen rekursiven Dreiecks-Fraktal-Zeichnung, bei der im Basisfall gezeichnet wird.\n\n### Suggestion\n- Überlege bei den Boxen: Welche vier Teilquadrate gibt es nach dem Halbieren von `s` (oben-links, oben-rechts, unten-rechts, unten-links) und für welches davon fehlt dir noch der rekursive Schritt? Nutze dafür passende `x`/`y` Offsets mit `s/2`.\n- Prüfe bei den Boxen, ob du wirklich in jedem Rekursionsschritt das aktuelle Quadrat zeichnen musst, oder ob Zeichnen nur im Abbruchfall (`n == 0`) reicht, damit nicht “zu große” Umrandungen übrig bleiben.\n- Bei den Dreiecken: Entscheide dich für eine klare Basisfall-Strategie: Entweder zeichnest du nur bei `n == 0`, oder du musst sehr bewusst sein, dass du sonst auf allen Ebenen Kanten doppelt/überlappend einzeichnest. Teste visuell, wie sich das auf das Muster auswirkt.\n\n### Code Style\n- In `Triangles.drawRec` sind die Variablennamen (`xLinks`, `xRechts`, `xUnten`) zwar verständlich, aber du könntest sie konsistenter an der Geometrie ausrichten (z.B. “mid01”, “mid02”, “mid12”), damit klarer ist, welche Kante gemittelt wird.\n- Die vielen `Math.abs(...) / 2 + Math.min(...)`-Berechnungen sind funktional, aber unübersichtlich; bei Mittelpunkten reicht meist eine viel direktere Ausdrucksform, was die Lesbarkeit deutlich verbessert.\n\n\n# Exercise: knapsack\n\n### Correctness\n- Du berücksichtigst `maxN` nicht: In `pack(i)` wird ein Gegenstand effektiv nur 0 oder 1 Mal genommen, obwohl laut Aufgabe jeder Gegenstand bis zu `n`-mal gewählt werden darf.\n- Es fehlt eine Abbruch-/Prüflogik während des Rekursionsbaums, um Kombinationen zu vermeiden, die bereits das `maxWeight` überschreiten (du prüfst das Gewicht erst am Blatt `i == weights.length`), wodurch du auch “ungültige” Teilzustände weiter ausbaust.\n\n### Suggestion\n- Überlege dir, wie du an der Stelle, wo du aktuell genau einmal `loadItem(i)` machst, stattdessen alle Möglichkeiten von “0-mal bis `maxN`-mal” für Item `i` durchprobieren kannst, bevor du mit `pack(i+1)` weitergehst.\n- Wenn du ein Item mehrfach lädst, brauchst du beim Zurückgehen (Backtracking) auch das korrekte “Zurücksetzen” des Zustands: Stelle sicher, dass du genau so oft wieder entlädst, wie du geladen hast (oder in einem Schritt mit dem passenden Faktor).\n- Baue eine Gewichtsprüfung so ein, dass du gar nicht erst tiefer rekursiv weitergehst, wenn `currWeight > maxWeight` bereits überschritten ist.\n\n### Code Style\n- `KnapsackN.main()` hat nicht die übliche Java-Signatur (`main(String[] args)`); falls die Tests/Runner darauf angewiesen sind, kann das zu Problemen führen.\n\n\n# Exercise: sudoku\n\n### Correctness\n- `Sudoku.main` hat nicht die geforderte Signatur als Einstiegspunkt (muss `public static void main(String[] args)` sein), sonst startet die Applikation nicht.\n- `solved(...)` gibt unabhängig vom tatsächlichen Ergebnis immer `false` zurück, obwohl laut Interface `true` zurückkommen muss, wenn eine Lösung gefunden wurde.\n- `solved(...)` setzt beim Backtracking das Modell nicht zuverlässig in den Ausgangszustand zurück, wenn keine Lösung existiert (Requirement: bei `false` muss das Modell wieder initial sein).\n- In `solved(...)` sind die Koordinaten aus `fieldNr` vertauscht (`i/j`-Berechnung), dadurch wird nicht Feld für Feld in der richtigen Reihenfolge bearbeitet.\n- In `solved(...)` testest du Kandidatenwerte mit `while (number <= 10 ...)` und setzt dabei auch Werte außerhalb des erlaubten Bereichs (`1..size`), was die Modell-API verletzt.\n- In `solved(...)` prüfst du `checker.oneOK(model, i, j)` in der Schleifenbedingung, bevor ein sinnvoller Kandidat gesetzt/validiert wurde; dadurch hängt die Logik der Kandidatensuche nicht an “setze Wert -> prüfe -> recurse”.\n- In `solved(...)` wird bei `number == 10` rekursiv mit `fieldNr - 1` zurückgesprungen, ohne sicherzustellen, dass du ein tatsächlich veränderbares (nicht-vorgegebenes) Feld zurückgehst; das kann zu falschem Verhalten/Endlosschleifen führen.\n- `nofSolutions(...)` ist nicht implementiert und gibt immer `0` zurück; die Anforderung “Anzahl Lösungen zählen (bis MAX) und Modell am Ende zurücksetzen” ist damit nicht erfüllt.\n\n### Suggestion\n- Für `main`: Schau dir an, wie Java den Programmeinstieg findet (statisch, public, mit `String[] args`) und passe nur die Signatur an.\n- Für den Rückgabewert von `solved`: Lass den rekursiven Aufruf sein Ergebnis nach oben “durchreichen” und gib es am Ende auch wirklich zurück, statt immer `false`.\n- Für das Zurücksetzen des Modells: Überlege dir, an welchen Stellen du Felder selbst befüllst und wo du sie beim Scheitern wieder `clear(...)`en musst, damit am Ende (bei “keine Lösung”) genau der Startzustand wiederhergestellt ist.\n- Für die `i/j`-Berechnung: Nimm `fieldNr` und leite daraus Zeile und Spalte konsistent aus `model.size()` ab (eine Richtung ist “Division”, die andere “Modulo”).\n- Für den Wertebereich: Iteriere Kandidaten strikt von `1` bis `model.size()`; alles darüber darfst du nie an `model.set(...)` geben.\n- Für die Kandidatenlogik: Struktur: “wenn Feld leer: probiere Werte; setze; wenn gültig: rekursiv nächstes Feld; wenn nicht erfolgreich: nächster Wert; am Ende Feld leeren”. Achte darauf, dass `oneOK` immer nach dem Setzen des Kandidaten geprüft wird.\n- Für korrektes Backtracking: Statt einfach `fieldNr - 1` zu machen, ist es meist stabiler, die Rekursion so zu bauen, dass das Zurückgehen automatisch passiert, wenn ein rekursiver Aufruf `false` liefert (du kehrst dann in die Schleife zurück und probierst den nächsten Wert).\n- Für `nofSolutions`: Denk an dieselbe Rekursionsstruktur wie beim Lösen, aber statt beim ersten Fund zu stoppen addierst du Treffer auf; zusätzlich musst du abbrechen, sobald du `MAX` erreicht hast, und am Ende die von dir gesetzten Felder wieder leeren.\n\n### Code Style\n- Unbenutzter Import: `java.util.HashSet` wird nirgends verwendet.\n- Magic Numbers (`80`, `9`, `10`) machen den Code unnötig starr; verwende stattdessen `model.size()` bzw. `model.size()*model.size()` (und ggf. abgeleitete Konstanten), dann funktioniert es auch, falls die Modellgröße je geändert würde.\n- In `solved(...)` ist die Kontrolle des Flusses schwer nachvollziehbar, weil Rückgabewerte der rekursiven Calls ignoriert werden; auch wenn das primär Korrektheit betrifft, hilft es stylistisch sehr, das Ergebnis in einer Variable zu führen und konsequent zurückzugeben.\n\n\n# Exercise: queens\n\nLlm Evaluation ist für diese Aufgabe deaktiviert. Entferne die .llmignore Datei vom Package der Aufgabe.\n",
    "status" : "SUCCESS"
  },
  "unitTest" : {
    "tests" : [ {
      "name" : "allZero()",
      "status" : "PASSED",
      "message" : null
    }, {
      "name" : "uselessStuff()",
      "status" : "PASSED",
      "message" : null
    }, {
      "name" : "random1()",
      "status" : "FAILED",
      "message" : "expected: <190> but was: <174>"
    }, {
      "name" : "random2()",
      "status" : "FAILED",
      "message" : "expected: <340> but was: <279>"
    }, {
      "name" : "random3()",
      "status" : "FAILED",
      "message" : "expected: <558> but was: <357>"
    }, {
      "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
    } ]
  }
}