Add Task 5 prime number generator, AI comparison, and .gitignore
This commit is contained in:
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Build output
|
||||
out/
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
*.iml
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
10
.idea/.gitignore
generated
vendored
10
.idea/.gitignore
generated
vendored
@@ -1,10 +0,0 @@
|
||||
# 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/
|
||||
9
.idea/Aufgabenblatt1.iml
generated
9
.idea/Aufgabenblatt1.iml
generated
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
6
.idea/copilot.data.migration.ask2agent.xml
generated
6
.idea/copilot.data.migration.ask2agent.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Ask2AgentMigrationStateService">
|
||||
<option name="migrationStatus" value="COMPLETED" />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/misc.xml
generated
6
.idea/misc.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" default="true" project-jdk-name="openjdk-25" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
9
.idea/modules.xml
generated
9
.idea/modules.xml
generated
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/Aufgabenblatt1.iml" filepath="$PROJECT_DIR$/.idea/Aufgabenblatt1.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/aufgabenblatt1/aufgabenblatt1.iml" filepath="$PROJECT_DIR$/aufgabenblatt1/aufgabenblatt1.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -57,3 +57,48 @@ Beide Lösungen verwenden den **gleichen Algorithmus**: Sortieren der Zeichen un
|
||||
- **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()`.
|
||||
|
||||
# Task 5
|
||||
|
||||
## Ergebnisse
|
||||
|
||||
| maximum | Anzahl Primzahlen (Algorithmus) | maximum/ln(maximum) (Schätzung) |
|
||||
|--------:|-------------------------------:|-------------------------------:|
|
||||
| 100 | 25 | 21,7 |
|
||||
| 500 | 95 | 80,5 |
|
||||
| 1.000 | 168 | 144,8 |
|
||||
| 2.000 | 303 | 263,1 |
|
||||
| 5.000 | 669 | 587,0 |
|
||||
| 10.000 | 1.229 | 1.085,7 |
|
||||
| 20.000 | 2.262 | 2.019,5 |
|
||||
| 50.000 | 5.133 | 4.621,2 |
|
||||
| 100.000 | 9.592 | 8.685,9 |
|
||||
| 200.000 | 17.984 | 16.385,3 |
|
||||
|
||||
## Kurvenvergleich
|
||||
|
||||

|
||||
|
||||
Die Schätzung durch maximum/ln(maximum) (Primzahlsatz) liegt durchgehend etwas **unter** der tatsächlichen Anzahl der Primzahlen, nähert sich aber mit steigendem maximum proportional an. Beide Kurven zeigen den gleichen sublinearen Wachstumsverlauf.
|
||||
|
||||
## Aufwandsvergleich: Algorithmus vs. Formel
|
||||
|
||||
- **Algorithmus (Zählen durch Sieben):** Für jede Zahl bis `maximum` wird geprüft, ob sie prim ist. Die naive Implementierung hat eine Laufzeitkomplexität von **O(n²)** — für jede der n Zahlen wird im schlimmsten Fall bis n dividiert. Bei maximum = 200.000 sind das potenziell Milliarden von Divisionen.
|
||||
- **Formel maximum/ln(maximum):** Eine einzige Division und ein Logarithmus — **O(1)**, also konstanter Aufwand, unabhängig von der Größe von maximum.
|
||||
|
||||
**Fazit:** Die Formel ist um Größenordnungen schneller, liefert aber nur eine Schätzung. Der Algorithmus liefert das exakte Ergebnis, braucht dafür aber erheblich mehr Rechenzeit. Für große Werte ist die Formel eine sehr gute Approximation.
|
||||
|
||||
## Vergleich: Eigene Lösung vs. KI-Lösung
|
||||
|
||||
Beide Lösungen liefern **identische Ergebnisse** für alle getesteten Werte. Der zentrale Unterschied liegt in der `isPrime()`-Methode:
|
||||
|
||||
**Gemeinsamkeiten:**
|
||||
- Gleiche Gesamtstruktur: Klasse mit `maximum`-Feld, `isPrime()`, `countPrimes()`, `printPrimeNumbers()`
|
||||
- Gleicher Brute-Force-Ansatz: Jede Zahl einzeln auf Primeigenschaft prüfen
|
||||
|
||||
**Unterschiede:**
|
||||
- **Schleifengrenze:** Meine Lösung prüft Teiler bis `number - 1` (O(n) pro Zahl). Die KI prüft nur bis `√number` (`i * i <= number`), was O(√n) pro Zahl ergibt — mathematisch ausreichend, da ein Teiler > √n immer einen Gegenteiler < √n hat.
|
||||
- **Gerade Zahlen:** Die KI schließt gerade Zahlen > 2 sofort aus (`if (number % 2 == 0) return false`) und prüft danach nur ungerade Teiler (`i += 2`). Das halbiert die Anzahl der Divisionen nochmals.
|
||||
- **Sonderfälle:** Die KI behandelt Zahlen < 2 und die Zahl 2 explizit als Sonderfälle.
|
||||
|
||||
**Bewertung:** Die KI-Lösung ist **besser**. Durch die Optimierung der Schleifengrenze auf √n und das Überspringen gerader Zahlen sinkt die Gesamtkomplexität von O(n²) auf ca. O(n√n) — bei maximum = 200.000 ein erheblicher Geschwindigkeitsvorteil. Die Ergebnisse sind trotzdem identisch.
|
||||
|
||||
BIN
aufgabenblatt1/src/task5.png
Normal file
BIN
aufgabenblatt1/src/task5.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
45
aufgabenblatt1/src/task5/PrimeNumberGenerator.java
Normal file
45
aufgabenblatt1/src/task5/PrimeNumberGenerator.java
Normal file
@@ -0,0 +1,45 @@
|
||||
package task5;
|
||||
|
||||
public class PrimeNumberGenerator {
|
||||
private int maximum;
|
||||
|
||||
public PrimeNumberGenerator(int maximum) {
|
||||
this.maximum = maximum;
|
||||
}
|
||||
public void printPrimeNumbers() {
|
||||
for (int i = 2; i <= maximum; i++) {
|
||||
if (isPrime(i)) {
|
||||
System.out.println(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
private boolean isPrime(int number) {
|
||||
for (int i = 2; i < number; i++) {
|
||||
if (number % i == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private int countPrimes() {
|
||||
int count = 0;
|
||||
for (int i = 2; i <= maximum; i++) {
|
||||
if (isPrime(i)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] testValues = {100, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000};
|
||||
|
||||
System.out.println("maximum,Anzahl Primzahlen (Algorithmus),maximum/ln(maximum) (Schätzung)");
|
||||
for (int max : testValues) {
|
||||
PrimeNumberGenerator generator = new PrimeNumberGenerator(max);
|
||||
int counted = generator.countPrimes();
|
||||
double estimated = max / Math.log(max);
|
||||
System.out.printf("%d,%d,%.1f%n", max, counted, estimated);
|
||||
}
|
||||
}
|
||||
}
|
||||
51
aufgabenblatt1/src/task5/PrimeNumberGeneratorAI.java
Normal file
51
aufgabenblatt1/src/task5/PrimeNumberGeneratorAI.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package task5;
|
||||
|
||||
public class PrimeNumberGeneratorAI {
|
||||
private final int maximum;
|
||||
|
||||
public PrimeNumberGeneratorAI(int maximum) {
|
||||
this.maximum = maximum;
|
||||
}
|
||||
|
||||
public void printPrimeNumbers() {
|
||||
for (int i = 2; i <= maximum; i++) {
|
||||
if (isPrime(i)) {
|
||||
System.out.println(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPrime(int number) {
|
||||
if (number < 2) return false;
|
||||
if (number == 2) return true;
|
||||
if (number % 2 == 0) return false;
|
||||
for (int i = 3; i * i <= number; i += 2) {
|
||||
if (number % i == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int countPrimes() {
|
||||
int count = 0;
|
||||
for (int i = 2; i <= maximum; i++) {
|
||||
if (isPrime(i)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] testValues = {100, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000};
|
||||
|
||||
System.out.println("maximum,Anzahl Primzahlen (Algorithmus),maximum/ln(maximum) (Schätzung)");
|
||||
for (int max : testValues) {
|
||||
PrimeNumberGeneratorAI generator = new PrimeNumberGeneratorAI(max);
|
||||
int counted = generator.countPrimes();
|
||||
double estimated = max / Math.log(max);
|
||||
System.out.printf("%d,%d,%.1f%n", max, counted, estimated);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
aufgabenblatt1/src/task5/primzahlen_ergebnisse.csv
Normal file
11
aufgabenblatt1/src/task5/primzahlen_ergebnisse.csv
Normal file
@@ -0,0 +1,11 @@
|
||||
maximum,Anzahl Primzahlen (Algorithmus),maximum/ln(maximum) (Schätzung)
|
||||
100,25,21.7
|
||||
500,95,80.5
|
||||
1000,168,144.8
|
||||
2000,303,263.1
|
||||
5000,669,587.0
|
||||
10000,1229,1085.7
|
||||
20000,2262,2019.5
|
||||
50000,5133,4621.2
|
||||
100000,9592,8685.9
|
||||
200000,17984,16385.3
|
||||
|
@@ -1,6 +0,0 @@
|
||||
# Task 1
|
||||

|
||||
|
||||
# Task 2
|
||||

|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user