{
"llm" : {
"feedback" : "# Exercise: fractal\n\n### Correctness\n- **Boxes:** Dein Abbruchfall ist `n == 1` und du zeichnest in diesem Fall gar kein Rechteck; dadurch wird für gewisse `n` (z.B. `n=0` oder `n=1`) nichts bzw. nicht wie gefordert gezeichnet.\n- **Boxes:** In der Rekursion rufst du `drawRec(g, x, y, s, n-1)` erneut mit **derselben** Größe `s` und denselben Koordinaten auf. Dadurch verkleinerst du in diesem Ast nie und die Rekursion läuft (für `n>1`) nicht auf ein sinnvolles Basisbild hinaus.\n- **Triangles:** Auch hier ist der Abbruchfall `n == 1` und im Abbruchfall wird **kein** Dreieck gezeichnet; für `n=0/1` fehlt damit die Basiszeichnung.\n- **Triangles:** Du zeichnest die Dreieckslinien in *jedem* Rekursionsschritt vor den rekursiven Aufrufen. Üblicherweise soll im Nicht-Basisfall nur weiter unterteilt werden und erst im Basisfall gezeichnet werden, sonst bekommst du nicht die intendierte Fraktal-Struktur (und sehr viele “überlagerte” Linien).\n- **Circles:** Die Aufgabe verlangt nur `Boxes` und `Triangles`. Deine `Circles`-Implementierung ist optional (Challenge), aber derzeit ist sie rekursiv/geom. nicht konsistent (z.B. `cos(90)`/`sin(90)` sind in Java in Radiant, nicht Grad), und der Abbruchfall verhindert ebenfalls eine Basiszeichnung.\n\n### Suggestion\n- **Boxes:** Überlege dir einen Basisfall, der wirklich *zeichnet* (z.B. bei kleinster Tiefe) und einen Rekursionsfall, der in **kleinere** Teilquadrate übergeht. Prüfe dabei: Wird `s` in allen rekursiven Aufrufen kleiner?\n- **Boxes:** Kontrolliere jeden rekursiven Call: Wenn du vier Teilquadrate zeichnen willst, sollten die Aufrufe alle mit `s/2` arbeiten und die passenden `(x,y)`-Offsets nutzen; ein Aufruf mit unverändertem `s` ist ein Warnsignal.\n- **Triangles:** Entscheide dich klar: Entweder zeichnest du nur im Basisfall (`n==0`) und unterteilst sonst nur, oder du bekommst schnell “zu viele” Linien. Teste mit kleinem `n` (0,1,2), ob das Bild dem erwarteten Sierpinski-Dreieck ähnelt.\n- **Triangles:** Prüfe, ob deine rekursiven Dreiecke wirklich die drei “Eck”-Dreiecke sind (oben, unten links, unten rechts). Ein guter Check: Nutze die drei Seitenmittelpunkte und stelle sicher, dass jedes Kinddreieck aus einem Eckpunkt + zwei passenden Mittelpunkten besteht.\n- **Circles (falls du sie behalten willst):** Wenn du Winkel verwendest, nutze `Math.toRadians(...)` oder arbeite gleich in Radiant. Und achte darauf, dass du bei der Positionierung die Offsets relativ zum aktuellen Kreiszentrum (`x,y`) berechnest, nicht über gemischte Hilfsvariablen wie `newr/newry`, die eigentlich keine Zentren sind.\n\n### Code Style\n- - `Point.java` wird nirgends verwendet; das verwirrt beim Lesen und kann weg, solange du es nicht brauchst.\n- - Viele auskommentierte Zeilen (gerade in `Boxes` und `Circles`) machen es schwer, die eigentliche Lösung zu erkennen; lieber löschen oder in kleine, klare Tests/Varianten auslagern.\n- - In `Circles` mischst du `int`-Casts in Geometrie mit `double`-Werten; selbst wenn es funktioniert, wird es ungenauer und schwerer nachvollziehbar.\n\n\n# Exercise: knapsack\n\n### Correctness\n- Du aktualisierst `maxValue` auch dann, wenn `i < weights.length` (also bevor alle Entscheidungen für alle Gegenstände getroffen wurden); damit werden Zwischenstände als “Lösung” gewertet, obwohl noch weitere Items folgen könnten.\n- In deiner Schleife `for (int j = 0; j <= maxN; j++)` erzeugst du Zustände, in denen du die Variante „0 Stück“ doppelt durchläufst: einmal durch `pack(i+1)` vor der Schleife und einmal mit `j = 0` in der Schleife.\n\n### Suggestion\n- Überlege dir, wann ein Zustand wirklich eine vollständige Kandidatenlösung ist: typischerweise erst dann, wenn du bei `i == weights.length` angekommen bist (Basisfall). Setze `maxValue` nur in diesem Basisfall (und nur wenn das Gewicht passt).\n- Entscheide dich für genau einen Ort, an dem du die „0 Stück von Item i“-Variante behandelst: entweder separat vor der Schleife oder als Schleifeniteration. Passe dann die Schleifen-Grenzen entsprechend an, damit keine Doppelzählung entsteht.\n\n### Code Style\n- Entferne die `// TODO implement`-Kommentare, sobald du die Methoden implementiert hast, sonst wirkt es wie unvollständig.\n- Die Methodennamen `loadItem/unloadItem` sind ok, aber der zusätzliche Parameter `j` macht die Verantwortung etwas „breit“; lesbarer wäre oft, wenn eine Methode genau “ein Stück” packt/entpackt oder klar dokumentiert ist, dass sie “j Stück” behandelt.\n\n\n# Exercise: sudoku\n\n### Correctness\n- `Sudoku.main` hat nicht die geforderte Signatur `public static void main(String[] args)`, dadurch startet die Applikation nicht wie vorgesehen.\n- In `nofSolutions` überschreibst du den Parameter `max` direkt mit `max = 0;` und nutzt damit die MAX-Abbruchbedingung nicht mehr; die Methode kann so die geforderte Begrenzung auf `MAX` Lösungen nicht einhalten.\n- `nofSolutions` ruft rekursiv (mehrfach) `solved(...)` auf statt `nofSolutions(...)` weiterzuführen; dadurch wird nicht korrekt “die Anzahl Lösungen gezählt”, sondern eher “eine Lösung gesucht”.\n- In `nofSolutions`: Im Fall `model.get(row, col) != 0` wird zwar `solved(...)` aufgerufen, aber das Ergebnis wird nicht zurückgegeben/aufaddiert; damit stimmt die gezählte Anzahl nicht.\n- `nofSolutions` erfüllt die Requirement “The model was reset to its initial state” nicht: durch das Aufrufen von `solved` und die fehlende systematische Rücknahme (Backtracking) über alle Pfade bleibt das Model am Ende typischerweise verändert.\n- Die Bedingung `if(fieldNr == 81)` innerhalb des inneren Blocks von `nofSolutions` ist logisch unerreichbar (du bist in diesem Block, weil du gerade `solved(model, fieldNr + 1)` geprüft hast; `fieldNr` selbst wird dort nicht zu 81).\n\n### Suggestion\n- Schau dir für den Programmeinstieg an, wie Java das Entry-Point-Methodensignatur erwartet (Zugriffsmodifikator, `static`, Parameterliste). Vergleiche das mit deiner `main`.\n- Überlege bei `nofSolutions`, was der Parameter `max` semantisch bedeutet: er ist kein Zähler, sondern ein “Restbudget”/Limit. Wenn du ihn auf 0 setzt, nimmst du dir selbst die Möglichkeit zu zählen und korrekt abzubrechen.\n- Trenne gedanklich “eine Lösung finden” von “alle Lösungen zählen”: Beim Zählen darfst du nicht beim ersten Fund aufhören, sondern musst nach einem gefundenen vollständigen Board weiter suchen (weiteres Backtracking).\n- Statt in `nofSolutions` `solved(...)` aufzurufen, lass dieselbe Rekursion wie beim Lösen laufen, aber gib eine Zahl zurück (0/1/mehr) und addiere sie über alle gültigen Kandidaten; achte dabei darauf, dass du das verbleibende `max`-Budget mitgibst.\n- Achte darauf, dass du bei jedem ausprobierten Wert das Feld nach dem rekursiven Schritt wieder leerst, bevor du den nächsten Wert testest, damit das Model nach dem Durchlauf wieder im Ausgangszustand ist.\n\n### Code Style\n- Die vielen `System.out.println(...)` in der Rekursion erzeugen extrem viel Output und verlangsamen Backtracking massiv; besser nur gezielt debuggen oder mit einem Schalter/Logger arbeiten.\n- In `solved`/`nofSolutions` sind `81`, `9` hart codiert; nutze die Modell-Methoden (`model.size()`) statt Magic Numbers, dann funktioniert es auch für andere Größen und ist konsistenter.\n- Variablennamen wie `i` in der Schleife und gleichzeitig `row/col` sind ok, aber in `nofSolutions` ist `max` als Name irreführend, wenn du ihn als Zähler missbrauchst; konsistente Bedeutung pro Variable hilft beim Debuggen.\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" : "FAILED",
"message" : "Connection refused to host: 172.25.0.12; nested exception is: \n\tjava.net.ConnectException: Connection refused"
}, {
"name" : "uselessStuff()",
"status" : "PASSED",
"message" : null
}, {
"name" : "random1()",
"status" : "PASSED",
"message" : null
}, {
"name" : "random2()",
"status" : "FAILED",
"message" : "Connection refused to host: 172.25.0.13; nested exception is: \n\tjava.net.ConnectException: Connection refused"
}, {
"name" : "random3()",
"status" : "PASSED",
"message" : null
}, {
"name" : "boardIsValidAfterSolveN4()",
"status" : "FAILED",
"message" : "Connection refused to host: 172.25.0.14; nested exception is: \n\tjava.net.ConnectException: Connection refused"
}, {
"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" : "Connection refused to host: 172.25.0.15; nested exception is: \n\tjava.net.ConnectException: Connection refused"
}, {
"name" : "solveReturnsTrueForN1()",
"status" : "PASSED",
"message" : null
}, {
"name" : "solveReturnsTrueForN4()",
"status" : "PASSED",
"message" : null
}, {
"name" : "solveReturnsTrueForN8()",
"status" : "PASSED",
"message" : null
}, {
"name" : "solveReturnsFalseForN2()",
"status" : "FAILED",
"message" : "Connection refused to host: 172.25.0.16; nested exception is: \n\tjava.net.ConnectException: Connection refused"
}, {
"name" : "solveReturnsFalseForN3()",
"status" : "FAILED",
"message" : "N=3 has no valid queen placement ==> expected: <false> but was: <true>"
} ]
}
}