{
"llm" : {
"feedback" : "# Exercise: fractal\n\n### Correctness\n- In `Boxes.drawRec`: Bei `n == 0` zeichnest du gar nichts (`return`), dadurch bleibt die Basisstufe leer. Laut Aufgabenidee muss in der kleinsten Rekursionsebene mindestens das Rechteck gezeichnet werden.\n- In `Boxes.drawRec`: Du machst nur 3 rekursive Aufrufe (oben links, oben rechts, unten links). Dadurch fehlt ein Viertel (unten rechts) und das Muster ist nicht vollständig.\n- In `Triangles.drawRec`: Bei `n == 0` zeichnest du ebenfalls nichts (`return`). Damit wird auch hier die Basisstufe nicht gezeichnet und bei `n=1` werden nur die äußeren Linien gezeichnet, aber keine kleinsten Dreiecke als Endzustand.\n- In `Fractal.main`: Die Aufgabenstellung fordert das Implementieren der `draw`-Methoden in `Boxes` und `Triangles`. Du hast zusätzlich `Circles` eingebaut und `Fractal` angepasst (zusätzliche Keys `q/e`, feste Indexannahme `shapes.get(currShape % 3)`). Das ist eine Abweichung von der vorgegebenen Struktur (auch wenn es “funktioniert”), und kann beim Abgleich mit der Vorlage/Tests problematisch sein.\n\n### Suggestion\n- Überlege dir bei beiden Rekursionen (`Boxes`, `Triangles`), was genau der “kleinste” Fall (`n == 0`) zeichnen soll. Wenn du dort sofort zurückkehrst, fehlt der sichtbare Endpunkt der Rekursion.\n- Prüfe bei `Boxes`, welche Teilquadrate in jedem Schritt entstehen sollen. Skizziere einmal ein Quadrat und markiere alle Teilquadranten, die in der nächsten Stufe vorkommen müssen, dann siehst du schnell, welcher rekursive Call noch fehlt.\n- Bei `Triangles`: Wenn du die Rekursion so aufbaust, dass du immer kleinere Dreiecke zeichnest, sollte die Basisstufe ein vollständiges Dreieck (3 Linien) zeichnen. Alternativ (wenn du “immer erst zeichnen, dann rekursiv”) musst du sicherstellen, dass die Rekursion auch wirklich bis zu einem gezeichneten Endzustand läuft.\n- Wenn die Abgabe/Autokorrektur strikt ist: Lass `Fractal` und die Shape-Liste so nah wie möglich an der Vorlage und ändere keine Signaturen/Konstruktor-Zwänge (z.B. `new Circles(m)` statt parameterlos). Zusätzliche Features lieber separat oder optional halten.\n\n### Code Style\n- In `Fractal.main` ist `shapes.get(currShape % 3)` unnötig “hart kodiert”. Besser ist es, sich an `shapes.size()` zu orientieren, damit die Liste wartbar bleibt.\n- `Circles` ist für die Aufgabe nicht verlangt; das zusätzliche Feature (inkl. `setCircles`, Key-Handling, Cast in `Fractal`) macht den Code komplexer und stärker gekoppelt als nötig.\n\n\n# Exercise: knapsack\n\n### Correctness\n- In `pack(...)` aktualisierst du `maxValue` am Ende (`i == weights.length`) nur anhand von `currValue`, ohne nochmals zu prüfen, ob `currWeight <= maxWeight` ist. Das kann zu ungültigen Lösungen führen, falls irgendwo doch ein Zustand mit Übergewicht durchrutscht (z.B. bei späteren Änderungen/Refactorings).\n- In `KnapsackN` hat `main()` nicht die übliche Java-Signatur `main(String[] args)`. Je nach Test-/Run-Setup wird die Methode so nicht als Einstiegspunkt erkannt.\n\n### Suggestion\n- Überlege dir, ob du beim “Leaf” der Rekursion (wenn alle Items betrachtet wurden) dieselbe Bedingung wie beim “Weitergehen” absichern willst: Nur dann `maxValue` updaten, wenn das aktuelle Gewicht wirklich innerhalb der Grenze liegt.\n- Prüfe in der Vorlage/Tests, wie `KnapsackN` gestartet wird: Wenn ein normaler Java-Entry-Point erwartet ist, muss die Signatur exakt passen.\n\n### Code Style\n- In `pack(...)` lädst/entlädst du ein Item `count`-mal über eine innere Schleife; das ist korrekt, aber unnötig teuer. Du könntest das Laden/Entladen je Variante kompakter machen (z.B. in einem Schritt statt `count` Einzeloperationen).\n- Kommentare sind hilfreich, aber achte darauf, dass sie eher die Idee erklären als die Zeile zu wiederholen (z.B. “backtracking” ist gut, “lade count-mal” ist eher redundant).\n\n\n# Exercise: queens\n\n1. Correctness \n- \n\n2. Suggestion \n- \n\n3. Code Style \n- In `count()` verwendest du einen Parameter `boolean[][] board`, der den gleichnamigen Klassen-Field `board` überschattet; das ist zwar korrekt, kann aber beim Lesen schnell verwirren—ein anderer Parametername würde die Unterscheidung klarer machen. \n- In `Queens.java` ist `main()` nicht als übliche Java-Entry-Point-Signatur (`static void main(String[] args)`) deklariert; falls ihr das Programm direkt starten sollt, könnte das je nach Umgebung/Tests ein Problem sein (auch wenn es nicht Teil der `QueensSolver`-Aufgabe ist).\n\n\n# Exercise: sudoku\n\n### Correctness\n- Du hast die geforderten Methoden `solved(SudokuModel model)` und `nofSolutions(SudokuModel model)` in `…sudoku/solver/SudokuSolverImpl.java` nicht implementiert, sondern ein komplett eigenes API (`Solver`, `Board`, `BacktrackingSolver`, etc.) gebaut.\n- Dadurch erfüllst du die Schnittstelle aus der Vorlage nicht: Die GUI/Applikation der Aufgabe erwartet `SudokuChecker`, `SudokuSolver`, `SudokuModel` und deren Zusammenspiel (insbesondere auch, dass `nofSolutions` die Anzahl Lösungen liefert und das Modell danach wieder im Ausgangszustand ist).\n- In der Aufgabenbeschreibung steht explizit “Implementiere die `solved` Methode in … SudokuSolverImpl.java” sowie `nofSolutions`. Dein Abgabe-Stand enthält diese Implementationen nicht im vorgegebenen Ort/Format.\n\n### Suggestion\n- Schau dir an, welche Klassen/Interfaces in der Vorlage als “Framework” vorgegeben sind (`SudokuSolver`, `SudokuModel`, `SudokuChecker`) und implementiere die Logik genau dort, statt neue Domain-Klassen einzuführen.\n- Orientiere dich an der Signatur/Verwendung: `solved(model)` muss **das übergebene** `SudokuModel` in-place füllen oder es (bei “keine Lösung”) wieder auf den Startzustand zurücksetzen. Überlege dir, wie du beim Backtracking sicherstellst, dass Felder beim Scheitern wieder geleert werden.\n- Für `nofSolutions(model)` ist wichtig, dass du beim Zählen nach jedem getesteten Wert wieder “zurückräumst” (Backtracking), und dass du nach außen hin am Ende den ursprünglichen Zustand wiederherstellst. Überlege dir dafür eine Strategie, wie du Anfangsbelegung vs. von dir gesetzte Werte unterscheiden kannst (z.B. “vordefinierte Felder überspringen” und nur leere füllen).\n\n### Code Style\n- Du hast sehr viel zusätzliche/alternative Architektur eingebaut (eigene `Board`, eigene `GUI`, eigene Interfaces). Das macht die Abgabe schwer vergleichbar und widerspricht dem üblichen Erwartungsformat solcher Template-Aufgaben (Implementierung an der vorgesehenen Stelle statt “Rewrite”).\n- In `SudokuApp` erzeugst du einen `ConstraintChecker checker = new ConstraintChecker();`, übergibst ihn aber nicht konsistent weiter: `BacktrackingSolver` bekommt später teilweise einen anderen/neu erzeugten `ConstraintChecker` (über den Convenience-Konstruktor wäre das der Fall). Das ist unnötig verwirrend – besser eine klare Ownership/Injection.\n- In `DefaultCandidateStrategy` sind mehrere Imports ungenutzt (`List` brauchst du, aber z.B. je nach IDE könnten `Collectors`/`IntStream` ok sein; prüf das), und generell wäre es gut, Imports automatisch aufräumen zu lassen.\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" : "PASSED",
"message" : null
}, {
"name" : "boardIsValidAfterSolveN5()",
"status" : "FAILED",
"message" : "Connection refused to host: 172.25.0.11; nested exception is: \n\tjava.net.ConnectException: Connection refused"
}, {
"name" : "boardIsValidAfterSolveN8()",
"status" : "FAILED",
"message" : "Connection refused to host: 172.25.0.12; nested exception is: \n\tjava.net.ConnectException: Connection refused"
}, {
"name" : "boardSizeIsCorrectForN4()",
"status" : "PASSED",
"message" : null
}, {
"name" : "boardSizeIsCorrectForN8()",
"status" : "PASSED",
"message" : null
}, {
"name" : "countN1()",
"status" : "PASSED",
"message" : null
}, {
"name" : "countN2()",
"status" : "PASSED",
"message" : null
}, {
"name" : "countN3()",
"status" : "PASSED",
"message" : null
}, {
"name" : "countN4()",
"status" : "FAILED",
"message" : "Connection refused to host: 172.25.0.13; nested exception is: \n\tjava.net.ConnectException: Connection refused"
}, {
"name" : "countN5()",
"status" : "PASSED",
"message" : null
}, {
"name" : "countN6()",
"status" : "PASSED",
"message" : null
}, {
"name" : "countN8()",
"status" : "PASSED",
"message" : null
}, {
"name" : "solveReturnsTrueForN1()",
"status" : "PASSED",
"message" : null
}, {
"name" : "solveReturnsTrueForN4()",
"status" : "PASSED",
"message" : null
}, {
"name" : "solveReturnsTrueForN8()",
"status" : "PASSED",
"message" : null
}, {
"name" : "solveReturnsFalseForN2()",
"status" : "PASSED",
"message" : null
}, {
"name" : "solveReturnsFalseForN3()",
"status" : "PASSED",
"message" : null
} ]
}
}