commit c6fca7b5410a0ce9b5506954edc9d7fbd21e5b8a Author: Jean-Luc Makiola Date: Mon Mar 30 20:45:04 2026 +0200 Add initial implementation including utility classes, core modules, and project configuration files diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..ab1f416 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/Aufgabenblatt1.iml b/.idea/Aufgabenblatt1.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/Aufgabenblatt1.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.ask2agent.xml b/.idea/copilot.data.migration.ask2agent.xml new file mode 100644 index 0000000..1f2ea11 --- /dev/null +++ b/.idea/copilot.data.migration.ask2agent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..be7226b --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5784362 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/aufgabenblatt1/aufgabenblatt1.iml b/aufgabenblatt1/aufgabenblatt1.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/aufgabenblatt1/aufgabenblatt1.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/aufgabenblatt1/src/solution.md b/aufgabenblatt1/src/solution.md new file mode 100644 index 0000000..e140a11 --- /dev/null +++ b/aufgabenblatt1/src/solution.md @@ -0,0 +1,59 @@ +# Task 1 +![](./task1.png) + +# Task 2 +![](./task2.png) + +# Task 3 + +## Strategie & Laufzeitkomplexität + +Mein Ansatz für `autoGuess()` verwendet **Binary Search** (Binäre Suche). Die Suchgrenzen starten bei `Integer.MIN_VALUE` und `Integer.MAX_VALUE`. In jedem Schritt wird die Mitte des verbleibenden Bereichs geraten und mit `isBigger()` geprüft, ob die Zielzahl größer oder kleiner ist. Dadurch halbiert sich der Suchbereich mit jedem Versuch. + +**Laufzeitkomplexität: O(log n)**, wobei n die Größe des Suchbereichs ist (hier 2^32 für den gesamten int-Bereich). Das ergibt maximal ~32 Rateversuche, unabhängig von der Zielzahl. + +## Vergleich: Eigene Lösung vs. KI-Lösung + +Die KI (Claude) hat die gleiche Aufgabe erhalten — die vollständige NumberGuesser-Klasse mit einer leeren `autoGuess()`-Methode zum Ausfüllen. + +**Ergebnis:** Beide Implementierungen sind **identisch**. Sowohl meine als auch die KI-Lösung verwenden Binary Search mit denselben Suchgrenzen und derselben overflow-sicheren Berechnung der Mitte (`low + (high - low) / 2`). + +**Gemeinsamkeiten:** +- Beide nutzen Binary Search über den gesamten int-Bereich +- Gleiche Initialisierung: `low = Integer.MIN_VALUE`, `high = Integer.MAX_VALUE` +- Gleiche Berechnung des Mittelpunkts: `low + (high - low) / 2` (overflow-sicher) +- Gleiche Abbruchbedingung: `while (low <= high)` + +**Unterschiede:** +- Keine funktionalen Unterschiede in `autoGuess()` + +## KI-Abschätzung der Laufzeitkomplexität + +**KI-Antwort:** "Runtime complexity for both: O(log n) where n = 2^32 (the full int range), so at most ~32 iterations." + +**Bewertung:** Die KI liegt **richtig**. Binary Search halbiert den Suchbereich in jedem Schritt, was zu einer logarithmischen Laufzeit führt. Für den gesamten int-Bereich von 2^32 Werten ergibt das log₂(2^32) = 32 Schritte im Worst Case. Dies ist deutlich effizienter als ein linearer Ansatz mit O(n), der im schlimmsten Fall alle ~4,3 Milliarden Werte durchprobieren müsste. + +# Task 4 + +## Strategie & Laufzeitkomplexität + +Mein Ansatz für `isAnagram()` wandelt beide Wörter in char-Arrays um, sortiert diese mit `Arrays.sort()` und vergleicht die sortierten Strings. Wenn die sortierten Versionen gleich sind, handelt es sich um ein Anagramm. + +**Laufzeitkomplexität: O(n log n)**, wobei n die Länge des längeren Wortes ist. Der dominierende Faktor ist das Sortieren der char-Arrays (`Arrays.sort()` verwendet Dual-Pivot Quicksort mit O(n log n)). Der anschließende Vergleich ist nur O(n). + +Ein effizienterer Ansatz wäre O(n) mit einer HashMap/Array, die die Buchstabenhäufigkeiten zählt — allerdings ist O(n log n) für typische Wortlängen völlig ausreichend. + +## Vergleich: Eigene Lösung vs. KI-Lösung + +Beide Lösungen verwenden den **gleichen Algorithmus**: Sortieren der Zeichen und Vergleich der sortierten Arrays. + +**Gemeinsamkeiten:** +- Beide nutzen `Arrays.sort()` auf char-Arrays +- Gleicher algorithmischer Ansatz: Sort-and-Compare +- Gleiche Laufzeitkomplexität: O(n log n) + +**Unterschiede:** +- **Rückgabetyp:** Meine Lösung gibt `void` zurück und druckt das Ergebnis direkt auf die Konsole. Die KI gibt `boolean` zurück — sauberer, da die Methode so wiederverwendbar ist. +- **Null-Check:** Die KI prüft auf `null`-Werte (`if (word0 == null || word1 == null)`). Meine Lösung tut dies nicht, würde also bei `null`-Eingaben eine `NullPointerException` werfen. +- **Vergleichsmethode:** Meine Lösung erstellt neue Strings und vergleicht mit `String.equals()`. Die KI vergleicht die char-Arrays direkt mit `Arrays.equals()`, was einen unnötigen String-Allokationsschritt spart. +- **Hilfsmethode:** Meine Lösung lagert das Sortieren in eine eigene `sortString()`-Methode aus. Die KI schreibt alles inline in `isAnagram()`. diff --git a/aufgabenblatt1/src/task1.png b/aufgabenblatt1/src/task1.png new file mode 100644 index 0000000..94f2a61 Binary files /dev/null and b/aufgabenblatt1/src/task1.png differ diff --git a/aufgabenblatt1/src/task2.png b/aufgabenblatt1/src/task2.png new file mode 100644 index 0000000..65ff825 Binary files /dev/null and b/aufgabenblatt1/src/task2.png differ diff --git a/aufgabenblatt1/src/task3/NumberGuesser.java b/aufgabenblatt1/src/task3/NumberGuesser.java new file mode 100644 index 0000000..47db76c --- /dev/null +++ b/aufgabenblatt1/src/task3/NumberGuesser.java @@ -0,0 +1,49 @@ +package task3; + +import java.util.Scanner; + +public class NumberGuesser { + private int number; + + public NumberGuesser(int targetNumber){ + this.number = targetNumber; + } + public boolean isBigger(int guess){ + return guess < number; + } + + public void guess(){ + Scanner scanner = new Scanner(System.in); + System.out.println("Guess a number: "); + int guess = scanner.nextInt(); + switch (Integer.compare(guess, number)) { + case -1 -> System.out.println("Too low!"); + case 0 -> System.out.println("Correct!"); + case 1 -> System.out.println("Too high!"); + } + } + + public void autoGuess(){ + int low = Integer.MIN_VALUE; + int high = Integer.MAX_VALUE; + + while (low <= high) { + int mid = low + (high - low) / 2; + + if (mid == number) { + System.out.println("Found the number: " + mid); + return; + } else if (isBigger(mid)) { + low = mid + 1; + } else { + high = mid - 1; + } + } + } + + public static void main(String[] args) { + NumberGuesser numberGuesser = new NumberGuesser(100); + System.out.println(numberGuesser.isBigger(Integer.MAX_VALUE/2)); + numberGuesser.autoGuess(); + } +} diff --git a/aufgabenblatt1/src/task3/NumberGuesserAI.java b/aufgabenblatt1/src/task3/NumberGuesserAI.java new file mode 100644 index 0000000..6320231 --- /dev/null +++ b/aufgabenblatt1/src/task3/NumberGuesserAI.java @@ -0,0 +1,38 @@ +package task3; + +import java.util.Scanner; + +public class NumberGuesserAI { + private final int number; + + public NumberGuesserAI(int targetNumber){ + this.number = targetNumber; + } + public boolean isBigger(int guess){ + return guess < number; + } + + public void autoGuess(){ + int low = Integer.MIN_VALUE; + int high = Integer.MAX_VALUE; + + while (low <= high) { + int mid = low + (high - low) / 2; + + if (mid == number) { + System.out.println("Found the number: " + mid); + return; + } else if (isBigger(mid)) { + low = mid + 1; + } else { + high = mid - 1; + } + } + } + + public static void main(String[] args) { + NumberGuesserAI numberGuesser = new NumberGuesserAI(100); + System.out.println(numberGuesser.isBigger(Integer.MAX_VALUE/2)); + numberGuesser.autoGuess(); + } +} \ No newline at end of file diff --git a/aufgabenblatt1/src/task4/AnagrammChecker.java b/aufgabenblatt1/src/task4/AnagrammChecker.java new file mode 100644 index 0000000..ac3968b --- /dev/null +++ b/aufgabenblatt1/src/task4/AnagrammChecker.java @@ -0,0 +1,35 @@ +package task4; + +import java.lang.reflect.Array; +import java.util.Arrays; + +public class AnagrammChecker { + private String word0; + private String word1; + + public AnagrammChecker(String word0, String word1){ + this.word0 = word0; + this.word1 = word1; + } + + + + public void isAnagram(){ + String sortedWord0 = sortString(word0); + String sortedWord1 = sortString(word1); + + if (sortedWord1.equals(sortedWord0)) { + System.out.println("Die Wörter sind Anagramme."); + } else { + System.out.println("Die Wörter sind keine Anagramme."); + } + } + + private String sortString(String string) { + char tempArr[] = string.toCharArray(); + + Arrays.sort(tempArr); + + return new String(tempArr); + } +} diff --git a/aufgabenblatt1/src/task4/AnagrammCheckerAI.java b/aufgabenblatt1/src/task4/AnagrammCheckerAI.java new file mode 100644 index 0000000..506b956 --- /dev/null +++ b/aufgabenblatt1/src/task4/AnagrammCheckerAI.java @@ -0,0 +1,27 @@ +package task4; + +import java.util.Arrays; + +public class AnagrammCheckerAI { + private String word0; + private String word1; + + public AnagrammCheckerAI(String word0, String word1){ + this.word0 = word0; + this.word1 = word1; + } + + + + public boolean isAnagram() { + if (word0 == null || word1 == null) { + return false; + } + char[] chars0 = word0.toLowerCase().toCharArray(); + char[] chars1 = word1.toLowerCase().toCharArray(); + Arrays.sort(chars0); + Arrays.sort(chars1); + return Arrays.equals(chars0, chars1); + } + +} diff --git a/aufgabenblatt1/src/util/ArrayTester.java b/aufgabenblatt1/src/util/ArrayTester.java new file mode 100644 index 0000000..c0426b3 --- /dev/null +++ b/aufgabenblatt1/src/util/ArrayTester.java @@ -0,0 +1,14 @@ +package util; + +public class ArrayTester { + public static final void main(String[] args) + { + Util util = new Util(); + int num = 60; + int[] array0 = new int[num]; + int[] array1 = new int[num]; + util.fillArrayRandom(array0, num*100); + util.fillArrayRandom(array1, num*100); + System.out.println(util.firstMatch(array0, array1)); + } +} diff --git a/aufgabenblatt1/src/util/Util.java b/aufgabenblatt1/src/util/Util.java new file mode 100644 index 0000000..4460f07 --- /dev/null +++ b/aufgabenblatt1/src/util/Util.java @@ -0,0 +1,116 @@ +package util; +/** + * Write a description of class Util here. + * + * @author (your name) + * @version (a version number or a date) + */ +public class Util +{ + public void printArray(int[] array) + { + for (int i = 0; i < array.length; ++i) + { + System.out.print(array[i]); + + // Prüfen, ob wir nicht beim letzten Element sind. + // Auf das letzte Element sollte kein Komma folgen. + if (i < array.length - 1) + { + System.out.print(","); + } + } + + // Nach Ausgabe brechen wir die Zeile um, damit folgende Ausgaben + // in einer neuen Zeile beginnen. + System.out.println(); + } + + public int randomInt(int upperLimit) + { + double random = Math.random(); // Zufallszahl zwischen 0.0 und 1.0 holen. + + // Zufallszahl per Multiplikation auf 0.0-upperLimit skalieren + random = random * upperLimit; + + // Nachkommastellen abschneiden und in Ganzzahlwert (int) umwandeln. + int result = (int) random; + + return result; + } + + public void fillArrayRandom(int[] array, int upperLimit) + { + for (int i = 0; i < array.length; ++i) + { + array[i] = randomInt(upperLimit); + } + } + + public int[] concatArray(int[] array0, int[] array1) + { + int[] result = new int[array0.length + array1.length]; + + // Manuelles Kopieren mit Schleifen. + for (int i = 0; i < array0.length; ++i) + { + result[i] = array0[i]; + } + for (int i = 0; i < array1.length; ++i) + { + // Um array0.length verschoben einfügen. + result[array0.length + i] = array1[i]; + } + + // Alternative Lösung unter Verwendung von System.arraycopy(). + // System.arraycopy(array0, 0, result, 0, array0.length); + // System.arraycopy(array1, 0, result, array0.length, array1.length); + + return result; + } + + public int findMax(int[] array) { + int max = 0; + boolean found = false; + int loopRuns = 0; + for (int i = 0; !found && i < array.length; ++i) { + loopRuns++; + if (array[i] > max) { + max = array[i]; + } + } + return loopRuns; + } + + public int firstMatch(int[] array0, int[] array1) { + int loopRuns = 0; + for (int i = 0; i < array0.length; i++) { + for (int j = 0; j < array1.length; j++) { + loopRuns++; + if (array0[i] == array1[j]) { + return loopRuns; + } + } + } + return loopRuns; + } + + public void fillArrayRandomRecursively(int[] array, int start, int upperLimit) + { + if (array.length - start <= 0) + { + return; + } + + array[start] = randomInt(upperLimit); + fillArrayRandomRecursively(array, start + 1, upperLimit); + } + + public void testRandomFillRecursively() + { + Util util = new Util(); + int[] valueArray = new int[100]; + util.fillArrayRandomRecursively(valueArray, 0, 100); + util.printArray(valueArray); + } +} diff --git a/out/production/aufgabenblatt1/solution.md b/out/production/aufgabenblatt1/solution.md new file mode 100644 index 0000000..10503f8 --- /dev/null +++ b/out/production/aufgabenblatt1/solution.md @@ -0,0 +1,6 @@ +# Task 1 +![](./task1.png) + +# Task 2 +![](./task2.png) + diff --git a/out/production/aufgabenblatt1/task1.png b/out/production/aufgabenblatt1/task1.png new file mode 100644 index 0000000..94f2a61 Binary files /dev/null and b/out/production/aufgabenblatt1/task1.png differ diff --git a/out/production/aufgabenblatt1/task2.png b/out/production/aufgabenblatt1/task2.png new file mode 100644 index 0000000..65ff825 Binary files /dev/null and b/out/production/aufgabenblatt1/task2.png differ diff --git a/out/production/aufgabenblatt1/task3/NumberGuesser.class b/out/production/aufgabenblatt1/task3/NumberGuesser.class new file mode 100644 index 0000000..bc3ceb8 Binary files /dev/null and b/out/production/aufgabenblatt1/task3/NumberGuesser.class differ diff --git a/out/production/aufgabenblatt1/util/ArrayTester.class b/out/production/aufgabenblatt1/util/ArrayTester.class new file mode 100644 index 0000000..289f88e Binary files /dev/null and b/out/production/aufgabenblatt1/util/ArrayTester.class differ diff --git a/out/production/aufgabenblatt1/util/Util.class b/out/production/aufgabenblatt1/util/Util.class new file mode 100644 index 0000000..b4a7c87 Binary files /dev/null and b/out/production/aufgabenblatt1/util/Util.class differ