From 3f35d9bbfe543dd053377c8db35bb74519763a0c Mon Sep 17 00:00:00 2001 From: M-H9 Date: Tue, 10 Dec 2024 18:12:08 +0100 Subject: [PATCH] Created my branch folder for the merge --- .../Mohammed_Implementations/IMPL_M_1.java | 302 ++++++++++++++++++ .../java/de/uni_marburg/powersort/App.java | 22 -- .../de/uni_marburg/powersort/PowerSort.java | 229 +------------ .../de/uni_marburg/powersort/AppTest.java | 14 - .../uni_marburg/powersort/PowerSortTest.java | 37 +++ 5 files changed, 342 insertions(+), 262 deletions(-) create mode 100644 app/src/main/java/Mohammed_Implementations/IMPL_M_1.java delete mode 100644 app/src/main/java/de/uni_marburg/powersort/App.java delete mode 100644 app/src/test/java/de/uni_marburg/powersort/AppTest.java create mode 100644 app/src/test/java/de/uni_marburg/powersort/PowerSortTest.java diff --git a/app/src/main/java/Mohammed_Implementations/IMPL_M_1.java b/app/src/main/java/Mohammed_Implementations/IMPL_M_1.java new file mode 100644 index 0000000..03c69d6 --- /dev/null +++ b/app/src/main/java/Mohammed_Implementations/IMPL_M_1.java @@ -0,0 +1,302 @@ +package Mohammed_Implementations; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.IntStream; + +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 + */ + private 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 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() list = new ArrayList<>(List.of(5, 2, 8, 12, 1, 6)); - extendRun(list, 0); - System.out.println(list); - } -} diff --git a/app/src/main/java/de/uni_marburg/powersort/PowerSort.java b/app/src/main/java/de/uni_marburg/powersort/PowerSort.java index 2152d71..39916ad 100644 --- a/app/src/main/java/de/uni_marburg/powersort/PowerSort.java +++ b/app/src/main/java/de/uni_marburg/powersort/PowerSort.java @@ -1,8 +1,6 @@ package de.uni_marburg.powersort; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.Comparator; class PowerSort { /** @@ -21,229 +19,8 @@ class PowerSort { * @param workLen usable size of work array * @since 1.8 */ - private static int MERGE_COST = 0; - - 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; -// ask question about this whether it should be double or int - int a = (int) ((i1 + n1 / 2.0) / n); - int b = (int) ((i2 + n2 / 2.0) / 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; -// is this right? - 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); - } - } - } - -// // Example usage -// public static void main(String[] args) { -// List list = new ArrayList<>(List.of(5, 2, 8, 12, 1, 6)); -// extendRun(list, 0); -// System.out.println(list); -// } - - - - /* static void sort(T[] a, int lo, int hi, Comparator c, + static void sort(T[] a, int lo, int hi, Comparator 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() 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