{
"llm" : {
"feedback" : "# Exercise: fractal\n\n### Correctness\n- In `Boxes.drawRec` zeichnest du bei jedem Rekursionsschritt immer zuerst ein Rechteck und gehst dann weiter, bis `n < 0`; dadurch werden auch für `n == 0` noch weitere Rekursionsaufrufe gemacht (mit `n - 1`), was nicht zur üblichen Abbruchbedingung „bei n == 0 nur zeichnen, sonst rekursiv weiter“ passt und die gewünschte Form/Iteration verfälscht.\n- In `Boxes.drawRec` fehlt der vierte Teil (unten links): du machst nur 3 rekursive Aufrufe (oben links, oben rechts, unten rechts), aber unten links wird bei dir nie gezeichnet/rekursiv bearbeitet.\n- In `Triangles.drawRec` zeichnest du das Dreieck in jedem Rekursionsschritt und nicht nur im Basisfall; dadurch wird bei größeren `n` nicht nur das „Fraktal aus kleinen Dreiecken“ gezeichnet, sondern zusätzlich immer wieder das große/alle Zwischen-Dreiecke, was das Ergebnis deutlich verändert.\n- In `Triangles.drawRec` verwendest du `n < 0` als Abbruch; damit wird bei `n == 0` trotzdem noch rekursiv weiter aufgerufen (bis `-1`), was wiederum nicht der beabsichtigten Rekursionstiefe entspricht.\n\n### Suggestion\n- Überlege dir eine klare Basisfall-Regel: „Wann soll nur noch gezeichnet werden, ohne weitere Unteraufrufe?“ Teste das gezielt mit `n = 0` und `n = 1`, ob genau eine Ebene entsteht.\n- Bei den Boxen: skizziere die 4 Quadranten (oben links, oben rechts, unten links, unten rechts) und kontrolliere, ob du wirklich alle vier mit passenden `(x,y)`-Offsets abdeckst.\n- Bei den Dreiecken: prüfe, ob du wirklich nur dann Linien zeichnest, wenn du „ein finales kleines Dreieck“ erreicht hast, und ob du in der Rekursion nur die 3 Eckdreiecke weiterverfolgst (nicht das mittlere).\n- Setze dir beim Debuggen z.B. `n = 1` und vergleiche: Erwartest du 1 großes Dreieck oder 3 kleine? Danach `n = 2`: sollten es 9 kleine werden (ohne zusätzliche „Zwischenlinien“).\n\n### Code Style\n- In beiden Klassen nutzt du `if (n < 0) return;` als Stop-Kriterium; lesbarer und üblicher ist ein klarer Basisfall (z.B. „wenn n == 0 … else …“), weil dadurch auch sofort klar wird, wann gezeichnet wird und wann rekursiert wird.\n- In `Boxes.drawRec` überschreibst du den Parameter `s` direkt (`s = s / 2;`); ein eigener neuer Variablenname für die Kind-Größe macht die Rekursion leichter nachvollziehbar.\n- Der auskommentierte `drawRec(...)`-Aufruf in `Triangles` wirkt wie ein liegengebliebener Versuch; entweder entfernen oder gezielt als Erklärungskommentar formulieren.\n\n\n# Exercise: knapsack\n\n### Correctness\n- In `pack(i)` berücksichtigst du den Fall „Gegenstand i gar nicht nehmen“ nicht korrekt: Du rufst `pack(i + 1)` nur innerhalb der `for (j < maxN)`-Schleife auf, wodurch der „0-mal nehmen“-Zweig nicht als eigener, sauberer Fall existiert, sondern mehrfach (redundant) ausgeführt wird.\n- Durch die aktuelle Reihenfolge `pack(i+1)` und danach `loadItem(i)` erzeugst du zwar Zustände für 0..(maxN-1) Kopien, aber nicht für genau `maxN` Kopien (der Zustand mit `maxN` geladenen Items wird nie mit `pack(i+1)` weiterverarbeitet).\n- Deine „Aufräumlogik“ am Ende (`unloadItem` in einer zweiten Schleife) hängt davon ab, dass zuvor auch wirklich genau `maxN`-mal geladen wurde. Das ist bei deiner Schleifenstruktur nicht garantiert „symmetrisch“ zu den rekursiven Aufrufen und macht den Zustand schwer nachvollziehbar; hier kann es passieren, dass du am Ende nicht auf den exakt gleichen Zustand zurückkommst, von dem du gestartet bist (je nachdem, wie viele `loadItem`-Aufrufe tatsächlich passiert sind, bevor die Rekursion zurückkommt).\n\n### Suggestion\n- Überlege dir die Entscheidungsstruktur pro Item als klare Fälle: erst „0-mal nehmen“ genau einmal ausprobieren, dann „1-mal“, „2-mal“, … bis „maxN-mal“, und nach jedem Laden direkt den rekursiven Schritt ausführen.\n- Prüfe gezielt, ob dein Code wirklich den Zustand „genau maxN Kopien von Item i im Rucksack“ jemals an `pack(i+1)` weitergibt (ein einfacher Debug-Print für `i`, `currWeight`, `currValue` hilft).\n- Achte darauf, dass das „Rückgängig machen“ (unload) exakt die Anzahl Ladevorgänge rückgängig macht, die du in diesem `pack(i)`-Frame durchgeführt hast. Eine gute Kontrolle ist: Am Ende von `pack(i)` sollten `currWeight`/`currValue` wieder exakt so sein wie beim Eintritt in die Methode.\n\n### Code Style\n- Kommentare wie `// TODO implement` stehen noch drin, obwohl du implementiert hast; räume diese auf, damit klar ist, was fertig ist.\n- Die zwei `for`-Schleifen (eine zum Laden/rekursiv gehen, eine zum Entladen) machen die Logik unnötig schwer zu lesen; versuche die Zustandsänderung und den rekursiven Aufruf enger zusammenzuhalten, dann wird auch das „Backtracking“ klarer.\n\n\n# Exercise: sudoku\n\n### Correctness\n- In `Sudoku.java` ist `main()` nicht als `public static void main(String[] args)` deklariert; so kann die Applikation nicht wie erwartet gestartet werden.\n- `nofSolutions`: Du ignorierst beim rekursiven Aufruf den Parameter `max` als “Restbudget” (du gibst immer wieder `max` unverändert weiter). Damit ist die Begrenzung auf `MAX` nicht korrekt umgesetzt und es können (je nach Sudoku) deutlich mehr als `MAX` Lösungen gezählt/erzeugt werden, bevor abgebrochen wird.\n\n### Suggestion\n- Schau dir die Signatur an, die Java für den Programmeinstieg erwartet, und vergleiche das mit deiner `main`-Methode.\n- Überlege bei `nofSolutions`, was `max` in jeder Rekursionsebene bedeuten soll: nicht “das globale MAX”, sondern “wie viele Lösungen darf ich ab hier noch finden, bevor ich abbreche”. Wenn du bereits `zähler` Lösungen gefunden hast, sollte der nächste rekursive Aufruf nur noch das verbleibende Kontingent bekommen.\n\n### Code Style\n- Benutze konsistente Sprache und Bezeichner (z.B. nicht gemischt `row/col` und dann `zähler`), das macht das Debugging von Rekursion/Backtracking deutlich einfacher.\n- Vermeide Tippfehler in Kommentaren/Bezeichnern (“Cheken”, “Umrechunng”, “filedNr”), weil das Lesen/Reviewen sonst unnötig schwer wird.\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" : "PASSED",
"message" : null
}, {
"name" : "random2()",
"status" : "FAILED",
"message" : "expected: <340> but was: <334>"
}, {
"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
} ]
}
}