diff --git a/.idea/misc.xml b/.idea/misc.xml
index 511c874..122ba17 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,5 +3,5 @@
-
+
\ No newline at end of file
diff --git a/app/bin/main/de/uni_marburg/powersort/App.class b/app/bin/main/de/uni_marburg/powersort/App.class
new file mode 100644
index 0000000..2c43fac
Binary files /dev/null and b/app/bin/main/de/uni_marburg/powersort/App.class differ
diff --git a/app/bin/main/de/uni_marburg/powersort/ComparableTimSort.class b/app/bin/main/de/uni_marburg/powersort/ComparableTimSort.class
new file mode 100644
index 0000000..9f7d58f
Binary files /dev/null and b/app/bin/main/de/uni_marburg/powersort/ComparableTimSort.class differ
diff --git a/app/bin/main/de/uni_marburg/powersort/PowerSort.class b/app/bin/main/de/uni_marburg/powersort/PowerSort.class
new file mode 100644
index 0000000..d40d730
Binary files /dev/null and b/app/bin/main/de/uni_marburg/powersort/PowerSort.class differ
diff --git a/app/bin/main/de/uni_marburg/powersort/TimSort.class b/app/bin/main/de/uni_marburg/powersort/TimSort.class
new file mode 100644
index 0000000..fe86166
Binary files /dev/null and b/app/bin/main/de/uni_marburg/powersort/TimSort.class differ
diff --git a/app/bin/test/de/uni_marburg/powersort/AppTest.class b/app/bin/test/de/uni_marburg/powersort/AppTest.class
new file mode 100644
index 0000000..994ac66
Binary files /dev/null and b/app/bin/test/de/uni_marburg/powersort/AppTest.class differ
diff --git a/app/src/main/java/de/uni_marburg/powersort/msort/IMPL_M_1.java b/app/src/main/java/de/uni_marburg/powersort/msort/IMPL_M_1.java
new file mode 100644
index 0000000..0d0f25d
--- /dev/null
+++ b/app/src/main/java/de/uni_marburg/powersort/msort/IMPL_M_1.java
@@ -0,0 +1,298 @@
+package de.uni_marburg.powersort.msort;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.IntStream;
+
+public class IMPL_M_1 {
+
+
+
+ private IMPL_M_1() {}
+
+ /**
+ * Sorts the given range, using the given workspace array slice
+ * for temp storage when possible. This method is designed to be
+ * invoked from public methods (in class Arrays) after performing
+ * any necessary array bounds checks and expanding parameters into
+ * the required forms.
+ *
+ * @param a the array to be sorted
+ * @param lo the index of the first element, inclusive, to be sorted
+ * @param hi the index of the last element, exclusive, to be sorted
+ * @param c the comparator to use
+ * @param work a workspace array (slice)
+ * @param workBase origin of usable space in work array
+ * @param workLen usable size of work array
+ * @since 1.8
+ */
+ protected static int MERGE_COST = 0;
+
+ // Example usage
+// int[] runs = new int[] {5, 3, 3, 14, 1, 2}; // example from slides
+// //runs = new int[]{9, 16, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
+//
+// ArrayList a = new ArrayList<>(IntStream.range(0, Arrays.stream(runs).sum()).boxed().collect(Collectors.toList()));
+//
+// System.out.println();
+// fillWithAscRunsHighToLow(a, runs);
+// MERGE_COST = 0;
+// System.out.println("Sorting with Powersort:");
+// powersort(a, this::extendRunIncreasingOnly);
+// System.out.println("Merge cost: " + MERGE_COST);
+
+// runs = [5,3,3,14,1,2];
+// runs = [9,16,7,7,7,7,7,7,7,7,7,7];
+//
+// a = list(range(sum(runs)));
+// fill_with_asc_runs_high_to_low(a, runs);
+// MERGE_COST = 0;
+// System.out.println("Sorting with Powersort:");
+// powersort(a, extendRunIncreasingOnly);
+// System.out.println("Merge cost: " + MERGE_COST);
+
+
+ public static void fillWithAscRunsHighToLow(List A, int[] runLengths, int runLenFactor) {
+ int n = A.size();
+ assert IntStream.of(runLengths).sum() * runLenFactor == n;
+
+ for (int i = 0; i < n; i++) {
+ A.set(i, n - i);
+ }
+
+ int i = 0;
+ for (int l : runLengths) {
+ int L = l * runLenFactor;
+ List sublist = A.subList(i, i + L);
+ Collections.sort(sublist);
+ i += L;
+ }
+ }
+
+ private static List merge(List run1, List run2) {
+ List result = new ArrayList<>();
+ while (!run1.isEmpty() && !run2.isEmpty()) {
+ if (run1.get(0) < run2.get(0)) {
+ result.add(run1.remove(0));
+ } else {
+ result.add(run2.remove(0));
+ }
+ }
+ result.addAll(run1);
+ result.addAll(run2);
+ return result;
+ }
+
+ private static void mergeInplace(List a, int i, int m, int j) {
+ System.out.printf("Merge(%d, %d, %d)%n", i, m, j);
+ MERGE_COST += j - i;
+ List sublist = merge(
+ new ArrayList<>(a.subList(i, m)),
+ new ArrayList<>(a.subList(m, j))
+ );
+ for (int k = 0; k < sublist.size(); k++) {
+ a.set(i + k, sublist.get(k));
+ }
+ }
+
+ static int extendRun(List a, int i) {
+ if (i == a.size() - 1) {
+ return i + 1;
+ }
+ int j = i + 1;
+ if (a.get(i) <= a.get(j)) {
+ while (j < a.size() && a.get(j - 1) <= a.get(j)) {
+ j++;
+ }
+ } else {
+ while (j < a.size() && a.get(j - 1) > a.get(j)) {
+ j++;
+ }
+ List sublist = a.subList(i, j);
+ Collections.reverse(sublist);
+ }
+ return j;
+ }
+
+ private static int extendRunIncreasingOnly(List a, int i) {
+ if (i == a.size() - 1) {
+ return i + 1;
+ }
+ int j = i + 1;
+ while (j < a.size() && a.get(j - 1) <= a.get(j)) {
+ j++;
+ }
+ return j;
+ }
+
+ public static int power(int[] run1, int[] run2, int n) {
+ int i1 = run1[0], n1 = run1[1];
+ int i2 = run2[0], n2 = run2[1];
+
+ assert i1 >= 0;
+ assert i2 == i1 + n1;
+ assert n1 >= 1 && n2 >= 1;
+ assert i2 + n2 <= n;
+
+ double a = ((i1 + n1 / 2.0d) / n);
+ double b = ((i2 + n2 / 2.0d) / n);
+
+ int l = 0;
+ while (Math.floor(a * Math.pow(2, l)) == Math.floor(b * Math.pow(2, l))) {
+ l++;
+ }
+ return l;
+ }
+
+ public static int powerFast(int[] run1, int[] run2, int n) {
+ int i1 = run1[0], n1 = run1[1];
+ int i2 = run2[0], n2 = run2[1];
+
+ int a = 2 * i1 + n1;
+ int b = a + n1 + n2;
+
+ int l = 0;
+ while (true) {
+ l++;
+ if (a >= n) {
+ assert b >= a;
+ a -= n;
+ b -= n;
+ } else if (b >= n) {
+ break;
+ }
+ assert a < b && b < n;
+ a <<= 1;
+ b <<= 1;
+ }
+ return l;
+ }
+
+ public static void mergeTopmost2(List a, List runs) {
+ assert runs.size() >= 2;
+
+ int[] Y = runs.get(runs.size() - 2);
+ int[] Z = runs.get(runs.size() - 1);
+
+ assert Z[0] == Y[0] + Y[1];
+
+ mergeInplace(a, Y[0], Z[0], Z[0] + Z[1]);
+
+ runs.set(runs.size() - 2, new int[] {Y[0], Y[1] + Z[1], Y[2]});
+ runs.remove(runs.size() - 1);
+ }
+
+ public static void powerSort(List a) {
+ int n = a.size();
+ int i = 0;
+ List runs = new ArrayList<>();
+
+ int j = extendRun(a, i);
+ runs.add(new int[] {i, j - i, 0});
+ i = j;
+
+ while (i < n) {
+ j = extendRun(a, i);
+ int p = power(runs.get(runs.size() - 1), new int[] {i, j - i}, n);
+
+ while (p <= runs.get(runs.size() - 1)[2]) {
+ mergeTopmost2(a, runs);
+ }
+
+ runs.add(new int[] {i, j - i, p});
+ i = j;
+ }
+
+ while (runs.size() >= 2) {
+ mergeTopmost2(a, runs);
+ }
+ }
+
+ /* """Fills the given array A with ascending runs of the given list of run
+ lengths.
+ More precisely, the array is first filled n, n-1, ..., 1
+ and then for i=0..l-1 segments of runLengths.get(i) * runLenFactor
+ are sorted ascending.
+ The sum of all lengths in runLengths times runLenFactor should be equal to the
+ length of A.
+ """*/
+
+
+ /* static void sort(T[] a, int lo, int hi, Comparator super T> c,
+ T[] work, int workBase, int workLen) {
+ assert c != null && a != null && lo >= 0 && lo <= hi && hi <= a.length;
+ }*/
+/*
+ public static final int MIN_MERGE=24;
+ public int mergeCost=0;
+ private final T []sortedArray;
+
+ public PowerSort(T[] sortedArray) {
+ super();
+ this.sortedArray = sortedArray;
+ }
+
+ ArrayList run1 = new ArrayList<>();
+ ArrayList run2 = new ArrayList<>();
+
+ private AbstractList merge(ArrayList run1, ArrayList run2) {
+ ArrayList result = new ArrayList<>();
+
+ while(run1.size() > 0 && run2.size() >0) {
+ if (run1.getFirst() {
T[] work, int workBase, int workLen) {
assert c != null && a != null && lo >= 0 && lo <= hi && hi <= a.length;
}
-}
\ No newline at end of file
+}
diff --git a/app/src/test/java/de/uni_marburg/powersort/msort/PowerSortTest.java b/app/src/test/java/de/uni_marburg/powersort/msort/PowerSortTest.java
new file mode 100644
index 0000000..dc2bfa5
--- /dev/null
+++ b/app/src/test/java/de/uni_marburg/powersort/msort/PowerSortTest.java
@@ -0,0 +1,37 @@
+package de.uni_marburg.powersort.msort;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import org.junit.jupiter.api.Test;
+
+import static de.uni_marburg.powersort.msort.IMPL_M_1.MERGE_COST;
+import static de.uni_marburg.powersort.msort.IMPL_M_1.extendRun;
+import static de.uni_marburg.powersort.msort.IMPL_M_1.fillWithAscRunsHighToLow;
+import static de.uni_marburg.powersort.msort.IMPL_M_1.powerSort;
+
+class PowerSortTest {
+ @Test
+
+ public void testWithOneInputList() {
+ List list = new ArrayList<>(List.of(5, 2, 8, 12, 1, 6));
+ extendRun(list, 0);
+ System.out.println(list);
+ // example from slides he wrote this
+ int[] runs = {5, 3, 3, 14, 1, 2};
+ // runs = new int[]{9, 16, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
+
+ List a = new ArrayList<>(IntStream.range(0, Arrays.stream(runs).sum()).boxed().collect(Collectors.toList()));
+
+ System.out.println();
+ fillWithAscRunsHighToLow(a, runs, 1);
+ MERGE_COST = 0;
+ System.out.println("Sorting with Powersort:");
+ powerSort(a);
+ System.out.println("Merge cost: " + MERGE_COST);
+ }
+
+ }
\ No newline at end of file