diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fb7783f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,135 @@
+# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,java,maven,eclipse
+# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,java,maven,eclipse
+
+### Eclipse ###
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# CDT- autotools
+.autotools
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+# Annotation Processing
+.apt_generated/
+.apt_generated_test/
+
+# Scala IDE specific (Scala & Java development for Eclipse)
+.cache-main
+.scala_dependencies
+.worksheet
+
+# Uncomment this line if you wish to ignore the project description file.
+# Typically, this file would be tracked if it contains build/dependency configurations:
+#.project
+
+### Eclipse Patch ###
+# Spring Boot Tooling
+.sts4-cache/
+
+### Java ###
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+replay_pid*
+
+### Maven ###
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+# https://github.com/takari/maven-wrapper#usage-without-binary-jar
+.mvn/wrapper/maven-wrapper.jar
+
+# Eclipse m2e generated files
+# Eclipse Core
+.project
+# JDT-specific (Eclipse Java Development Tools)
+.classpath
+
+### VisualStudioCode ###
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+!.vscode/*.code-snippets
+
+# Local History for Visual Studio Code
+.history/
+
+# Built Visual Studio Code Extensions
+*.vsix
+
+### VisualStudioCode Patch ###
+# Ignore all local history of files
+.history
+.ionide
+
+# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,java,maven,eclipse
+
diff --git a/.mvn/jvm.config b/.mvn/jvm.config
new file mode 100644
index 0000000..e69de29
diff --git a/.mvn/maven.config b/.mvn/maven.config
new file mode 100644
index 0000000..e69de29
diff --git a/checkstyle.xml b/checkstyle.xml
new file mode 100644
index 0000000..8108f76
--- /dev/null
+++ b/checkstyle.xml
@@ -0,0 +1,205 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pmd.xml b/pmd.xml
new file mode 100644
index 0000000..f004da7
--- /dev/null
+++ b/pmd.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+ My custom rules
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..76c82f9
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,160 @@
+
+ 4.0.0
+ de.hs_mannheim.pr2
+ solutions
+ 1.0-SNAPSHOT
+ jar
+
+ PR2 Excercises
+
+
+ UTF-8
+ 21
+ 21
+ 5.12.2
+ 1.12.2
+ 7.13.0
+
+
+
+ jitpack.io
+ https://jitpack.io
+
+
+
+ install
+ ${basedir}/target
+ ${project.artifactId}-${project.version}
+
+
+ maven-compiler-plugin
+ 3.10.1
+
+
+ maven-surefire-plugin
+ 3.5.2
+
+
+ maven-failsafe-plugin
+ 3.5.2
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ 3.6.0
+
+
+ com.puppycrawl.tools
+ checkstyle
+ 10.4
+
+
+
+ checkstyle.xml
+ true
+ true
+ false
+
+
+
+ validate
+ validate
+
+ check
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-pmd-plugin
+ 3.26.0
+
+
+ net.sourceforge.pmd
+ pmd-core
+ ${pmdVersion}
+
+
+ net.sourceforge.pmd
+ pmd-java
+ ${pmdVersion}
+
+
+ net.sourceforge.pmd
+ pmd-javascript
+ ${pmdVersion}
+
+
+ net.sourceforge.pmd
+ pmd-jsp
+ ${pmdVersion}
+
+
+
+
+ ./pmd.xml
+
+ true
+ true
+
+
+
+
+ check
+
+
+
+
+
+
+
+
+
+ com.github.thomsmits
+ game-framework
+ v1.0
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit.jupiter.version}
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit.jupiter.version}
+
+
+ org.junit.jupiter
+ junit-jupiter-params
+ ${junit.jupiter.version}
+
+
+ org.junit.platform
+ junit-platform-suite
+ ${junit.platform.version}
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ ${junit.jupiter.version}
+
+
+ org.jfree
+ jfreechart
+ 1.5.3
+
+
+
+
+
diff --git a/src/main/java/de/hs_mannheim/pr2/Skiplist.java b/src/main/java/de/hs_mannheim/pr2/Skiplist.java
new file mode 100644
index 0000000..4ea28ef
--- /dev/null
+++ b/src/main/java/de/hs_mannheim/pr2/Skiplist.java
@@ -0,0 +1,196 @@
+package de.hs_mannheim.pr2;
+
+import java.util.Comparator;
+import java.util.Random;
+
+/**
+ * Hello world!
+ */
+public class Skiplist {
+
+ Node head = null;
+ int size = 0;
+ int lvl = 1;
+ Comparator super T> comparator = null;
+ Random rng = new Random();
+
+ int cpr(T x, T y) {
+ return comparator != null ? comparator.compare(x, y) : ((Comparable)x).compareTo(y);
+ }
+
+ public Skiplist() {
+ comparator = null;
+ head = new Node(null, true);
+ }
+
+ public Skiplist(Comparator super T> comparator) {
+ this.comparator = comparator;
+ head = new Node(null, true);
+ }
+
+ public int size() {
+ return size;
+ }
+
+ public boolean empty() {
+ return size == 0;
+ }
+
+ private void insertAtLvl(int lvl, Node oldNode) {
+ Node newNode = new Node(oldNode.value);
+ newNode.down = oldNode;
+
+ if (this.lvl < lvl) {
+ throw new RuntimeException();
+ } else if (this.lvl == lvl) {
+ Node newHead = new Node(null, true);
+ newHead.down = this.head;
+ this.head = newHead;
+ this.lvl += 1;
+ }
+
+ if (rng.nextDouble() < 0.5) {
+ insertAtLvl(lvl + 1, newNode);
+ }
+
+ Node currentNode = this.head;
+ for (int i = 0; i < this.lvl - lvl - 1; i++) {
+ currentNode = currentNode.down;
+ }
+
+ while (true) {
+ if (currentNode.next == null || cpr(currentNode.next.value, newNode.value) > 0) {
+ newNode.next = currentNode.next;
+ currentNode.next = newNode;
+ return;
+ }
+ currentNode = currentNode.next;
+ }
+ }
+
+ public void add(T data) {
+ Node node = new Node(data);
+ Node currentNode = head;
+ int counter = 0;
+ while (true) {
+ if (currentNode.next == null || cpr(currentNode.next.value, data) > 0) {
+ if (currentNode.down == null) {
+ node.next = currentNode.next;
+ currentNode.next = node;
+ break;
+ } else {
+ currentNode = currentNode.down;
+ }
+ } else {
+ currentNode = currentNode.next;
+ }
+ counter++;
+ }
+ size += 1;
+ if (rng.nextDouble() < 0.5) {
+ insertAtLvl(1, node);
+ }
+ System.out.println("adding took " + counter + " steps");
+ }
+
+ private void removeUpper(int lvl, Node node) {
+ Node currentNode = this.head;
+ for (int i = 0; i < this.lvl - lvl - 1; i++) {
+ currentNode = currentNode.down;
+ }
+ while (currentNode.next != null) {
+ if (currentNode.next.down == node) {
+ removeUpper(lvl + 1, currentNode.next);
+ currentNode.next = currentNode.next.next;
+ return;
+ }
+ currentNode = currentNode.next;
+ }
+
+ }
+
+ public T pop() {
+ if (size == 0) {
+ return null;
+ }
+ Node head = this.head;
+ while (head.down != null) {
+ head = head.down;
+ }
+ removeUpper(1, head.next);
+ T result = head.next.value;
+ head.next = head.next.next;
+ size -= 1;
+ return result;
+ }
+
+ public T get(int location) {
+ if (location >= size) {
+ return null;
+ }
+ Node currentNode = head;
+ while (currentNode.down != null) {
+ currentNode = currentNode.down;
+ }
+ currentNode = currentNode.next;
+
+ for (int i = 0; i < location; i++) {
+ currentNode = currentNode.next;
+ }
+ return currentNode.value;
+ }
+
+ @Override
+ public String toString() {
+ Node currentHead = head;
+ StringBuilder result = new StringBuilder();
+ while (currentHead != null) {
+ Node currentNode = currentHead;
+ while (currentNode != null) {
+ result.append(currentNode);
+ currentNode = currentNode.next;
+ }
+ currentHead = currentHead.down;
+ result.append("\n");
+ }
+ return result.toString();
+ }
+
+ // @Override
+ // public String toString() {
+ // return head.toString();
+ // }
+
+ private class Node {
+ Node next = null;
+ Node down = null;
+ T value;
+ boolean dummy = false;
+
+ Node(T value) {
+ this.value = value;
+ }
+
+ Node(T value, Boolean dummy) {
+ this.dummy = true;
+ }
+
+ @Override
+ public String toString() {
+ // String result = "";
+ // if (this.down != null) {
+ // result += this.down.toString();
+ // result += " --v\n";
+ // }
+ // if (this.next != null) {
+ // result += this.next.toString();
+ // }
+ if (dummy) {
+ return "[dummy]";
+ } else {
+ return "[" + value + "]";
+ }
+ // return result;
+ }
+ }
+}
diff --git a/src/test/java/de/hs_mannheim/pr2/SkiplistTest.java b/src/test/java/de/hs_mannheim/pr2/SkiplistTest.java
new file mode 100644
index 0000000..5978e57
--- /dev/null
+++ b/src/test/java/de/hs_mannheim/pr2/SkiplistTest.java
@@ -0,0 +1,78 @@
+package de.hs_mannheim.pr2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit test for simple App.
+ */
+public class SkiplistTest {
+
+ /**
+ * Rigorous Test :-)
+ */
+ @Test
+ public void shouldAnswerWithTrue() {
+ assertTrue(true);
+ }
+
+ @Test
+ public void canPush() {
+ Skiplist list = new Skiplist();
+ list.add(1);
+ list.add(3);
+ list.add(2);
+ list.add(4);
+ list.add(10);
+ list.add(7);
+ list.add(8);
+ list.add(6);
+ list.add(3);
+ System.out.println(list);
+ assertEquals(9, list.size());
+ }
+
+ @Test
+ public void canPop() {
+ Skiplist list = new Skiplist();
+ list.add(1);
+ list.add(3);
+ list.add(2);
+ list.add(4);
+ list.add(10);
+ list.add(7);
+ list.add(8);
+ list.add(6);
+ list.add(3);
+ System.out.println(list);
+ assertEquals(1, list.pop().intValue());
+ System.out.println(list);
+ assertEquals(2, list.pop().intValue());
+ System.out.println(list);
+ assertEquals(3, list.pop().intValue());
+ System.out.println(list);
+ assertEquals(3, list.pop().intValue());
+ System.out.println(list);
+ assertEquals(4, list.pop().intValue());
+ System.out.println(list);
+ assertEquals(6, list.pop().intValue());
+ System.out.println(list);
+ assertTrue(list.size() == 3);
+ }
+
+ @Test
+ public void canGet() {
+ Skiplist list = new Skiplist();
+ list.add(1);
+ list.add(2);
+ list.add(3);
+ assertEquals(1, list.get(0).intValue());
+ assertEquals(2, list.get(1).intValue());
+ assertEquals(3, list.get(2).intValue());
+ assertEquals(null, list.get(3));
+ }
+
+
+}