From 6de2927cf64adcdc380d5992e194b1fc8b057a84 Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Tue, 22 Feb 2022 16:50:29 -0700 Subject: [PATCH 01/29] Add base color code functionality --- .../github/arrayv/main/ArrayVisualizer.java | 23 +++++- .../io/github/arrayv/utils/Highlights.java | 70 ++++++++++++++++++- .../github/arrayv/visuals/bars/BarGraph.java | 4 +- 3 files changed, 93 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java index de6b42c5..42e69bba 100644 --- a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java +++ b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java @@ -675,7 +675,7 @@ private void drawStats(Color textColor, boolean dropShadow) { int yPos = (int)(fontSelectionScale / 25.0 * 30); this.mainRender.setColor(textColor); - + int step = 0; statLoop: for (StatisticType statType : statsConfig) { // System.out.println(yPos); @@ -727,6 +727,25 @@ private void drawStats(Color textColor, boolean dropShadow) { stat = null; // Unreachable } mainRender.drawString(stat, xOffset, (int)(windowRatio * yPos) + yOffset); + if(step++ == 0 && Highlights.getDeclaredColors().length > 0) { + int startOffset = mainRender.getFontMetrics().stringWidth(stat) + xOffset + 24, + copy = startOffset, metricFontHeight = mainRender.getFontMetrics().getHeight(), + copyYPos = (int)(windowRatio * yPos) + yOffset, textWidth; + for(String color : Highlights.getDeclaredColors()) { + textWidth = mainRender.getFontMetrics().stringWidth(color); + if(startOffset + textWidth + metricFontHeight + 4 >= currentWidth() - 40) { + startOffset = copy; + copyYPos += metricFontHeight + 8; + } + if(!dropShadow) + mainRender.setColor(Highlights.getColorFromName(color)); + mainRender.fillRect(startOffset, copyYPos - metricFontHeight + (metricFontHeight / 3), metricFontHeight, metricFontHeight); + if(!dropShadow) + mainRender.setColor(textColor); + mainRender.drawString(color, startOffset + metricFontHeight + 6, copyYPos); + startOffset += textWidth + metricFontHeight + 12; + } + } yPos += fontSelectionScale; } } @@ -1289,6 +1308,8 @@ public String formatTimes() { public void endSort() { this.Timer.disableRealTimer(); this.Highlights.clearAllMarks(); + this.Highlights.clearAllColors(); + this.Highlights.clearColorList(); System.out.println(formatTimes()); this.isCanceled = false; diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index 0aba07b5..ce9ab763 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -1,9 +1,10 @@ package io.github.arrayv.utils; import java.util.Arrays; - +import java.awt.Color; import io.github.arrayv.main.ArrayVisualizer; import io.github.arrayv.panes.JErrorPane; +import java.util.HashMap; /* * @@ -34,6 +35,10 @@ of this software and associated documentation files (the "Software"), to deal public final class Highlights { private volatile int[] highlights; private volatile byte[] markCounts; + private volatile boolean[] colorMarks; + private volatile Color[] colorColors; + public volatile boolean retainColorMarks = true; + private volatile HashMap defined; private volatile int maxHighlightMarked; // IMPORTANT: This stores the index one past the farthest highlight used, so that a value // of 0 means no highlights are in use, and iteration is more convenient. @@ -65,8 +70,11 @@ public Highlights(ArrayVisualizer ArrayVisualizer, int maximumLength) { this.ArrayVisualizer = ArrayVisualizer; try { + defined = new HashMap<>(); this.highlights = new int[maximumLength]; this.markCounts = new byte[maximumLength]; + this.colorMarks = new boolean[maximumLength]; + this.colorColors = new Color[maximumLength]; } catch (OutOfMemoryError e) { JErrorPane.invokeCustomErrorMessage("Failed to allocate mark arrays. The program will now exit."); System.exit(1); @@ -149,6 +157,60 @@ public boolean containsPosition(int arrayPosition) { if (arrayPosition >= markCounts.length) return false; return this.markCounts[arrayPosition] != 0; } + public String[] getDeclaredColors() { + return defined.keySet().toArray(new String[0]); + } + public Color getColorFromName(String color) { + return defined.getOrDefault(color, Color.WHITE); + } + public synchronized void defineColor(String alias, Color col) { + defined.put(alias, col); + } + public synchronized void colorCode(int position, String color) { + try { + if (position < 0) { + throw new Exception("Highlights.colorCode(): Invalid position!"); + } else { + colorMarks[position] = true; + colorColors[position] = defined.getOrDefault(color, Color.WHITE); + } + } catch (Exception e) { + e.printStackTrace(); + } + ArrayVisualizer.updateNow(); + } + public synchronized void colorCode(String color, int... positions) { + for(int i : positions) { + colorCode(i, color); + } + } + public synchronized void clearColorList() { + defined.clear(); + retainColorMarks = false; + } + public synchronized void clearColor(int position) { + if(colorMarks[position]) { + colorMarks[position] = false; + colorColors[position] = null; + } + } + public synchronized boolean hasColor(int position) { + return colorMarks[position]; + } + public synchronized Color colorAt(int position) { + return colorColors[position]; + } + public synchronized void clearAllColors() { + Arrays.fill(colorMarks, false); // dirty way + } + public void swapColors(int locA, int locB) { + boolean t0 = colorMarks[locA]; + Color t1 = colorColors[locA]; + colorMarks[locA] = colorMarks[locB]; + colorMarks[locB] = t0; + colorColors[locA] = colorColors[locB]; + colorColors[locB] = t1; + } public synchronized void markArray(int marker, int markPosition) { try { if (markPosition < 0) { @@ -162,6 +224,9 @@ public synchronized void markArray(int marker, int markPosition) { if (highlights[marker] != -1) { decrementIndexMarkCount(highlights[marker]); } + if(!retainColorMarks) { + colorMarks[markPosition] = false; + } highlights[marker] = markPosition; incrementIndexMarkCount(markPosition); @@ -178,9 +243,10 @@ public synchronized void clearMark(int marker) { if (highlights[marker] == -1) { return; } + if(!retainColorMarks) + clearColor(highlights[marker]); decrementIndexMarkCount(highlights[marker]); highlights[marker] = -1; // -1 is used as the magic number to unmark a position in the main array - if (marker == this.maxHighlightMarked) { this.maxHighlightMarked = marker; while (maxHighlightMarked > 0 && highlights[maxHighlightMarked-1] == -1) { diff --git a/src/main/java/io/github/arrayv/visuals/bars/BarGraph.java b/src/main/java/io/github/arrayv/visuals/bars/BarGraph.java index 4ba5a169..1ad7d1a4 100644 --- a/src/main/java/io/github/arrayv/visuals/bars/BarGraph.java +++ b/src/main/java/io/github/arrayv/visuals/bars/BarGraph.java @@ -25,7 +25,9 @@ else if (ArrayVisualizer.colorEnabled()) { int val = ArrayVisualizer.doingStabilityCheck() && ArrayVisualizer.colorEnabled() ? ArrayVisualizer.getIndexValue(array[i]): array[i]; this.mainRender.setColor(getIntColor(val, ArrayVisualizer.getCurrentLength())); } - else this.mainRender.setColor(Color.WHITE); + else if(Highlights.hasColor(i)) { + this.mainRender.setColor(Highlights.colorAt(i)); + } else this.mainRender.setColor(Color.WHITE); int val = ArrayVisualizer.doingStabilityCheck() && ArrayVisualizer.colorEnabled() ? ArrayVisualizer.getStabilityValue(array[i]): array[i]; int y = (int) (((Renderer.getViewSize() - 20)) - (val + 1) * Renderer.getYScale()); From 6ee885b9553de86dc22ffa6efec9ca76bbf82ca7 Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Tue, 22 Feb 2022 17:02:44 -0700 Subject: [PATCH 02/29] Right-align color legend --- src/main/java/io/github/arrayv/main/ArrayVisualizer.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java index 42e69bba..45211016 100644 --- a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java +++ b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java @@ -728,13 +728,15 @@ private void drawStats(Color textColor, boolean dropShadow) { } mainRender.drawString(stat, xOffset, (int)(windowRatio * yPos) + yOffset); if(step++ == 0 && Highlights.getDeclaredColors().length > 0) { - int startOffset = mainRender.getFontMetrics().stringWidth(stat) + xOffset + 24, + int startOffset = currentWidth(), copy = startOffset, metricFontHeight = mainRender.getFontMetrics().getHeight(), + startStat = mainRender.getFontMetrics().stringWidth(stat) + xOffset + 24, copyYPos = (int)(windowRatio * yPos) + yOffset, textWidth; for(String color : Highlights.getDeclaredColors()) { textWidth = mainRender.getFontMetrics().stringWidth(color); - if(startOffset + textWidth + metricFontHeight + 4 >= currentWidth() - 40) { - startOffset = copy; + startOffset -= textWidth + metricFontHeight + 12; + if(startOffset >= startStat) { + startOffset = copy - textWidth - metricFontHeight - 12; copyYPos += metricFontHeight + 8; } if(!dropShadow) @@ -743,7 +745,6 @@ private void drawStats(Color textColor, boolean dropShadow) { if(!dropShadow) mainRender.setColor(textColor); mainRender.drawString(color, startOffset + metricFontHeight + 6, copyYPos); - startOffset += textWidth + metricFontHeight + 12; } } yPos += fontSelectionScale; From 66af7527fe14f8e6535a6abe1b616d47a4e4d64d Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Thu, 24 Feb 2022 14:26:58 -0700 Subject: [PATCH 03/29] Color-code some sorts --- .../sorts/merge/BlockSwapMergeSort.java | 13 +- .../arrayv/sorts/merge/RotateMergeSort.java | 13 +- .../github/arrayv/sorts/select/CycleSort.java | 15 +- .../arrayv/sorts/select/ExpliciumSort.java | 133 +++++++++++ .../arrayv/sorts/templates/GrailSorting.java | 219 ++++++++++++------ 5 files changed, 317 insertions(+), 76 deletions(-) create mode 100644 src/main/java/io/github/arrayv/sorts/select/ExpliciumSort.java diff --git a/src/main/java/io/github/arrayv/sorts/merge/BlockSwapMergeSort.java b/src/main/java/io/github/arrayv/sorts/merge/BlockSwapMergeSort.java index dcba6a75..024f78f1 100644 --- a/src/main/java/io/github/arrayv/sorts/merge/BlockSwapMergeSort.java +++ b/src/main/java/io/github/arrayv/sorts/merge/BlockSwapMergeSort.java @@ -1,5 +1,7 @@ package io.github.arrayv.sorts.merge; +import java.awt.Color; + import io.github.arrayv.main.ArrayVisualizer; import io.github.arrayv.sorts.templates.Sort; @@ -46,14 +48,20 @@ public BlockSwapMergeSort(ArrayVisualizer arrayVisualizer) { } private void multiSwap(int[] array, int a, int b, int len) { - for(int i = 0; i < len; i++) + for(int i = 0; i < len; i++) { + Highlights.colorCode("blockswap", a+i, b+i); Writes.swap(array, a+i, b+i, 1, true, false); + } } private int binarySearchMid(int[] array, int start, int mid, int end) { int a = 0, b = Math.min(mid-start, end-mid), m = a+(b-a)/2; while(b > a) { + Highlights.colorCode("double_binsearch", mid-m-1, mid+m); + Highlights.markArray(1, mid-m-1); + Highlights.markArray(2, mid+m); + Delays.sleep(2.5); if(Reads.compareValues(array[mid-m-1], array[mid+m]) == 1) a = m+1; else @@ -80,6 +88,9 @@ public void multiSwapMerge(int[] array, int start, int mid, int end) { } public void multiSwapMergeSort(int[] array, int a, int b) { + Highlights.retainColorMarks = true; + Highlights.defineColor("double_binsearch", new Color(128, 0, 255)); + Highlights.defineColor("blockswap", Color.ORANGE); int len = b-a, i; for(int j = 1; j < len; j *= 2) { diff --git a/src/main/java/io/github/arrayv/sorts/merge/RotateMergeSort.java b/src/main/java/io/github/arrayv/sorts/merge/RotateMergeSort.java index 5cf587c5..e476fb3f 100644 --- a/src/main/java/io/github/arrayv/sorts/merge/RotateMergeSort.java +++ b/src/main/java/io/github/arrayv/sorts/merge/RotateMergeSort.java @@ -1,5 +1,7 @@ package io.github.arrayv.sorts.merge; +import java.awt.Color; + import io.github.arrayv.main.ArrayVisualizer; import io.github.arrayv.sorts.templates.Sort; @@ -45,8 +47,10 @@ public RotateMergeSort(ArrayVisualizer arrayVisualizer) { } private void multiSwap(int[] array, int a, int b, int len) { - for(int i = 0; i < len; i++) + for(int i = 0; i < len; i++) { + Highlights.colorCode("rotate", a+i, b+i); Writes.swap(array, a+i, b+i, 1, true, false); + } } private void rotate(int[] array, int a, int m, int b) { @@ -71,7 +75,9 @@ private void rotate(int[] array, int a, int m, int b) { private int binarySearch(int[] array, int a, int b, int value, boolean left) { while(a < b) { int m = a+(b-a)/2; - + Highlights.colorCode(m, "binsearch"); + Highlights.markArray(1, m); + Delays.sleep(2.5); boolean comp = left ? Reads.compareValues(value, array[m]) <= 0 : Reads.compareValues(value, array[m]) < 0; @@ -102,6 +108,9 @@ private void rotateMerge(int[] array, int a, int m, int b) { } protected void rotateMergeSort(int[] array, int a, int b) { + Highlights.retainColorMarks = true; + Highlights.defineColor("binsearch", Color.CYAN); + Highlights.defineColor("rotate", Color.ORANGE); int len = b-a, i; for(int j = 1; j < len; j *= 2) { diff --git a/src/main/java/io/github/arrayv/sorts/select/CycleSort.java b/src/main/java/io/github/arrayv/sorts/select/CycleSort.java index 930b93c3..72941708 100644 --- a/src/main/java/io/github/arrayv/sorts/select/CycleSort.java +++ b/src/main/java/io/github/arrayv/sorts/select/CycleSort.java @@ -1,5 +1,7 @@ package io.github.arrayv.sorts.select; +import java.awt.Color; + import io.github.arrayv.main.ArrayVisualizer; import io.github.arrayv.sorts.templates.Sort; @@ -51,8 +53,11 @@ private int countLesser(int[] array, int a, int b, int t) { Highlights.markArray(1, r); Highlights.markArray(2, i); Delays.sleep(0.01); - - r += Reads.compareValues(array[i], t) < 0 ? 1 : 0; + int cmp = Reads.compareIndexValue(array, i, t, 0.05, true) < 0 ? 1 : 0; + if(cmp == 1) { + Highlights.colorCode(i, "lower_rank"); + } + r += cmp; } Highlights.clearMark(2); return r; @@ -60,6 +65,7 @@ private int countLesser(int[] array, int a, int b, int t) { @Override public void runSort(int[] array, int length, int bucketCount) { + Highlights.defineColor("lower_rank", Color.GREEN); for(int i = 0; i < length-1; i++) { Highlights.markArray(3, i); @@ -72,11 +78,14 @@ public void runSort(int[] array, int length, int bucketCount) { int t1 = array[r]; Writes.write(array, r, t, 0.02, false, false); + + Highlights.clearAllColors(); t = t1; - + r = this.countLesser(array, i, length, t); } while(r != i); + Highlights.clearAllColors(); Writes.write(array, i, t, 0.02, false, false); } diff --git a/src/main/java/io/github/arrayv/sorts/select/ExpliciumSort.java b/src/main/java/io/github/arrayv/sorts/select/ExpliciumSort.java new file mode 100644 index 00000000..712a0d4f --- /dev/null +++ b/src/main/java/io/github/arrayv/sorts/select/ExpliciumSort.java @@ -0,0 +1,133 @@ +package io.github.arrayv.sorts.select; + +import java.awt.Color; +import java.util.Arrays; + +import io.github.arrayv.main.ArrayVisualizer; +import io.github.arrayv.sorts.templates.Sort; + + +final public class ExpliciumSort extends Sort { + public ExpliciumSort(ArrayVisualizer arrayVisualizer) { + super(arrayVisualizer); + + this.setSortListName("Explicium"); + this.setRunAllSortsName("Explicium Sort"); + this.setRunSortName("Expliciumsort"); + this.setCategory("Selection Sorts"); + this.setBucketSort(false); + this.setRadixSort(false); + this.setUnreasonablySlow(false); + this.setUnreasonableLimit(0); + this.setBogoSort(false); + } + + // Expliciumsort: A variant of Classic Tournament Sort that runs faster. + // *Made by Distray* + + private void make(int[] array, int[] tree, int start, int end, int index) { + if(end <= start) { + Highlights.markArray(1, start); + Writes.write(tree, index, start, 1, true, true); + return; + } + int next = 2*index+1, // Location of left child in implicit binary tree, + mid = start + (end - start) / 2; // and the middle number. + + make(array, tree, start, mid, next); // Build the two children. + make(array, tree, mid+1, end, next+1); + + // Get the winning child, and set the parent index to that value. + if(Reads.compareIndices(array, tree[next], tree[next+1], 0.5, true) <= 0) { + Writes.write(tree, index, tree[next], 1, true, true); + } else { + Writes.write(tree, index, tree[next+1], 1, true, true); + } + // Colorcode the winner using "build". + Highlights.colorCode(tree[index], "build"); + } + private void makeTree(int[] array, int[] tree, int start, int end) { + make(array, tree, start, end, 0); // wrapper function + } + private void removeWinner(int[] array, int[] tree) { + int now = 0, neg; + int l = (tree.length - 1) / 2; + // Note: We can't take Classic Tournament's approach at finding the winner value, + // because this sort doesn't handle trees exactly like Classic Tournament does. + while(now < l) { + // Negation value to skip past empty children + neg = (2*(tree[2*now+1] >> 31)) + (tree[2*now+2] >> 31); + if(neg < 0) { + if(neg == -3) // -3 is the special number that indicates that we should stop. + break; + // When the left child is empty, this gives us the index for the right child, + // and when the right child is empty, it gives the index for the left child. + now = 2*now-neg; + } else if(tree[now] == tree[2*now+1]) { + // Traverse the child that it pulled the winner from. + now = 2*now+1; + } else { + now = 2*now+2; + } + } + Highlights.colorCode(tree[now], "eliminate"); // Mark the winner as eliminated, + Writes.write(tree, now, -1, 1, true, true); // snap the winner out of existence, + while(now > 0) { + now = (now - 1) / 2; // go up a level, + neg = (2*(tree[2*now+1] >> 31)) + (tree[2*now+2] >> 31); // get the negation value, + if(neg < 0) { // and check. + if(neg == -3) { // -3 in the rebuilding stage is the special number that deletes the parent. + Writes.write(tree, now, -1, 1, true, true); + continue; + } else // And just like before, this gives the non-empty child whenever used. + Writes.write(tree, now, tree[2*now-neg], 1, true, true); + } else if(Reads.compareIndices(array, tree[2*now+1], tree[2*now+2], 0.5, true) <= 0) { + // Rebuild the tree with the lower child of the two, if both are non-empty. + Writes.write(tree, now, tree[2*now+1], 1, true, true); + } else { + Writes.write(tree, now, tree[2*now+2], 1, true, true); + } + // Colorcode the winning child with the rebuild alias. + Highlights.colorCode(tree[now], "rebuild"); + } + } + public void Explic(int[] array, int start, int end) { + int treeLen = 2*(end-start)-1; + + // Convert the tree length into a 2^x-1 number. + treeLen |= treeLen>>1; + treeLen |= treeLen>>2; + treeLen |= treeLen>>4; + treeLen |= treeLen>>8; + treeLen |= treeLen>>16; + + // Define the colors we'll be using. + Highlights.retainColorMarks = true; + Highlights.defineColor("build", new Color(0, 192, 192)); + Highlights.defineColor("eliminate", Color.DARK_GRAY); + Highlights.defineColor("rebuild", Color.BLUE); + + int[] tree = Writes.createExternalArray(treeLen), // Tree of indices + out = Writes.createExternalArray(end-start); // Sorted result + Arrays.fill(tree, -1); + Writes.changeAuxWrites(treeLen); + makeTree(array, tree, start, end-1); + int t = 0; + while(true) { + // Push the winner value stored in the root of the tree to the output. + Writes.write(out, t++, array[tree[0]], 1, true, true); + if(t < end-start) // Remove the winner and rebuild the tree. + removeWinner(array, tree); + else + break; + } + // Put the sorted output back into the main array, and wipe the elimination colors off in the process. + Highlights.retainColorMarks = false; + Writes.arraycopy(out, 0, array, start, end-start, 1, true, false); + Writes.deleteExternalArrays(out, tree); + } + @Override + public void runSort(int[] array, int length, int bucketCount) { + Explic(array, 0, length); + } +} \ No newline at end of file diff --git a/src/main/java/io/github/arrayv/sorts/templates/GrailSorting.java b/src/main/java/io/github/arrayv/sorts/templates/GrailSorting.java index b0e1e805..3a001258 100644 --- a/src/main/java/io/github/arrayv/sorts/templates/GrailSorting.java +++ b/src/main/java/io/github/arrayv/sorts/templates/GrailSorting.java @@ -1,5 +1,7 @@ package io.github.arrayv.sorts.templates; +import java.awt.Color; + import io.github.arrayv.main.ArrayVisualizer; import io.github.arrayv.sorts.exchange.OptimizedGnomeSort; @@ -67,37 +69,46 @@ protected int getLeftOverFrag() { public abstract class GrailSorting extends Sort { private OptimizedGnomeSort grailInsertSorter; - + final private int grailStaticBufferLen = 32; //Buffer length changed due to less numbers in this program being sorted than what Mr. Astrelin used for testing. - + protected GrailSorting(ArrayVisualizer arrayVisualizer) { super(arrayVisualizer); } - - protected int getStaticBuffer() { + + public int getStaticBuffer() { return this.grailStaticBufferLen; } - + private void grailSwap(int[] arr, int a, int b) { Writes.swap(arr, a, b, 1, true, false); } - - private void grailMultiSwap(int[] arr, int a, int b, int swapsLeft) { + + private void grailMultiSwapCS(int[] arr, int a, int b, int swapsLeft, String usage) { while(swapsLeft != 0) { + Highlights.colorCode(usage, a, b); this.grailSwap(arr, a++, b++); swapsLeft--; } } - + + private void grailMultiSwapCSCC(int[] arr, int a, int b, int swapsLeft) { + while(swapsLeft != 0) { + Highlights.swapColors(a, b); + this.grailSwap(arr, a++, b++); + swapsLeft--; + } + } + protected void grailRotate(int[] array, int pos, int lenA, int lenB) { - while(lenA != 0 && lenB != 0) { + while(lenA != 0 && lenB != 0) { if(lenA <= lenB) { - this.grailMultiSwap(array, pos, pos + lenA, lenA); + this.grailMultiSwapCS(array, pos, pos + lenA, lenA, "rotate"); pos += lenA; lenB -= lenA; - } + } else { - this.grailMultiSwap(array, pos + (lenA - lenB), pos + lenA, lenB); + this.grailMultiSwapCS(array, pos + (lenA - lenB), pos + lenA, lenB, "rotate"); lenA -= lenB; } } @@ -108,10 +119,11 @@ private void grailInsertSort(int[] arr, int pos, int len) { } //boolean argument determines direction - private int grailBinSearch(int[] arr, int pos, int len, int keyPos, boolean isLeft) { + protected int grailBinSearch(int[] arr, int pos, int len, int keyPos, boolean isLeft) { int left = -1, right = len; while(left < right - 1) { int mid = left + ((right - left) >> 1); + Highlights.colorCode("binsearch", pos + mid); if(isLeft) { if(Reads.compareValues(arr[pos + mid], arr[keyPos]) >= 0) { right = mid; @@ -128,17 +140,37 @@ private int grailBinSearch(int[] arr, int pos, int len, int keyPos, boolean isLe return right; } + //boolean argument determines direction + protected int grailBinSearchExc(int[] arr, int pos, int len, int keyPos) { + int left = -1, right = len; + while(left < right - 1) { + int mid = left + ((right - left) >> 1); + switch(Reads.compareValues(arr[pos + mid], arr[keyPos])) { + case 1: + right = mid; + break; + case 0: + return -1; + case -1: + left = mid; + break; + } + Highlights.markArray(1, pos + mid); + } + return right; + } + // cost: 2 * len + numKeys^2 / 2 - private int grailFindKeys(int[] arr, int pos, int len, int numKeys) { + public int grailFindKeys(int[] arr, int pos, int len, int numKeys) { int dist = 1, foundKeys = 1, firstKey = 0; // first key is always here while(dist < len && foundKeys < numKeys) { if(dist < (len - 1)) Highlights.markArray(3, dist + 1); Delays.sleep(1); - + //Binary Search left - int loc = this.grailBinSearch(arr, pos + firstKey, foundKeys, pos + dist, true); - if(loc == foundKeys || Reads.compareValues(arr[pos + dist], arr[pos + (firstKey + loc)]) != 0) { + int loc = this.grailBinSearchExc(arr, pos + firstKey, foundKeys, pos + dist); + if(loc >= 0 || loc == foundKeys) { this.grailRotate(arr, pos + firstKey, foundKeys, dist - (firstKey + foundKeys)); firstKey = dist - foundKeys; this.grailRotate(arr, pos + (firstKey + loc), foundKeys - loc, 1); @@ -147,19 +179,19 @@ private int grailFindKeys(int[] arr, int pos, int len, int numKeys) { else { Highlights.clearMark(2); } - + dist++; } Highlights.clearMark(3); this.grailRotate(arr, pos, firstKey, foundKeys); - + Highlights.clearMark(2); - + return foundKeys; } // cost: min(len1, len2)^2 + max(len1, len2) - protected void grailMergeWithoutBuffer(int[] arr, int pos, int len1, int len2) { + public void grailMergeWithoutBuffer(int[] arr, int pos, int len1, int len2) { if(len1 < len2) { while(len1 != 0) { //Binary Search left @@ -197,8 +229,8 @@ protected void grailMergeWithoutBuffer(int[] arr, int pos, int len1, int len2) { // aBlockCount are regular blocks from stream A. // lastLen is length of last (irregular) block from stream B, that should go before nblock2 blocks. // lastLen = 0 requires aBlockCount = 0 (no irregular blocks). lastLen > 0, aBlockCount = 0 is possible. - private void grailMergeBuffersLeft(int[] arr, int keysPos, int midkey, int pos, - int blockCount, int blockLen, boolean havebuf, int aBlockCount, + private void grailMergeBuffersLeft(int[] arr, int keysPos, int midkey, int pos, + int blockCount, int blockLen, boolean havebuf, int aBlockCount, int lastLen) { if(blockCount == 0) { @@ -216,9 +248,9 @@ private void grailMergeBuffersLeft(int[] arr, int keysPos, int midkey, int pos, for(int keyIndex = 1; keyIndex < blockCount; keyIndex++, processIndex += blockLen) { restToProcess = processIndex - leftOverLen; int nextFrag = Reads.compareValues(arr[keysPos + keyIndex], arr[midkey]) < 0 ? 0 : 1; - + if(nextFrag == leftOverFrag) { - if(havebuf) this.grailMultiSwap(arr, pos + restToProcess - blockLen, pos + restToProcess, leftOverLen); + if(havebuf) this.grailMultiSwapCS(arr, pos + restToProcess - blockLen, pos + restToProcess, leftOverLen, "fragment"); restToProcess = processIndex; leftOverLen = blockLen; } else { @@ -238,7 +270,7 @@ private void grailMergeBuffersLeft(int[] arr, int keysPos, int midkey, int pos, if(lastLen != 0) { if(leftOverFrag != 0) { if(havebuf) { - this.grailMultiSwap(arr, pos + restToProcess - blockLen, pos + restToProcess, leftOverLen); + this.grailMultiSwapCS(arr, pos + restToProcess - blockLen, pos + restToProcess, leftOverLen, "fragment"); } restToProcess = processIndex; leftOverLen = blockLen * aBlockCount; @@ -254,11 +286,11 @@ private void grailMergeBuffersLeft(int[] arr, int keysPos, int midkey, int pos, } } else { if(havebuf) { - this.grailMultiSwap(arr, pos + restToProcess, pos + (restToProcess - blockLen), leftOverLen); + this.grailMultiSwapCS(arr, pos + restToProcess, pos + (restToProcess - blockLen), leftOverLen, "fragment"); } } } - + // arr[dist..-1] - buffer, arr[0, leftLen - 1] ++ arr[leftLen, leftLen + rightLen - 1] // -> arr[dist, dist + leftLen + rightLen - 1] private void grailMergeLeft(int[] arr, int pos, int leftLen, int rightLen, int dist) { @@ -268,17 +300,25 @@ private void grailMergeLeft(int[] arr, int pos, int leftLen, int rightLen, int d rightLen += leftLen; while(right < rightLen) { + Highlights.colorCode(pos + dist, "leftmerge"); if(left == leftLen || Reads.compareValues(arr[pos + left], arr[pos + right]) > 0) { + Highlights.colorCode(pos + right, "buffer"); this.grailSwap(arr, pos + (dist++), pos + (right++)); + } else { + Highlights.colorCode(pos + left, "buffer"); + this.grailSwap(arr, pos + (dist++), pos + (left++)); } - else this.grailSwap(arr, pos + (dist++), pos + (left++)); Highlights.markArray(3, pos + left); Highlights.markArray(4, pos + right); } Highlights.clearMark(3); Highlights.clearMark(4); - - if(dist != left) this.grailMultiSwap(arr, pos + dist, pos + left, leftLen - left); + + if(dist != left) { + this.grailMultiSwapCS(arr, pos + dist, pos + left, leftLen - left, "leftmerge"); + for(int i=0; i= 0) { + Highlights.colorCode(pos + mergedPos, "rightmerge"); if(right < leftLen || Reads.compareValues(arr[pos + left], arr[pos + right]) > 0) { + Highlights.colorCode(pos + left, "buffer"); this.grailSwap(arr, pos + (mergedPos--), pos + (left--)); + } else { + Highlights.colorCode(pos + right, "buffer"); + this.grailSwap(arr, pos + (mergedPos--), pos + (right--)); } - else this.grailSwap(arr, pos + (mergedPos--), pos + (right--)); if(pos + left >= 0) Highlights.markArray(3, pos + left); Highlights.markArray(4, pos + right); } Highlights.clearMark(3); Highlights.clearMark(4); - + if(right != mergedPos) { - while(right >= leftLen) this.grailSwap(arr, pos + (mergedPos--), pos + (right--)); + while(right >= leftLen) { + Highlights.colorCode(pos + mergedPos, "rightmerge"); + Highlights.colorCode(pos + right, "buffer"); + this.grailSwap(arr, pos + (mergedPos--), pos + (right--)); + } } } @@ -316,7 +364,7 @@ private GrailPair grailSmartMergeWithoutBuffer(int[] arr, int pos, int leftOverL if (typeFrag != 0) { //Binary Search left foundLen = this.grailBinSearch(arr, pos + len1, len2, pos, true); - } else { + } else { //Binary Search right foundLen = this.grailBinSearch(arr, pos + len1, len2, pos, false); } @@ -343,20 +391,28 @@ private GrailPair grailSmartMergeWithBuffer(int[] arr, int pos, int leftOverLen, int typeFrag = 1 - leftOverFrag; // 1 if inverted while(left < leftEnd && right < rightEnd) { + Highlights.colorCode(pos + dist, "smartmerge"); if(Reads.compareValues(arr[pos + left], arr[pos + right]) - typeFrag < 0) { + Highlights.colorCode(pos + left, "buffer"); this.grailSwap(arr, pos + (dist++), pos + (left++)); + } else { + Highlights.colorCode(pos + right, "buffer"); + this.grailSwap(arr, pos + (dist++), pos + (right++)); } - else this.grailSwap(arr, pos + (dist++), pos + (right++)); Highlights.markArray(3, pos + left); Highlights.markArray(4, pos + right); } Highlights.clearMark(3); Highlights.clearMark(4); - + int length, fragment = leftOverFrag; if(left < leftEnd) { length = leftEnd - left; - while(left < leftEnd) this.grailSwap(arr, pos + (--leftEnd), pos + (--rightEnd)); + while(left < leftEnd) { + Highlights.colorCode(pos + (--leftEnd), "buffer"); + Highlights.colorCode(pos + (--rightEnd), "bufferrewind"); + this.grailSwap(arr, pos + leftEnd, pos + rightEnd); + } } else { length = rightEnd - right; fragment = typeFrag; @@ -371,9 +427,9 @@ private GrailPair grailSmartMergeWithBuffer(int[] arr, int pos, int leftOverLen, private GrailPair grailSmartMergeWithXBuf(int[] arr, int pos, int leftOverLen, int leftOverFrag, int blockLen) { int dist = 0 - blockLen, left = 0, right = leftOverLen, leftEnd = right, rightEnd = right + blockLen; int typeFrag = 1 - leftOverFrag; // 1 if inverted - + Highlights.clearMark(2); - + while(left < leftEnd && right < rightEnd) { if(Reads.compareValues(arr[pos + left], arr[pos + right]) - typeFrag < 0) { Writes.write(arr, pos + dist++, arr[pos + left++], 1, true, false); @@ -384,7 +440,7 @@ private GrailPair grailSmartMergeWithXBuf(int[] arr, int pos, int leftOverLen, i } Highlights.clearMark(2); Highlights.clearMark(3); - + int length, fragment = leftOverFrag; if(left < leftEnd) { length = leftEnd - left; @@ -404,7 +460,7 @@ private void grailMergeLeftWithXBuf(int[] arr, int pos, int leftEnd, int rightEn rightEnd += leftEnd; Highlights.clearMark(2); - + while(right < rightEnd) { if(left == leftEnd || Reads.compareValues(arr[pos + left], arr[pos + right]) > 0) { Writes.write(arr, pos + dist++, arr[pos + right++], 1, true, false); @@ -415,7 +471,7 @@ private void grailMergeLeftWithXBuf(int[] arr, int pos, int leftEnd, int rightEn } Highlights.clearMark(2); Highlights.clearMark(3); - + if(dist != left) { while(left < leftEnd) Writes.write(arr, pos + dist++, arr[pos + left++], 1, true, false); } @@ -431,7 +487,7 @@ private void grailMergeBuffersLeftWithXBuf(int[] arr, int keysPos, int midkey, i int blockCount, int regBlockLen, int aBlockCount, int lastLen) { Highlights.clearMark(2); - + if(blockCount == 0) { int aBlocksLen = aBlockCount * regBlockLen; this.grailMergeLeftWithXBuf(arr, pos, aBlocksLen, lastLen, 0 - regBlockLen); @@ -449,12 +505,12 @@ private void grailMergeBuffersLeftWithXBuf(int[] arr, int keysPos, int midkey, i if(nextFrag == leftOverFrag) { Writes.arraycopy(arr, pos + restToProcess, arr, pos + restToProcess - regBlockLen, leftOverLen, 1, true, false); - + restToProcess = processIndex; leftOverLen = regBlockLen; } else { GrailPair results = this.grailSmartMergeWithXBuf(arr, pos + restToProcess, leftOverLen, leftOverFrag, regBlockLen); - leftOverLen = results.getLeftOverLen(); + leftOverLen = results.getLeftOverLen(); leftOverFrag = results.getLeftOverFrag(); } } @@ -463,7 +519,7 @@ private void grailMergeBuffersLeftWithXBuf(int[] arr, int keysPos, int midkey, i if(lastLen != 0) { if(leftOverFrag != 0) { Writes.arraycopy(arr, pos + restToProcess, arr, pos + restToProcess - regBlockLen, leftOverLen, 1, true, false); - + restToProcess = processIndex; leftOverLen = regBlockLen * aBlockCount; leftOverFrag = 0; @@ -481,7 +537,7 @@ private void grailMergeBuffersLeftWithXBuf(int[] arr, int keysPos, int midkey, i // build blocks of length buildLen // input: [-buildLen, -1] elements are buffer // output: first buildLen elements are buffer, blocks 2 * buildLen and last subblock sorted - private void grailBuildBlocks(int[] arr, int pos, int len, int buildLen, + private void grailBuildBlocks(int[] arr, int pos, int len, int buildLen, int[] extbuf, int bufferPos, int extBufLen) { int buildBuf = buildLen < extBufLen ? buildLen : extBufLen; @@ -490,7 +546,7 @@ private void grailBuildBlocks(int[] arr, int pos, int len, int buildLen, int extraDist, part; if(buildBuf != 0) { Writes.arraycopy(arr, pos - buildBuf, extbuf, bufferPos, buildBuf, 1, true, true); - + for(int dist = 1; dist < len; dist += 2) { extraDist = 0; if(Reads.compareValues(arr[pos + (dist - 1)], arr[pos + dist]) > 0) extraDist = 1; @@ -515,17 +571,23 @@ private void grailBuildBlocks(int[] arr, int pos, int len, int buildLen, for(; left < len; left++) Writes.write(arr, pos + left - part, arr[pos + left], 1, true, false); } pos -= part; - } + } Writes.arraycopy(extbuf, bufferPos, arr, pos + len, buildBuf, 1, true, false); - } + } else { for(int dist = 1; dist < len; dist += 2) { extraDist = 0; if(Reads.compareValues(arr[pos + (dist - 1)], arr[pos + dist]) > 0) extraDist = 1; + Highlights.colorCode("pairing", pos+(dist-3), pos+(dist-2)); + Highlights.colorCode("buffer", pos+(dist-1), pos+dist); this.grailSwap(arr, pos + (dist - 3), pos + (dist - 1 + extraDist)); this.grailSwap(arr, pos + (dist - 2), pos + (dist - extraDist)); } - if(len % 2 != 0) this.grailSwap(arr, pos + (len - 1), pos + (len - 3)); + if(len % 2 != 0) { + Highlights.colorCode(pos+(len-1), "buffer"); + Highlights.colorCode(pos+(len-3), "pairing"); + this.grailSwap(arr, pos + (len - 1), pos + (len - 3)); + } pos -= 2; part = 2; } @@ -556,12 +618,17 @@ private void grailBuildBlocks(int[] arr, int pos, int len, int buildLen, this.grailMergeRight(arr, pos + leftOverPos, buildLen, buildLen, buildLen); } } + + private int grailCmp(int[] arr, int a, int b, String usage) { + Highlights.colorCode(usage, a, b); + return Reads.compareIndices(arr, a, b, 1, true); + } // keys are on the left of arr. Blocks of length buildLen combined. We'll combine them in pairs // buildLen and nkeys are powers of 2. (2 * buildLen / regBlockLen) keys are guaranteed private void grailCombineBlocks(int[] arr, int keyPos, int pos, int len, int buildLen, int regBlockLen, boolean havebuf, int[] buffer, int bufferPos) { - + int combineLen = len / (2 * buildLen); int leftOver = len % (2 * buildLen); if(leftOver <= buildLen) { @@ -578,21 +645,21 @@ private void grailCombineBlocks(int[] arr, int keyPos, int pos, int len, int bui int blockCount = (i == combineLen ? leftOver : 2 * buildLen) / regBlockLen; this.grailInsertSort(arr, keyPos, blockCount + (i == combineLen ? 1 : 0)); - + int midkey = buildLen / regBlockLen; for(int index = 1; index < blockCount; index++) { int leftIndex = index - 1; for(int rightIndex = index; rightIndex < blockCount; rightIndex++) { - int rightComp = Reads.compareValues(arr[blockPos + leftIndex * regBlockLen], - arr[blockPos + rightIndex * regBlockLen]); - if(rightComp > 0 || (rightComp == 0 && Reads.compareValues(arr[keyPos + leftIndex], arr[keyPos + rightIndex]) > 0)) { + int rightComp = grailCmp(arr, blockPos + leftIndex * regBlockLen, blockPos + rightIndex * regBlockLen, "blockselect"); + if(rightComp > 0 || (rightComp == 0 && grailCmp(arr, keyPos + leftIndex, keyPos + rightIndex, "stability") > 0)) { leftIndex = rightIndex; } } if(leftIndex != index - 1) { - this.grailMultiSwap(arr, blockPos + (index - 1) * regBlockLen, blockPos + leftIndex * regBlockLen, regBlockLen); + this.grailMultiSwapCSCC(arr, blockPos + (index - 1) * regBlockLen, blockPos + leftIndex * regBlockLen, regBlockLen); + Highlights.colorCode(keyPos+index-1, "stability"); this.grailSwap(arr, keyPos + (index - 1), keyPos + leftIndex); if(midkey == index - 1 || midkey == leftIndex) { midkey ^= (index - 1) ^ leftIndex; @@ -605,8 +672,7 @@ private void grailCombineBlocks(int[] arr, int keyPos, int pos, int len, int bui if(i == combineLen) lastLen = leftOver % regBlockLen; if(lastLen != 0) { - while(aBlockCount < blockCount && Reads.compareValues(arr[blockPos + blockCount * regBlockLen], - arr[blockPos + (blockCount - aBlockCount - 1) * regBlockLen]) < 0) { + while(aBlockCount < blockCount && grailCmp(arr, blockPos + blockCount * regBlockLen, blockPos + (blockCount - aBlockCount - 1) * regBlockLen, "blockselect") < 0) { aBlockCount++; } } @@ -615,7 +681,7 @@ private void grailCombineBlocks(int[] arr, int keyPos, int pos, int len, int bui this.grailMergeBuffersLeftWithXBuf(arr, keyPos, keyPos + midkey, blockPos, blockCount - aBlockCount, regBlockLen, aBlockCount, lastLen); } - else this.grailMergeBuffersLeft(arr, keyPos, keyPos + midkey, blockPos, + else this.grailMergeBuffersLeft(arr, keyPos, keyPos + midkey, blockPos, blockCount - aBlockCount, regBlockLen, havebuf, aBlockCount, lastLen); } if(buffer != null) { @@ -624,6 +690,7 @@ private void grailCombineBlocks(int[] arr, int keyPos, int pos, int len, int bui } else if(havebuf) { while(--len >= 0) { + Highlights.swapColors(pos+len, pos + len - regBlockLen); this.grailSwap(arr, pos + len, pos + len - regBlockLen); } } @@ -656,16 +723,28 @@ protected void grailLazyStableSort(int[] arr, int pos, int len) { } } - protected void grailCommonSort(int[] arr, int pos, int len, int[] buffer, int bufferPos, int bufferLen) { + public void grailCommonSort(int[] arr, int pos, int len, int[] buffer, int bufferPos, int bufferLen) { this.grailInsertSorter = new OptimizedGnomeSort(this.arrayVisualizer); - + Highlights.retainColorMarks = true; + Highlights.defineColor("bufferrewind", Color.ORANGE); + Highlights.defineColor("rotate", Color.YELLOW); + Highlights.defineColor("pairing", Color.GRAY); + Highlights.defineColor("buffer", Color.DARK_GRAY); + Highlights.defineColor("binsearch", Color.PINK); + Highlights.defineColor("smartmerge", new Color(0, 200, 255)); + Highlights.defineColor("leftmerge", new Color(200, 0, 200)); + Highlights.defineColor("rightmerge", new Color(180, 100, 0)); + Highlights.defineColor("blockselect", new Color(0, 255, 100)); + Highlights.defineColor("stability", Color.CYAN); + Highlights.defineColor("fragment", new Color(0, 0, 255)); + if(len <= 16) { this.grailInsertSort(arr, pos, len); return; } - + int blockLen = 1; - while(blockLen * blockLen < len) blockLen *= 2; + while(blockLen * blockLen < len) blockLen *= 2; int numKeys = (len - 1) / blockLen + 1; @@ -713,16 +792,16 @@ protected void grailCommonSort(int[] arr, int pos, int len, int[] buffer, int bu regBlockLen = (2 * buildLen) / calcKeys; } } - this.grailCombineBlocks(arr, pos, pos + dist, len - dist, buildLen, regBlockLen, buildBufEnabled, + this.grailCombineBlocks(arr, pos, pos + dist, len - dist, buildLen, regBlockLen, buildBufEnabled, buildBufEnabled && regBlockLen <= bufferLen ? buffer : null, bufferPos); - + Highlights.clearMark(2); } this.grailInsertSort(arr, pos, dist); - this.grailMergeWithoutBuffer(arr, pos, dist, len - dist); + this.grailMergeWithoutBuffer(arr, pos, dist, len - dist); } - + private void grailInPlaceMerge(int[] arr, int pos, int len1, int len2) { if(len1 < 3 || len2 < 3) { this.grailMergeWithoutBuffer(arr, pos, len1, len2); @@ -777,4 +856,4 @@ protected void grailInPlaceMergeSort(int[] arr, int start, int len) { if(rest > part) this.grailInPlaceMerge(arr, left, part, rest - part); } } -} +} \ No newline at end of file From e4d72c2f7eda964d11406f8aa9d97f35f25efba2 Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Fri, 25 Feb 2022 18:39:30 -0700 Subject: [PATCH 04/29] (hopefully) Make PR checkstyle-compliant --- .../github/arrayv/main/ArrayVisualizer.java | 410 ++++++++++-------- .../io/github/arrayv/utils/Highlights.java | 49 ++- .../github/arrayv/visuals/bars/BarGraph.java | 45 +- 3 files changed, 290 insertions(+), 214 deletions(-) diff --git a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java index 45211016..619bb4e9 100644 --- a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java +++ b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java @@ -114,7 +114,9 @@ of this software and associated documentation files (the "Software"), to deal */ public final class ArrayVisualizer { + // @checkstyle:off StaticVariableName private static ArrayVisualizer INSTANCE = null; + // @checkstyle:on StaticVariableName private enum StatisticType { LINE_BREAK, @@ -132,6 +134,7 @@ private enum StatisticType { AUX_ALLOC, SEGMENTS; + // @checkstyle:off IndentationCheck - It doesn't like {{ syntax private static final Map CONFIG_KEYS = Collections.unmodifiableMap(new HashMap() {{ put("", LINE_BREAK); put("sort", SORT_IDENTITY); @@ -148,14 +151,15 @@ private enum StatisticType { put("auxlen", AUX_ALLOC); put("segments", SEGMENTS); }}); + // @checkstyle:on IndentationCheck } final JFrame window; - final private int MIN_ARRAY_VAL; - final private int MAX_ARRAY_VAL; + private final int minArrayVal; + private final int maxArrayVal; - final private Properties buildInfo; + private final Properties buildInfo; final int[] array; final int[] validateArray; @@ -171,11 +175,11 @@ private enum StatisticType { private volatile int sortLength; private volatile int uniqueItems; - private ArrayManager ArrayManager; - private SortAnalyzer SortAnalyzer; + private ArrayManager arrayManager; + private SortAnalyzer sortAnalyzer; - private UtilFrame UtilFrame; - private ArrayFrame ArrayFrame; + private UtilFrame utilFrame; + private ArrayFrame arrayFrame; private Visual[] visualClasses; @@ -183,7 +187,7 @@ private enum StatisticType { private Thread visualsThread; private volatile boolean visualsEnabled; - public final boolean disabledStabilityCheck; + private final boolean disabledStabilityCheck; private String category; private String heading; @@ -194,30 +198,23 @@ private enum StatisticType { private volatile int currentGap; - private boolean SHUFFLEANIM; + private boolean showShuffleAnimation; - private volatile boolean ANALYZE; - - private volatile boolean POINTER; + private volatile boolean highlightAsAnalysis; private Statistics statSnapshot; private String fontSelection; private double fontSelectionScale; - private volatile boolean TEXTDRAW; - private volatile boolean COLOR; - private volatile boolean DISPARITYDRAW; - private volatile boolean LINEDRAW; - private volatile boolean PIXELDRAW; - private volatile boolean RAINBOW; - private volatile boolean SPIRALDRAW; - private volatile boolean WAVEDRAW; - private volatile boolean EXTARRAYS; - - private volatile boolean ANTIQSORT; - private volatile boolean STABILITY; - private volatile boolean NETWORKS; - private volatile boolean REVERSED; + private volatile boolean showStatistics; + private volatile boolean showColor; + private volatile boolean showLines; + private volatile boolean showExternalArrays; + + private volatile boolean useAntiQSort; + private volatile boolean stabilityChecking; + private volatile boolean visualizingNetworks; + private volatile boolean reversedComparator; private volatile boolean isCanceled; @@ -232,19 +229,19 @@ private enum StatisticType { private Delays Delays; private Highlights Highlights; - private MultipleScript MultipleScript; + private MultipleScript multipleScript; private Reads Reads; - private Renderer Renderer; + private Renderer renderer; private Sounds Sounds; private Timer Timer; - private VisualStyles VisualStyles; + private VisualStyles visualStyles; private Writes Writes; - private AntiQSort AntiQSort; + private AntiQSort antiQSort; private volatile int updateVisualsForced; - public volatile boolean benchmarking; + private volatile boolean benchmarking; - public static int MAX_LENGTH_POWER = 15; + private static int maxLengthPower; private volatile boolean hidden; private volatile boolean frameSkipped; @@ -287,11 +284,11 @@ public synchronized void drop(DropTargetDropEvent e) { List droppedFiles = (List)e.getTransferable().getTransferData(DataFlavor.javaFileListFlavor); int success = 0; for (File file : droppedFiles) { - if (ArrayVisualizer.this.SortAnalyzer.importSort(file, false)) { + if (ArrayVisualizer.this.sortAnalyzer.importSort(file, false)) { success++; } } - ArrayVisualizer.this.SortAnalyzer.sortSorts(); + ArrayVisualizer.this.sortAnalyzer.sortSorts(); ArrayVisualizer.this.refreshSorts(); if (success == 0) { JErrorPane.invokeCustomErrorMessage("Failed to import all " + droppedFiles.size() + " sorts"); @@ -319,9 +316,9 @@ public boolean dispatchKeyEvent(KeyEvent e) { Thread thread = new Thread("ScriptSortThread") { @Override public void run(){ - RunScriptedSorts RunScriptedSorts = new RunScriptedSorts(ArrayVisualizer.this); + RunScriptedSorts runScriptedSorts = new RunScriptedSorts(ArrayVisualizer.this); try { - RunScriptedSorts.runThread(ArrayVisualizer.this.getArray(), 0, 0, false); + runScriptedSorts.runThread(ArrayVisualizer.this.getArray(), 0, 0, false); } catch (Exception e) { JErrorPane.invokeErrorMessage(e); } @@ -383,12 +380,12 @@ public void run() { e.printStackTrace(); } - this.MIN_ARRAY_VAL = 2; - this.MAX_ARRAY_VAL = (int)Math.pow(2, MAX_LENGTH_POWER); + this.minArrayVal = 2; + this.maxArrayVal = (int)Math.pow(2, maxLengthPower); int[] array; try { - array = new int[this.MAX_ARRAY_VAL]; + array = new int[this.maxArrayVal]; } catch (OutOfMemoryError e) { JErrorPane.invokeCustomErrorMessage("Failed to allocate main array. The program will now exit."); System.exit(1); @@ -396,7 +393,7 @@ public void run() { } this.array = array; - this.sortLength = this.MAX_ARRAY_VAL; + this.sortLength = this.maxArrayVal; this.arrays = new ArrayList<>(); this.arrays.add(this.array); @@ -455,6 +452,7 @@ public void run() { "ArrayVisualizer", JOptionPane.WARNING_MESSAGE ); + // @checkstyle:off IndentationCheck - There's custom indentation here to make things more readable statsConfig = new StatisticType[] { StatisticType.SORT_IDENTITY, StatisticType.ARRAY_LENGTH, @@ -472,11 +470,12 @@ public void run() { StatisticType.AUX_ALLOC, StatisticType.SEGMENTS }; + // @checkstyle:on IndentationCheck } else { statsConfig = statsInfoList.toArray(new StatisticType[statsInfoList.size()]); } - this.sortLength = Math.min(2048, this.MAX_ARRAY_VAL); + this.sortLength = Math.min(2048, this.maxArrayVal); this.uniqueItems = this.sortLength; this.formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US); @@ -485,29 +484,29 @@ public void run() { this.symbols.setGroupingSeparator(','); this.formatter.setDecimalFormatSymbols(this.symbols); - this.Highlights = new Highlights(this, this.MAX_ARRAY_VAL); + this.Highlights = new Highlights(this, this.maxArrayVal); this.Sounds = new Sounds(this.array, this); this.Delays = new Delays(this); this.Timer = new Timer(this); this.Reads = new Reads(this); - this.Renderer = new Renderer(this); + this.renderer = new Renderer(this); this.Writes = new Writes(this); - this.AntiQSort = new AntiQSort(this); + this.antiQSort = new AntiQSort(this); SoundFrame test = new SoundFrame(this.Sounds); test.setVisible(true); - this.ArrayManager = new ArrayManager(this); - this.SortAnalyzer = new SortAnalyzer(this); + this.arrayManager = new ArrayManager(this); + this.sortAnalyzer = new SortAnalyzer(this); - this.SortAnalyzer.analyzeSorts(); + this.sortAnalyzer.analyzeSorts(); this.refreshSorts(); int[] stabilityTable, indexTable, validateArray; boolean disabledStabilityCheck; try { - stabilityTable = new int[this.MAX_ARRAY_VAL]; - indexTable = new int[this.MAX_ARRAY_VAL]; + stabilityTable = new int[this.maxArrayVal]; + indexTable = new int[this.maxArrayVal]; disabledStabilityCheck = false; } catch (OutOfMemoryError e) { JErrorPane.invokeCustomErrorMessage("Failed to allocate arrays for stability check. This feature will be disabled."); @@ -516,7 +515,7 @@ public void run() { disabledStabilityCheck = true; } try { - validateArray = new int[this.MAX_ARRAY_VAL]; + validateArray = new int[this.maxArrayVal]; } catch (OutOfMemoryError e) { JErrorPane.invokeCustomErrorMessage("Failed to allocate array for improved validation. This feature will be disabled."); validateArray = null; @@ -530,7 +529,7 @@ public void run() { this.resetIndexTable(); } - this.MultipleScript = new MultipleScript(this); + this.multipleScript = new MultipleScript(this); this.category = ""; this.heading = ""; @@ -539,27 +538,22 @@ public void run() { this.statSnapshot = new Statistics(this); - this.UtilFrame = new UtilFrame(this.array, this); - this.ArrayFrame = new ArrayFrame(this.array, this); + this.utilFrame = new UtilFrame(this.array, this); + this.arrayFrame = new ArrayFrame(this.array, this); - this.UtilFrame.reposition(this.ArrayFrame); + this.utilFrame.reposition(this.arrayFrame); - this.SHUFFLEANIM = true; - this.ANALYZE = false; - this.POINTER = false; - this.TEXTDRAW = true; + this.showShuffleAnimation = true; + this.highlightAsAnalysis = false; + this.showStatistics = true; - this.COLOR = false; - this.DISPARITYDRAW = false; - this.LINEDRAW = false; - this.PIXELDRAW = false; - this.RAINBOW = false; - this.SPIRALDRAW = false; - this.EXTARRAYS = false; + this.showColor = false; + this.showLines = false; + this.showExternalArrays = false; - this.ANTIQSORT = false; - this.STABILITY = false; - this.NETWORKS = false; + this.useAntiQSort = false; + this.stabilityChecking = false; + this.visualizingNetworks = false; this.isCanceled = false; @@ -571,7 +565,7 @@ public void run() { this.ch = 0; this.cw = 0; - this.ArrayManager.initializeArray(this.array); + this.arrayManager.initializeArray(this.array); //TODO: Overhaul visual code to properly reflect Swing (JavaFX?) style and conventions this.toggleVisualUpdates(false); @@ -620,11 +614,11 @@ public void run() { try { if (ArrayVisualizer.this.updateVisualsForced > 0) { ArrayVisualizer.this.updateVisualsForced--; - ArrayVisualizer.this.Renderer.updateVisualsStart(ArrayVisualizer.this); + ArrayVisualizer.this.renderer.updateVisualsStart(ArrayVisualizer.this); int[][] arrays = ArrayVisualizer.this.arrays.toArray(new int[][] { }); - ArrayVisualizer.this.Renderer.drawVisual(ArrayVisualizer.this.VisualStyles, arrays, ArrayVisualizer.this, ArrayVisualizer.this.Highlights); + ArrayVisualizer.this.renderer.drawVisual(ArrayVisualizer.this.visualStyles, arrays, ArrayVisualizer.this, ArrayVisualizer.this.Highlights); - if (ArrayVisualizer.this.TEXTDRAW) { + if (ArrayVisualizer.this.showStatistics) { ArrayVisualizer.this.statSnapshot.updateStats(ArrayVisualizer.this); ArrayVisualizer.this.updateFontSize(); ArrayVisualizer.this.drawStats(Color.BLACK, true); @@ -640,7 +634,7 @@ public void run() { e.printStackTrace(); } long endTime = System.currentTimeMillis(); - statSnapshot.frameTimeMillis = endTime - startTime; + statSnapshot.setFrameTimeMillis(endTime - startTime); } } }; @@ -658,9 +652,9 @@ public JFrame getWindow() { } public void refreshSorts() { - this.sorts = this.SortAnalyzer.getSorts(); - this.invalidSorts = this.SortAnalyzer.getInvalidSorts(); - this.sortSuggestions = this.SortAnalyzer.getSuggestions(); + this.sorts = this.sortAnalyzer.getSorts(); + this.invalidSorts = this.sortAnalyzer.getInvalidSorts(); + this.sortSuggestions = this.sortAnalyzer.getSuggestions(); } private void drawStats(Color textColor, boolean dropShadow) { @@ -675,6 +669,7 @@ private void drawStats(Color textColor, boolean dropShadow) { int yPos = (int)(fontSelectionScale / 25.0 * 30); this.mainRender.setColor(textColor); + int step = 0; statLoop: for (StatisticType statType : statsConfig) { @@ -727,22 +722,22 @@ private void drawStats(Color textColor, boolean dropShadow) { stat = null; // Unreachable } mainRender.drawString(stat, xOffset, (int)(windowRatio * yPos) + yOffset); - if(step++ == 0 && Highlights.getDeclaredColors().length > 0) { + if (step++ == 0 && Highlights.getDeclaredColors().length > 0) { int startOffset = currentWidth(), copy = startOffset, metricFontHeight = mainRender.getFontMetrics().getHeight(), startStat = mainRender.getFontMetrics().stringWidth(stat) + xOffset + 24, copyYPos = (int)(windowRatio * yPos) + yOffset, textWidth; - for(String color : Highlights.getDeclaredColors()) { + for (String color : Highlights.getDeclaredColors()) { textWidth = mainRender.getFontMetrics().stringWidth(color); startOffset -= textWidth + metricFontHeight + 12; - if(startOffset >= startStat) { + if (startOffset >= startStat) { startOffset = copy - textWidth - metricFontHeight - 12; copyYPos += metricFontHeight + 8; } - if(!dropShadow) + if (!dropShadow) mainRender.setColor(Highlights.getColorFromName(color)); mainRender.fillRect(startOffset, copyYPos - metricFontHeight + (metricFontHeight / 3), metricFontHeight, metricFontHeight); - if(!dropShadow) + if (!dropShadow) mainRender.setColor(textColor); mainRender.drawString(color, startOffset + metricFontHeight + 6, copyYPos); } @@ -781,11 +776,14 @@ public boolean enableBenchmarking(boolean enabled) { } else if (this.benchmarking) { if (this.getCurrentLength() >= Math.pow(2, 23)) { - int warning = JOptionPane.showOptionDialog(this.getMainWindow(), "Warning! " - + "Your computer's GPU probably can't handle more than 2^23 elements at any " - + "framrate not significantly less than 1. Would you still like " - + "to re-enable graphics?", "Warning!", 2, JOptionPane.WARNING_MESSAGE, - null, new String[] { "Yes", "Please save my GPU!" }, "Please save my GPU!"); + int warning = JOptionPane.showOptionDialog( + this.getMainWindow(), + "Warning! " + + "Your computer's CPU probably can't handle more than 2^23 elements at any " + + "framrate not significantly less than 1. Would you still like " + + "to re-enable graphics?", + "Warning!", 2, JOptionPane.WARNING_MESSAGE, + null, new String[] { "Yes", "Please save my GPU!" }, "Please save my GPU!"); if (warning != 0) { enabled = true; } @@ -838,7 +836,7 @@ public void resetIndexTable() { } public boolean isSorted() { - return this.statSnapshot.findSegments(this.array, this.sortLength, this.REVERSED)[0] == 1; + return this.statSnapshot.findSegments(this.array, this.sortLength, this.reversedComparator)[0] == 1; } public int[] getArray() { @@ -850,10 +848,10 @@ public ArrayList getArrays() { } public ArrayManager getArrayManager() { - return this.ArrayManager; + return this.arrayManager; } public SortAnalyzer getSortAnalyzer() { - return this.SortAnalyzer; + return this.sortAnalyzer; } public Delays getDelays() { return this.Delays; @@ -865,7 +863,7 @@ public Reads getReads() { return this.Reads; } public Renderer getRender() { - return this.Renderer; + return this.renderer; } public Sounds getSounds() { return this.Sounds; @@ -874,13 +872,13 @@ public Timer getTimer() { return this.Timer; } public VisualStyles getVisualStyles() { - return this.VisualStyles; + return this.visualStyles; } public Writes getWrites() { return this.Writes; } public MultipleScript getScriptParser() { - return this.MultipleScript; + return this.multipleScript; } public Visual[] getVisuals() { @@ -888,11 +886,11 @@ public Visual[] getVisuals() { } public UtilFrame getUtilFrame() { - return this.UtilFrame; + return this.utilFrame; } public ArrayFrame getArrayFrame() { - return this.ArrayFrame; + return this.arrayFrame; } public SortInfo[] getSorts() { @@ -910,10 +908,10 @@ public void runSortingThread() { } public int getMinimumLength() { - return this.MIN_ARRAY_VAL; + return this.minArrayVal; } public int getMaximumLength() { - return this.MAX_ARRAY_VAL; + return this.maxArrayVal; } public void resetAllStatistics() { @@ -929,51 +927,51 @@ public boolean isActive() { public void setComparator(int comparator) { switch (comparator) { case 0: - this.REVERSED = false; - this.ANTIQSORT = false; - this.STABILITY = false; - this.NETWORKS = false; + this.reversedComparator = false; + this.useAntiQSort = false; + this.stabilityChecking = false; + this.visualizingNetworks = false; break; case 1: - this.REVERSED = false; - this.ANTIQSORT = true; - this.STABILITY = false; - this.NETWORKS = false; + this.reversedComparator = false; + this.useAntiQSort = true; + this.stabilityChecking = false; + this.visualizingNetworks = false; break; case 2: - this.REVERSED = false; - this.ANTIQSORT = false; - this.STABILITY = true; - this.NETWORKS = false; + this.reversedComparator = false; + this.useAntiQSort = false; + this.stabilityChecking = true; + this.visualizingNetworks = false; break; case 3: - this.REVERSED = true; - this.ANTIQSORT = false; - this.STABILITY = false; - this.NETWORKS = false; + this.reversedComparator = true; + this.useAntiQSort = false; + this.stabilityChecking = false; + this.visualizingNetworks = false; break; case 4: - this.REVERSED = false; - this.ANTIQSORT = false; - this.STABILITY = false; - this.NETWORKS = true; + this.reversedComparator = false; + this.useAntiQSort = false; + this.stabilityChecking = false; + this.visualizingNetworks = true; break; } } public boolean generateSortingNetworks() { - return this.NETWORKS; + return this.visualizingNetworks; } public boolean useAntiQSort() { - return this.ANTIQSORT; + return this.useAntiQSort; } public void initAntiQSort() { - this.AntiQSort.beginSort(this.array, this.sortLength); + this.antiQSort.beginSort(this.array, this.sortLength); } public void finishAntiQSort(String name) { - int[] result = this.AntiQSort.getResult(); - this.AntiQSort.hideResult(); + int[] result = this.antiQSort.getResult(); + this.antiQSort.hideResult(); String outName = "antiqsort_" + name + "_" + this.sortLength; if (!ArrayFileWriter.writeArray(outName, result, sortLength)) { return; @@ -981,18 +979,18 @@ public void finishAntiQSort(String name) { JOptionPane.showMessageDialog(null, "Successfully saved output to file \"" + outName + "\"", "AntiQSort", JOptionPane.INFORMATION_MESSAGE); } public int antiqCompare(int left, int right) { - int cmp = this.AntiQSort.compare(left, right); + int cmp = this.antiQSort.compare(left, right); if (cmp == 0) return 0; return cmp / Math.abs(cmp); } public boolean doingStabilityCheck() { - return this.STABILITY; + return this.stabilityChecking; } public boolean reversedComparator() { - return this.REVERSED; + return this.reversedComparator; } // These next five methods should be part of ArrayManager @@ -1024,10 +1022,11 @@ public int getLogBaseTwoOfLength() { } public boolean shuffleEnabled() { - return this.SHUFFLEANIM; + return this.showShuffleAnimation; } - public void toggleShuffleAnimation(boolean Bool) { - this.SHUFFLEANIM = Bool; + + public void toggleShuffleAnimation(boolean showShuffleAnimation) { + this.showShuffleAnimation = showShuffleAnimation; } public String getCategory() { @@ -1049,8 +1048,13 @@ public void setExtraHeading(String text) { this.extraHeading = text; } + /** + * @deprecated No longer does anything (always returns {@code false}) + * @return {@code false} + */ + @Deprecated public boolean pointerActive() { - return this.POINTER; + return false; } public JFrame getMainWindow() { @@ -1171,11 +1175,12 @@ public void updateFontSize() { this.mainRender.setFont(this.typeFace); } - public void toggleAnalysis(boolean Bool) { - this.ANALYZE = Bool; + public void toggleAnalysis(boolean highlightAsAnalysis) { + this.highlightAsAnalysis = highlightAsAnalysis; } + public boolean analysisEnabled() { - return this.ANALYZE; + return this.highlightAsAnalysis; } public int halfCircle() { @@ -1196,7 +1201,7 @@ public synchronized void verifySortAndSweep() { String temp = this.heading; this.heading = "Verifying sort..."; - int cmpVal = this.REVERSED ? -1 : 1; + int cmpVal = this.reversedComparator ? -1 : 1; boolean success = true, stable = true; int unstableIdx = 0; @@ -1249,7 +1254,7 @@ public synchronized void verifySortAndSweep() { // if (tempStability && success) // JOptionPane.showMessageDialog(this.window, "This sort is stable!", "Information", JOptionPane.OK_OPTION, null); - if (this.STABILITY && success && !stable) { + if (this.stabilityChecking && success && !stable) { boolean tempSound = this.Sounds.isEnabled(); this.Sounds.toggleSound(false); this.Highlights.toggleFancyFinish(false); @@ -1309,8 +1314,6 @@ public String formatTimes() { public void endSort() { this.Timer.disableRealTimer(); this.Highlights.clearAllMarks(); - this.Highlights.clearAllColors(); - this.Highlights.clearColorList(); System.out.println(formatTimes()); this.isCanceled = false; @@ -1325,42 +1328,69 @@ public void endSort() { this.Highlights.clearAllMarks(); } - public void togglePointer(boolean Bool) { - this.POINTER = Bool; + /** + * @deprecated No longer does anything + */ + @Deprecated + public void togglePointer(boolean showPointer) { } - public void toggleDistance(boolean Bool) { - this.DISPARITYDRAW = Bool; + + /** + * @deprecated No longer does anything + */ + @Deprecated + public void toggleDistance(boolean unused) { } - public void togglePixels(boolean Bool) { - this.PIXELDRAW = Bool; + + /** + * @deprecated No longer does anything + */ + @Deprecated + public void togglePixels(boolean usePixels) { } - public void toggleRainbow(boolean Bool) { - this.RAINBOW = Bool; + + /** + * @deprecated No longer does anything + */ + @Deprecated + public void toggleRainbow(boolean rainbow) { } - public void toggleSpiral(boolean Bool) { - this.SPIRALDRAW = Bool; + + /** + * @deprecated No longer does anything + */ + @Deprecated + public void toggleSpiral(boolean spiral) { } - public void toggleLinkedDots(boolean Bool) { - this.LINEDRAW = Bool; + + public void toggleLinkedDots(boolean showLines) { + this.showLines = showLines; } - public void toggleStatistics(boolean Bool) { - this.TEXTDRAW = Bool; + + public void toggleStatistics(boolean showStatistics) { + this.showStatistics = showStatistics; } - public void toggleColor(boolean Bool) { - this.COLOR = Bool; + + public void toggleColor(boolean showColor) { + this.showColor = showColor; } - public void toggleWave(boolean Bool) { - this.WAVEDRAW = Bool; + + /** + * @deprecated No longer does anything + */ + @Deprecated + public void toggleWave(boolean useWave) { } - public void toggleExternalArrays(boolean Bool) { - this.EXTARRAYS = Bool; + + public void toggleExternalArrays(boolean showExternalArrays) { + this.showExternalArrays = showExternalArrays; } public void setVisual(VisualStyles choice) { if (choice == io.github.arrayv.visuals.VisualStyles.CUSTOM_IMAGE) { ((CustomImage) this.visualClasses[9]).enableImgMenu(); } - this.VisualStyles = choice; + this.visualStyles = choice; synchronized (this) { this.updateNow(); } @@ -1381,33 +1411,65 @@ public void setCanceled(boolean canceled) { } public void repositionFrames() { - this.ArrayFrame.reposition(); - this.UtilFrame.reposition(this.ArrayFrame); + this.arrayFrame.reposition(); + this.utilFrame.reposition(this.arrayFrame); } + /** + * @deprecated No longer does anything (always returns {@code false}) + * @return {@code false} + */ + @Deprecated public boolean rainbowEnabled() { - return this.RAINBOW; + return false; } + public boolean colorEnabled() { - return this.COLOR; + return this.showColor; } + + /** + * @deprecated No longer does anything (always returns {@code false}) + * @return {@code false} + */ + @Deprecated public boolean spiralEnabled() { - return this.SPIRALDRAW; + return false; } + + /** + * @deprecated No longer does anything (always returns {@code false}) + * @return {@code false} + */ + @Deprecated public boolean distanceEnabled() { - return this.DISPARITYDRAW; + return false; } + + /** + * @deprecated No longer does anything (always returns {@code false}) + * @return {@code false} + */ + @Deprecated public boolean pixelsEnabled() { - return this.PIXELDRAW; + return false; } + public boolean linesEnabled() { - return this.LINEDRAW; + return this.showLines; } + + /** + * @deprecated No longer does anything (always returns {@code false}) + * @return {@code false} + */ + @Deprecated public boolean waveEnabled() { - return this.WAVEDRAW; + return false; } + public boolean externalArraysEnabled() { - return this.EXTARRAYS; + return this.showExternalArrays; } public DecimalFormat getNumberFormat() { @@ -1423,7 +1485,7 @@ private static String parseStringArray(String[] stringArray) { } private void drawWindows() { - this.VisualStyles = io.github.arrayv.visuals.VisualStyles.BARS; + this.visualStyles = io.github.arrayv.visuals.VisualStyles.BARS; this.category = "Select a Sort"; Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); @@ -1460,8 +1522,8 @@ public void windowClosing(WindowEvent close) { this.window.setVisible(true); this.visualsThread.start(); - this.UtilFrame.setVisible(true); - this.ArrayFrame.setVisible(true); + this.utilFrame.setVisible(true); + this.arrayFrame.setVisible(true); this.window.createBufferStrategy(2); @@ -1475,10 +1537,18 @@ public void windowClosing(WindowEvent close) { } } + public boolean isDisabledStabilityCheck() { + return disabledStabilityCheck; + } + + public static int getMaxLengthPower() { + return maxLengthPower; + } + public static void main(String[] args) { System.setProperty("sun.java2d.d3d", "false"); if (args.length > 0) { - ArrayVisualizer.MAX_LENGTH_POWER = Integer.parseInt(args[0]); + ArrayVisualizer.maxLengthPower = Integer.parseInt(args[0]); } new ArrayVisualizer(); } diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index ce9ab763..047b8e56 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -37,7 +37,11 @@ public final class Highlights { private volatile byte[] markCounts; private volatile boolean[] colorMarks; private volatile Color[] colorColors; + + // @checkstyle:off VisibilityModifier public volatile boolean retainColorMarks = true; + // @checkstyle:on VisibilityModifier + private volatile HashMap defined; private volatile int maxHighlightMarked; // IMPORTANT: This stores the index one past the farthest highlight used, so that a value @@ -60,14 +64,14 @@ public final class Highlights { private volatile int markCount; - private boolean FANCYFINISH; + private boolean showFancyFinish; private volatile boolean fancyFinish; private volatile int trackFinish; - private ArrayVisualizer ArrayVisualizer; + private ArrayVisualizer arrayVisualizer; - public Highlights(ArrayVisualizer ArrayVisualizer, int maximumLength) { - this.ArrayVisualizer = ArrayVisualizer; + public Highlights(ArrayVisualizer arrayVisualizer, int maximumLength) { + this.arrayVisualizer = arrayVisualizer; try { defined = new HashMap<>(); @@ -79,26 +83,28 @@ public Highlights(ArrayVisualizer ArrayVisualizer, int maximumLength) { JErrorPane.invokeCustomErrorMessage("Failed to allocate mark arrays. The program will now exit."); System.exit(1); } - this.FANCYFINISH = true; + this.showFancyFinish = true; this.maxHighlightMarked = 0; this.markCount = 0; Arrays.fill(highlights, -1); Arrays.fill(markCounts, (byte)0); + Arrays.fill(colorMarks, false); + Arrays.fill(colorColors, null); } public boolean fancyFinishEnabled() { - return this.FANCYFINISH; + return this.showFancyFinish; } - public void toggleFancyFinishes(boolean Bool) { - this.FANCYFINISH = Bool; + public void toggleFancyFinishes(boolean fancyFinishOn) { + this.showFancyFinish = fancyFinishOn; } public boolean fancyFinishActive() { return this.fancyFinish; } - public void toggleFancyFinish(boolean Bool) { - this.fancyFinish = Bool; + public void toggleFancyFinish(boolean fancyFin) { + this.fancyFinish = fancyFin; } public int getFancyFinishPosition() { @@ -111,8 +117,8 @@ public void resetFancyFinish() { this.trackFinish = -1; // Magic number that clears the green sweep animation } - public void toggleAnalysis(boolean Bool) { - this.ArrayVisualizer.toggleAnalysis(Bool); + public void toggleAnalysis(boolean analysis) { + this.arrayVisualizer.toggleAnalysis(analysis); } public int getMaxHighlight() { @@ -177,10 +183,10 @@ public synchronized void colorCode(int position, String color) { } catch (Exception e) { e.printStackTrace(); } - ArrayVisualizer.updateNow(); + arrayVisualizer.updateNow(); } public synchronized void colorCode(String color, int... positions) { - for(int i : positions) { + for (int i : positions) { colorCode(i, color); } } @@ -189,7 +195,7 @@ public synchronized void clearColorList() { retainColorMarks = false; } public synchronized void clearColor(int position) { - if(colorMarks[position]) { + if (colorMarks[position]) { colorMarks[position] = false; colorColors[position] = null; } @@ -224,8 +230,8 @@ public synchronized void markArray(int marker, int markPosition) { if (highlights[marker] != -1) { decrementIndexMarkCount(highlights[marker]); } - if(!retainColorMarks) { - colorMarks[markPosition] = false; + if (!retainColorMarks) { + clearColor(markPosition); } highlights[marker] = markPosition; incrementIndexMarkCount(markPosition); @@ -237,14 +243,15 @@ public synchronized void markArray(int marker, int markPosition) { } catch (Exception e) { e.printStackTrace(); } - ArrayVisualizer.updateNow(); + arrayVisualizer.updateNow(); } public synchronized void clearMark(int marker) { if (highlights[marker] == -1) { return; } - if(!retainColorMarks) + if (!retainColorMarks) { clearColor(highlights[marker]); + } decrementIndexMarkCount(highlights[marker]); highlights[marker] = -1; // -1 is used as the magic number to unmark a position in the main array if (marker == this.maxHighlightMarked) { @@ -253,7 +260,7 @@ public synchronized void clearMark(int marker) { maxHighlightMarked--; } } - ArrayVisualizer.updateNow(); + arrayVisualizer.updateNow(); } public synchronized void clearAllMarks() { for (int i = 0; i < this.maxHighlightMarked; i++) { @@ -264,6 +271,6 @@ public synchronized void clearAllMarks() { Arrays.fill(this.highlights, 0, this.maxHighlightMarked, -1); this.maxHighlightMarked = 0; this.markCount = 0; - ArrayVisualizer.updateNow(); + arrayVisualizer.updateNow(); } } diff --git a/src/main/java/io/github/arrayv/visuals/bars/BarGraph.java b/src/main/java/io/github/arrayv/visuals/bars/BarGraph.java index 1ad7d1a4..fe113e48 100644 --- a/src/main/java/io/github/arrayv/visuals/bars/BarGraph.java +++ b/src/main/java/io/github/arrayv/visuals/bars/BarGraph.java @@ -9,54 +9,53 @@ public final class BarGraph extends Visual { - public BarGraph(ArrayVisualizer ArrayVisualizer) { - super(ArrayVisualizer); + public BarGraph(ArrayVisualizer arrayVisualizer) { + super(arrayVisualizer); } @Override - public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - for (int i = 0, j = 0; i < Renderer.getArrayLength(); i++) { - int width = (int) (Renderer.getXScale() * (i + 1)) - j; + public void drawVisual(int[] array, ArrayVisualizer arrayVisualizer, Renderer renderer, Highlights Highlights) { + for (int i = 0, j = 0; i < renderer.getArrayLength(); i++) { + int width = (int) (renderer.getXScale() * (i + 1)) - j; if (width == 0) continue; - if (Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) + if (Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) { this.mainRender.setColor(Color.GREEN); - else if (ArrayVisualizer.colorEnabled()) { - int val = ArrayVisualizer.doingStabilityCheck() && ArrayVisualizer.colorEnabled() ? ArrayVisualizer.getIndexValue(array[i]): array[i]; - this.mainRender.setColor(getIntColor(val, ArrayVisualizer.getCurrentLength())); - } - else if(Highlights.hasColor(i)) { - this.mainRender.setColor(Highlights.colorAt(i)); + } else if (arrayVisualizer.colorEnabled()) { + int val = arrayVisualizer.doingStabilityCheck() && arrayVisualizer.colorEnabled() ? arrayVisualizer.getIndexValue(array[i]): array[i]; + this.mainRender.setColor(getIntColor(val, arrayVisualizer.getCurrentLength())); + } else if (Highlights.hasColor(i)) { + this.mainRender.setColor(Highlights.colorAt(i)); } else this.mainRender.setColor(Color.WHITE); - int val = ArrayVisualizer.doingStabilityCheck() && ArrayVisualizer.colorEnabled() ? ArrayVisualizer.getStabilityValue(array[i]): array[i]; - int y = (int) (((Renderer.getViewSize() - 20)) - (val + 1) * Renderer.getYScale()); + int val = arrayVisualizer.doingStabilityCheck() && arrayVisualizer.colorEnabled() ? arrayVisualizer.getStabilityValue(array[i]): array[i]; + int y = (int) (((renderer.getViewSize() - 20)) - (val + 1) * renderer.getYScale()); - this.mainRender.fillRect(j + 20, Renderer.getYOffset() + y, width, (int) ((val + 1) * Renderer.getYScale())); + this.mainRender.fillRect(j + 20, renderer.getYOffset() + y, width, (int) ((val + 1) * renderer.getYScale())); j += width; } - this.mainRender.setColor(ArrayVisualizer.getHighlightColor()); - int length = Math.min(Renderer.getArrayLength(), ArrayVisualizer.getCurrentLength()); + this.mainRender.setColor(arrayVisualizer.getHighlightColor()); + int length = Math.min(renderer.getArrayLength(), arrayVisualizer.getCurrentLength()); boolean mark = false; for (int i = 0, j = 0; i < length; i++) { mark = mark || Highlights.containsPosition(i); - int width = (int) (Renderer.getXScale() * (i + 1)) - j; + int width = (int) (renderer.getXScale() * (i + 1)) - j; if (width == 0) continue; if (mark) { - int val = ArrayVisualizer.doingStabilityCheck() && ArrayVisualizer.colorEnabled() ? ArrayVisualizer.getStabilityValue(array[i]): array[i]; - int y = (int) (((Renderer.getViewSize() - 20)) - (val + 1) * Renderer.getYScale()); + int val = arrayVisualizer.doingStabilityCheck() && arrayVisualizer.colorEnabled() ? arrayVisualizer.getStabilityValue(array[i]): array[i]; + int y = (int) (((renderer.getViewSize() - 20)) - (val + 1) * renderer.getYScale()); - this.mainRender.fillRect(j + 20, Renderer.getYOffset() + y, Math.max(width, 2), (int) ((val + 1) * Renderer.getYScale())); + this.mainRender.fillRect(j + 20, renderer.getYOffset() + y, Math.max(width, 2), (int) ((val + 1) * renderer.getYScale())); mark = false; } j += width; } - if (ArrayVisualizer.externalArraysEnabled()) { + if (arrayVisualizer.externalArraysEnabled()) { this.mainRender.setColor(Color.BLUE); - this.mainRender.fillRect(0, Renderer.getYOffset() + Renderer.getViewSize() - 20, ArrayVisualizer.currentWidth(), 1); + this.mainRender.fillRect(0, renderer.getYOffset() + renderer.getViewSize() - 20, arrayVisualizer.currentWidth(), 1); } } } From f27f7f58680bc198eb8a49f792b4d5ae623c19dd Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Sat, 26 Feb 2022 08:39:50 -0700 Subject: [PATCH 05/29] Delete ExpliciumSort.java --- .../arrayv/sorts/select/ExpliciumSort.java | 133 ------------------ 1 file changed, 133 deletions(-) delete mode 100644 src/main/java/io/github/arrayv/sorts/select/ExpliciumSort.java diff --git a/src/main/java/io/github/arrayv/sorts/select/ExpliciumSort.java b/src/main/java/io/github/arrayv/sorts/select/ExpliciumSort.java deleted file mode 100644 index 712a0d4f..00000000 --- a/src/main/java/io/github/arrayv/sorts/select/ExpliciumSort.java +++ /dev/null @@ -1,133 +0,0 @@ -package io.github.arrayv.sorts.select; - -import java.awt.Color; -import java.util.Arrays; - -import io.github.arrayv.main.ArrayVisualizer; -import io.github.arrayv.sorts.templates.Sort; - - -final public class ExpliciumSort extends Sort { - public ExpliciumSort(ArrayVisualizer arrayVisualizer) { - super(arrayVisualizer); - - this.setSortListName("Explicium"); - this.setRunAllSortsName("Explicium Sort"); - this.setRunSortName("Expliciumsort"); - this.setCategory("Selection Sorts"); - this.setBucketSort(false); - this.setRadixSort(false); - this.setUnreasonablySlow(false); - this.setUnreasonableLimit(0); - this.setBogoSort(false); - } - - // Expliciumsort: A variant of Classic Tournament Sort that runs faster. - // *Made by Distray* - - private void make(int[] array, int[] tree, int start, int end, int index) { - if(end <= start) { - Highlights.markArray(1, start); - Writes.write(tree, index, start, 1, true, true); - return; - } - int next = 2*index+1, // Location of left child in implicit binary tree, - mid = start + (end - start) / 2; // and the middle number. - - make(array, tree, start, mid, next); // Build the two children. - make(array, tree, mid+1, end, next+1); - - // Get the winning child, and set the parent index to that value. - if(Reads.compareIndices(array, tree[next], tree[next+1], 0.5, true) <= 0) { - Writes.write(tree, index, tree[next], 1, true, true); - } else { - Writes.write(tree, index, tree[next+1], 1, true, true); - } - // Colorcode the winner using "build". - Highlights.colorCode(tree[index], "build"); - } - private void makeTree(int[] array, int[] tree, int start, int end) { - make(array, tree, start, end, 0); // wrapper function - } - private void removeWinner(int[] array, int[] tree) { - int now = 0, neg; - int l = (tree.length - 1) / 2; - // Note: We can't take Classic Tournament's approach at finding the winner value, - // because this sort doesn't handle trees exactly like Classic Tournament does. - while(now < l) { - // Negation value to skip past empty children - neg = (2*(tree[2*now+1] >> 31)) + (tree[2*now+2] >> 31); - if(neg < 0) { - if(neg == -3) // -3 is the special number that indicates that we should stop. - break; - // When the left child is empty, this gives us the index for the right child, - // and when the right child is empty, it gives the index for the left child. - now = 2*now-neg; - } else if(tree[now] == tree[2*now+1]) { - // Traverse the child that it pulled the winner from. - now = 2*now+1; - } else { - now = 2*now+2; - } - } - Highlights.colorCode(tree[now], "eliminate"); // Mark the winner as eliminated, - Writes.write(tree, now, -1, 1, true, true); // snap the winner out of existence, - while(now > 0) { - now = (now - 1) / 2; // go up a level, - neg = (2*(tree[2*now+1] >> 31)) + (tree[2*now+2] >> 31); // get the negation value, - if(neg < 0) { // and check. - if(neg == -3) { // -3 in the rebuilding stage is the special number that deletes the parent. - Writes.write(tree, now, -1, 1, true, true); - continue; - } else // And just like before, this gives the non-empty child whenever used. - Writes.write(tree, now, tree[2*now-neg], 1, true, true); - } else if(Reads.compareIndices(array, tree[2*now+1], tree[2*now+2], 0.5, true) <= 0) { - // Rebuild the tree with the lower child of the two, if both are non-empty. - Writes.write(tree, now, tree[2*now+1], 1, true, true); - } else { - Writes.write(tree, now, tree[2*now+2], 1, true, true); - } - // Colorcode the winning child with the rebuild alias. - Highlights.colorCode(tree[now], "rebuild"); - } - } - public void Explic(int[] array, int start, int end) { - int treeLen = 2*(end-start)-1; - - // Convert the tree length into a 2^x-1 number. - treeLen |= treeLen>>1; - treeLen |= treeLen>>2; - treeLen |= treeLen>>4; - treeLen |= treeLen>>8; - treeLen |= treeLen>>16; - - // Define the colors we'll be using. - Highlights.retainColorMarks = true; - Highlights.defineColor("build", new Color(0, 192, 192)); - Highlights.defineColor("eliminate", Color.DARK_GRAY); - Highlights.defineColor("rebuild", Color.BLUE); - - int[] tree = Writes.createExternalArray(treeLen), // Tree of indices - out = Writes.createExternalArray(end-start); // Sorted result - Arrays.fill(tree, -1); - Writes.changeAuxWrites(treeLen); - makeTree(array, tree, start, end-1); - int t = 0; - while(true) { - // Push the winner value stored in the root of the tree to the output. - Writes.write(out, t++, array[tree[0]], 1, true, true); - if(t < end-start) // Remove the winner and rebuild the tree. - removeWinner(array, tree); - else - break; - } - // Put the sorted output back into the main array, and wipe the elimination colors off in the process. - Highlights.retainColorMarks = false; - Writes.arraycopy(out, 0, array, start, end-start, 1, true, false); - Writes.deleteExternalArrays(out, tree); - } - @Override - public void runSort(int[] array, int length, int bucketCount) { - Explic(array, 0, length); - } -} \ No newline at end of file From f260d194b83bbb04ef194e08e8125068cb177bdd Mon Sep 17 00:00:00 2001 From: "Josiah (Gaming32) Glosson" Date: Sat, 26 Feb 2022 10:06:21 -0600 Subject: [PATCH 06/29] Fix ignored checkstyle violation --- .../sorts/merge/BlockSwapMergeSort.java | 2 +- .../arrayv/sorts/merge/RotateMergeSort.java | 2 +- .../arrayv/sorts/templates/GrailSorting.java | 92 +++++++++---------- .../io/github/arrayv/utils/Highlights.java | 12 ++- 4 files changed, 57 insertions(+), 51 deletions(-) diff --git a/src/main/java/io/github/arrayv/sorts/merge/BlockSwapMergeSort.java b/src/main/java/io/github/arrayv/sorts/merge/BlockSwapMergeSort.java index 024f78f1..196a3bf3 100644 --- a/src/main/java/io/github/arrayv/sorts/merge/BlockSwapMergeSort.java +++ b/src/main/java/io/github/arrayv/sorts/merge/BlockSwapMergeSort.java @@ -88,7 +88,7 @@ public void multiSwapMerge(int[] array, int start, int mid, int end) { } public void multiSwapMergeSort(int[] array, int a, int b) { - Highlights.retainColorMarks = true; + Highlights.retainColorMarks(true);; Highlights.defineColor("double_binsearch", new Color(128, 0, 255)); Highlights.defineColor("blockswap", Color.ORANGE); int len = b-a, i; diff --git a/src/main/java/io/github/arrayv/sorts/merge/RotateMergeSort.java b/src/main/java/io/github/arrayv/sorts/merge/RotateMergeSort.java index e476fb3f..82864779 100644 --- a/src/main/java/io/github/arrayv/sorts/merge/RotateMergeSort.java +++ b/src/main/java/io/github/arrayv/sorts/merge/RotateMergeSort.java @@ -108,7 +108,7 @@ private void rotateMerge(int[] array, int a, int m, int b) { } protected void rotateMergeSort(int[] array, int a, int b) { - Highlights.retainColorMarks = true; + Highlights.retainColorMarks(true); Highlights.defineColor("binsearch", Color.CYAN); Highlights.defineColor("rotate", Color.ORANGE); int len = b-a, i; diff --git a/src/main/java/io/github/arrayv/sorts/templates/GrailSorting.java b/src/main/java/io/github/arrayv/sorts/templates/GrailSorting.java index 3a001258..61ef2278 100644 --- a/src/main/java/io/github/arrayv/sorts/templates/GrailSorting.java +++ b/src/main/java/io/github/arrayv/sorts/templates/GrailSorting.java @@ -69,21 +69,21 @@ protected int getLeftOverFrag() { public abstract class GrailSorting extends Sort { private OptimizedGnomeSort grailInsertSorter; - + final private int grailStaticBufferLen = 32; //Buffer length changed due to less numbers in this program being sorted than what Mr. Astrelin used for testing. - + protected GrailSorting(ArrayVisualizer arrayVisualizer) { super(arrayVisualizer); } - + public int getStaticBuffer() { return this.grailStaticBufferLen; } - + private void grailSwap(int[] arr, int a, int b) { Writes.swap(arr, a, b, 1, true, false); } - + private void grailMultiSwapCS(int[] arr, int a, int b, int swapsLeft, String usage) { while(swapsLeft != 0) { Highlights.colorCode(usage, a, b); @@ -91,7 +91,7 @@ private void grailMultiSwapCS(int[] arr, int a, int b, int swapsLeft, String usa swapsLeft--; } } - + private void grailMultiSwapCSCC(int[] arr, int a, int b, int swapsLeft) { while(swapsLeft != 0) { Highlights.swapColors(a, b); @@ -99,14 +99,14 @@ private void grailMultiSwapCSCC(int[] arr, int a, int b, int swapsLeft) { swapsLeft--; } } - + protected void grailRotate(int[] array, int pos, int lenA, int lenB) { while(lenA != 0 && lenB != 0) { if(lenA <= lenB) { this.grailMultiSwapCS(array, pos, pos + lenA, lenA, "rotate"); pos += lenA; lenB -= lenA; - } + } else { this.grailMultiSwapCS(array, pos + (lenA - lenB), pos + lenA, lenB, "rotate"); lenA -= lenB; @@ -167,7 +167,7 @@ public int grailFindKeys(int[] arr, int pos, int len, int numKeys) { while(dist < len && foundKeys < numKeys) { if(dist < (len - 1)) Highlights.markArray(3, dist + 1); Delays.sleep(1); - + //Binary Search left int loc = this.grailBinSearchExc(arr, pos + firstKey, foundKeys, pos + dist); if(loc >= 0 || loc == foundKeys) { @@ -179,14 +179,14 @@ public int grailFindKeys(int[] arr, int pos, int len, int numKeys) { else { Highlights.clearMark(2); } - + dist++; } Highlights.clearMark(3); this.grailRotate(arr, pos, firstKey, foundKeys); - + Highlights.clearMark(2); - + return foundKeys; } @@ -229,8 +229,8 @@ public void grailMergeWithoutBuffer(int[] arr, int pos, int len1, int len2) { // aBlockCount are regular blocks from stream A. // lastLen is length of last (irregular) block from stream B, that should go before nblock2 blocks. // lastLen = 0 requires aBlockCount = 0 (no irregular blocks). lastLen > 0, aBlockCount = 0 is possible. - private void grailMergeBuffersLeft(int[] arr, int keysPos, int midkey, int pos, - int blockCount, int blockLen, boolean havebuf, int aBlockCount, + private void grailMergeBuffersLeft(int[] arr, int keysPos, int midkey, int pos, + int blockCount, int blockLen, boolean havebuf, int aBlockCount, int lastLen) { if(blockCount == 0) { @@ -248,7 +248,7 @@ private void grailMergeBuffersLeft(int[] arr, int keysPos, int midkey, int pos, for(int keyIndex = 1; keyIndex < blockCount; keyIndex++, processIndex += blockLen) { restToProcess = processIndex - leftOverLen; int nextFrag = Reads.compareValues(arr[keysPos + keyIndex], arr[midkey]) < 0 ? 0 : 1; - + if(nextFrag == leftOverFrag) { if(havebuf) this.grailMultiSwapCS(arr, pos + restToProcess - blockLen, pos + restToProcess, leftOverLen, "fragment"); restToProcess = processIndex; @@ -290,7 +290,7 @@ private void grailMergeBuffersLeft(int[] arr, int keysPos, int midkey, int pos, } } } - + // arr[dist..-1] - buffer, arr[0, leftLen - 1] ++ arr[leftLen, leftLen + rightLen - 1] // -> arr[dist, dist + leftLen + rightLen - 1] private void grailMergeLeft(int[] arr, int pos, int leftLen, int rightLen, int dist) { @@ -306,14 +306,14 @@ private void grailMergeLeft(int[] arr, int pos, int leftLen, int rightLen, int d this.grailSwap(arr, pos + (dist++), pos + (right++)); } else { Highlights.colorCode(pos + left, "buffer"); - this.grailSwap(arr, pos + (dist++), pos + (left++)); + this.grailSwap(arr, pos + (dist++), pos + (left++)); } Highlights.markArray(3, pos + left); Highlights.markArray(4, pos + right); } Highlights.clearMark(3); Highlights.clearMark(4); - + if(dist != left) { this.grailMultiSwapCS(arr, pos + dist, pos + left, leftLen - left, "leftmerge"); for(int i=0; i= leftLen) { Highlights.colorCode(pos + mergedPos, "rightmerge"); @@ -364,7 +364,7 @@ private GrailPair grailSmartMergeWithoutBuffer(int[] arr, int pos, int leftOverL if (typeFrag != 0) { //Binary Search left foundLen = this.grailBinSearch(arr, pos + len1, len2, pos, true); - } else { + } else { //Binary Search right foundLen = this.grailBinSearch(arr, pos + len1, len2, pos, false); } @@ -404,7 +404,7 @@ private GrailPair grailSmartMergeWithBuffer(int[] arr, int pos, int leftOverLen, } Highlights.clearMark(3); Highlights.clearMark(4); - + int length, fragment = leftOverFrag; if(left < leftEnd) { length = leftEnd - left; @@ -427,9 +427,9 @@ private GrailPair grailSmartMergeWithBuffer(int[] arr, int pos, int leftOverLen, private GrailPair grailSmartMergeWithXBuf(int[] arr, int pos, int leftOverLen, int leftOverFrag, int blockLen) { int dist = 0 - blockLen, left = 0, right = leftOverLen, leftEnd = right, rightEnd = right + blockLen; int typeFrag = 1 - leftOverFrag; // 1 if inverted - + Highlights.clearMark(2); - + while(left < leftEnd && right < rightEnd) { if(Reads.compareValues(arr[pos + left], arr[pos + right]) - typeFrag < 0) { Writes.write(arr, pos + dist++, arr[pos + left++], 1, true, false); @@ -440,7 +440,7 @@ private GrailPair grailSmartMergeWithXBuf(int[] arr, int pos, int leftOverLen, i } Highlights.clearMark(2); Highlights.clearMark(3); - + int length, fragment = leftOverFrag; if(left < leftEnd) { length = leftEnd - left; @@ -460,7 +460,7 @@ private void grailMergeLeftWithXBuf(int[] arr, int pos, int leftEnd, int rightEn rightEnd += leftEnd; Highlights.clearMark(2); - + while(right < rightEnd) { if(left == leftEnd || Reads.compareValues(arr[pos + left], arr[pos + right]) > 0) { Writes.write(arr, pos + dist++, arr[pos + right++], 1, true, false); @@ -471,7 +471,7 @@ private void grailMergeLeftWithXBuf(int[] arr, int pos, int leftEnd, int rightEn } Highlights.clearMark(2); Highlights.clearMark(3); - + if(dist != left) { while(left < leftEnd) Writes.write(arr, pos + dist++, arr[pos + left++], 1, true, false); } @@ -487,7 +487,7 @@ private void grailMergeBuffersLeftWithXBuf(int[] arr, int keysPos, int midkey, i int blockCount, int regBlockLen, int aBlockCount, int lastLen) { Highlights.clearMark(2); - + if(blockCount == 0) { int aBlocksLen = aBlockCount * regBlockLen; this.grailMergeLeftWithXBuf(arr, pos, aBlocksLen, lastLen, 0 - regBlockLen); @@ -505,12 +505,12 @@ private void grailMergeBuffersLeftWithXBuf(int[] arr, int keysPos, int midkey, i if(nextFrag == leftOverFrag) { Writes.arraycopy(arr, pos + restToProcess, arr, pos + restToProcess - regBlockLen, leftOverLen, 1, true, false); - + restToProcess = processIndex; leftOverLen = regBlockLen; } else { GrailPair results = this.grailSmartMergeWithXBuf(arr, pos + restToProcess, leftOverLen, leftOverFrag, regBlockLen); - leftOverLen = results.getLeftOverLen(); + leftOverLen = results.getLeftOverLen(); leftOverFrag = results.getLeftOverFrag(); } } @@ -519,7 +519,7 @@ private void grailMergeBuffersLeftWithXBuf(int[] arr, int keysPos, int midkey, i if(lastLen != 0) { if(leftOverFrag != 0) { Writes.arraycopy(arr, pos + restToProcess, arr, pos + restToProcess - regBlockLen, leftOverLen, 1, true, false); - + restToProcess = processIndex; leftOverLen = regBlockLen * aBlockCount; leftOverFrag = 0; @@ -537,7 +537,7 @@ private void grailMergeBuffersLeftWithXBuf(int[] arr, int keysPos, int midkey, i // build blocks of length buildLen // input: [-buildLen, -1] elements are buffer // output: first buildLen elements are buffer, blocks 2 * buildLen and last subblock sorted - private void grailBuildBlocks(int[] arr, int pos, int len, int buildLen, + private void grailBuildBlocks(int[] arr, int pos, int len, int buildLen, int[] extbuf, int bufferPos, int extBufLen) { int buildBuf = buildLen < extBufLen ? buildLen : extBufLen; @@ -546,7 +546,7 @@ private void grailBuildBlocks(int[] arr, int pos, int len, int buildLen, int extraDist, part; if(buildBuf != 0) { Writes.arraycopy(arr, pos - buildBuf, extbuf, bufferPos, buildBuf, 1, true, true); - + for(int dist = 1; dist < len; dist += 2) { extraDist = 0; if(Reads.compareValues(arr[pos + (dist - 1)], arr[pos + dist]) > 0) extraDist = 1; @@ -571,9 +571,9 @@ private void grailBuildBlocks(int[] arr, int pos, int len, int buildLen, for(; left < len; left++) Writes.write(arr, pos + left - part, arr[pos + left], 1, true, false); } pos -= part; - } + } Writes.arraycopy(extbuf, bufferPos, arr, pos + len, buildBuf, 1, true, false); - } + } else { for(int dist = 1; dist < len; dist += 2) { extraDist = 0; @@ -618,7 +618,7 @@ private void grailBuildBlocks(int[] arr, int pos, int len, int buildLen, this.grailMergeRight(arr, pos + leftOverPos, buildLen, buildLen, buildLen); } } - + private int grailCmp(int[] arr, int a, int b, String usage) { Highlights.colorCode(usage, a, b); return Reads.compareIndices(arr, a, b, 1, true); @@ -628,7 +628,7 @@ private int grailCmp(int[] arr, int a, int b, String usage) { // buildLen and nkeys are powers of 2. (2 * buildLen / regBlockLen) keys are guaranteed private void grailCombineBlocks(int[] arr, int keyPos, int pos, int len, int buildLen, int regBlockLen, boolean havebuf, int[] buffer, int bufferPos) { - + int combineLen = len / (2 * buildLen); int leftOver = len % (2 * buildLen); if(leftOver <= buildLen) { @@ -645,7 +645,7 @@ private void grailCombineBlocks(int[] arr, int keyPos, int pos, int len, int bui int blockCount = (i == combineLen ? leftOver : 2 * buildLen) / regBlockLen; this.grailInsertSort(arr, keyPos, blockCount + (i == combineLen ? 1 : 0)); - + int midkey = buildLen / regBlockLen; for(int index = 1; index < blockCount; index++) { @@ -681,7 +681,7 @@ private void grailCombineBlocks(int[] arr, int keyPos, int pos, int len, int bui this.grailMergeBuffersLeftWithXBuf(arr, keyPos, keyPos + midkey, blockPos, blockCount - aBlockCount, regBlockLen, aBlockCount, lastLen); } - else this.grailMergeBuffersLeft(arr, keyPos, keyPos + midkey, blockPos, + else this.grailMergeBuffersLeft(arr, keyPos, keyPos + midkey, blockPos, blockCount - aBlockCount, regBlockLen, havebuf, aBlockCount, lastLen); } if(buffer != null) { @@ -725,7 +725,7 @@ protected void grailLazyStableSort(int[] arr, int pos, int len) { public void grailCommonSort(int[] arr, int pos, int len, int[] buffer, int bufferPos, int bufferLen) { this.grailInsertSorter = new OptimizedGnomeSort(this.arrayVisualizer); - Highlights.retainColorMarks = true; + Highlights.retainColorMarks(true); Highlights.defineColor("bufferrewind", Color.ORANGE); Highlights.defineColor("rotate", Color.YELLOW); Highlights.defineColor("pairing", Color.GRAY); @@ -737,14 +737,14 @@ public void grailCommonSort(int[] arr, int pos, int len, int[] buffer, int buffe Highlights.defineColor("blockselect", new Color(0, 255, 100)); Highlights.defineColor("stability", Color.CYAN); Highlights.defineColor("fragment", new Color(0, 0, 255)); - + if(len <= 16) { this.grailInsertSort(arr, pos, len); return; } - + int blockLen = 1; - while(blockLen * blockLen < len) blockLen *= 2; + while(blockLen * blockLen < len) blockLen *= 2; int numKeys = (len - 1) / blockLen + 1; @@ -792,16 +792,16 @@ public void grailCommonSort(int[] arr, int pos, int len, int[] buffer, int buffe regBlockLen = (2 * buildLen) / calcKeys; } } - this.grailCombineBlocks(arr, pos, pos + dist, len - dist, buildLen, regBlockLen, buildBufEnabled, + this.grailCombineBlocks(arr, pos, pos + dist, len - dist, buildLen, regBlockLen, buildBufEnabled, buildBufEnabled && regBlockLen <= bufferLen ? buffer : null, bufferPos); - + Highlights.clearMark(2); } this.grailInsertSort(arr, pos, dist); - this.grailMergeWithoutBuffer(arr, pos, dist, len - dist); + this.grailMergeWithoutBuffer(arr, pos, dist, len - dist); } - + private void grailInPlaceMerge(int[] arr, int pos, int len1, int len2) { if(len1 < 3 || len2 < 3) { this.grailMergeWithoutBuffer(arr, pos, len1, len2); diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index feb557a8..634d37ad 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -38,9 +38,7 @@ public final class Highlights { private volatile boolean[] colorMarks; private volatile Color[] colorColors; - // @checkstyle:off VisibilityModifier - public volatile boolean retainColorMarks = true; - // @checkstyle:on VisibilityModifier + private volatile boolean retainColorMarks = true; private volatile HashMap defined; @@ -273,4 +271,12 @@ public synchronized void clearAllMarks() { this.markCount = 0; arrayVisualizer.updateNow(); } + + public synchronized boolean isRetainingColorMarks() { + return retainColorMarks; + } + + public synchronized void retainColorMarks(boolean retainColorMarks) { + this.retainColorMarks = retainColorMarks; + } } From 3bf1b0bc644ce9240272bc3ae1af45b79b25494b Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Sat, 26 Feb 2022 09:50:21 -0700 Subject: [PATCH 07/29] Move legend slightly, properly clear colorcodes --- .../java/io/github/arrayv/main/ArrayVisualizer.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java index c44d8685..f6e69101 100644 --- a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java +++ b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java @@ -729,9 +729,9 @@ private void drawStats(Color textColor, boolean dropShadow) { copyYPos = (int)(windowRatio * yPos) + yOffset, textWidth; for (String color : Highlights.getDeclaredColors()) { textWidth = mainRender.getFontMetrics().stringWidth(color); - startOffset -= textWidth + metricFontHeight + 12; - if (startOffset >= startStat) { - startOffset = copy - textWidth - metricFontHeight - 12; + startOffset -= textWidth + metricFontHeight + 20; + if (startOffset <= startStat) { + startOffset = copy - textWidth - metricFontHeight - 20; copyYPos += metricFontHeight + 8; } if (!dropShadow) @@ -1313,7 +1313,11 @@ public String formatTimes() { public void endSort() { this.Timer.disableRealTimer(); + this.Highlights.clearAllMarks(); + this.Highlights.clearAllColors(); + this.Highlights.clearColorList(); + System.out.println(formatTimes()); this.isCanceled = false; From f3cec01adda53a6bb231eea45e1bae70fa3ce190 Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Sat, 26 Feb 2022 09:57:10 -0700 Subject: [PATCH 08/29] Checkstyle violation --- src/main/java/io/github/arrayv/main/ArrayVisualizer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java index f6e69101..74938a0a 100644 --- a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java +++ b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java @@ -1313,11 +1313,11 @@ public String formatTimes() { public void endSort() { this.Timer.disableRealTimer(); - + this.Highlights.clearAllMarks(); this.Highlights.clearAllColors(); this.Highlights.clearColorList(); - + System.out.println(formatTimes()); this.isCanceled = false; From fded4d396f569c78f5a3855097f550a6808f6bff Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Sun, 27 Feb 2022 16:28:59 -0700 Subject: [PATCH 09/29] (rough draft) Subarray colorcoding In desperate need of optimization, rough around the edges. --- .../github/arrayv/main/ArrayVisualizer.java | 2 +- .../io/github/arrayv/utils/ArrayVList.java | 20 +++ .../io/github/arrayv/utils/Highlights.java | 156 ++++++++++++++---- .../java/io/github/arrayv/utils/Writes.java | 1 + .../github/arrayv/visuals/bars/BarGraph.java | 4 +- .../visuals/bars/DisparityBarGraph.java | 3 +- .../github/arrayv/visuals/bars/SineWave.java | 4 +- .../arrayv/visuals/dots/DisparityDots.java | 5 +- .../arrayv/visuals/dots/ScatterPlot.java | 2 + .../arrayv/visuals/dots/SpiralDots.java | 5 +- .../github/arrayv/visuals/dots/WaveDots.java | 4 +- 11 files changed, 168 insertions(+), 38 deletions(-) diff --git a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java index 74938a0a..c629b7a5 100644 --- a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java +++ b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java @@ -1315,7 +1315,7 @@ public void endSort() { this.Timer.disableRealTimer(); this.Highlights.clearAllMarks(); - this.Highlights.clearAllColors(); + this.Highlights.clearAllColorsReferenced(); this.Highlights.clearColorList(); System.out.println(formatTimes()); diff --git a/src/main/java/io/github/arrayv/utils/ArrayVList.java b/src/main/java/io/github/arrayv/utils/ArrayVList.java index fd67f7d5..87ffb3ca 100644 --- a/src/main/java/io/github/arrayv/utils/ArrayVList.java +++ b/src/main/java/io/github/arrayv/utils/ArrayVList.java @@ -29,6 +29,7 @@ public class ArrayVList extends AbstractList implements RandomAccess, C int[] internal; double growFactor; int count, capacity; + boolean colorsEnabled; public ArrayVList() { this(DEFAULT_CAPACITY, DEFAULT_GROW_FACTOR); @@ -54,6 +55,7 @@ public ArrayVList(int capacity, double growFactor) { public void delete() { Writes.changeAllocAmount(-count); arrayVisualizer.getArrays().remove(internal); + disableColors(); this.internal = null; this.count = 0; this.capacity = 0; @@ -95,11 +97,29 @@ public T[] toArray(T[] a) { return (T[])toArray(); } + public void enableColors() { + if (!colorsEnabled) { + colorsEnabled = true; + arrayVisualizer.getHighlights().registerColorMarks(internal); + } + } + + public void disableColors() { + if (colorsEnabled) { + colorsEnabled = false; + arrayVisualizer.getHighlights().unregisterColors(internal); + } + } + protected void grow() { int newCapacity = (int)Math.ceil(capacity * growFactor); int[] newInternal = new int[newCapacity]; System.arraycopy(internal, 0, newInternal, 0, count); ArrayList arrays = arrayVisualizer.getArrays(); + if (colorsEnabled) { + arrayVisualizer.getHighlights().unregisterColors(internal); + arrayVisualizer.getHighlights().registerColorMarks(newInternal); + } arrays.set(arrays.indexOf(internal), newInternal); this.capacity = newCapacity; this.internal = newInternal; diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index 634d37ad..2bbe3548 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -35,12 +35,15 @@ of this software and associated documentation files (the "Software"), to deal public final class Highlights { private volatile int[] highlights; private volatile byte[] markCounts; - private volatile boolean[] colorMarks; - private volatile Color[] colorColors; + + // This is in desperate need of optimization. + private volatile HashMap colorMarks; + private volatile HashMap colorColors; private volatile boolean retainColorMarks = true; private volatile HashMap defined; + private static int[] main; private volatile int maxHighlightMarked; // IMPORTANT: This stores the index one past the farthest highlight used, so that a value // of 0 means no highlights are in use, and iteration is more convenient. @@ -75,8 +78,8 @@ public Highlights(ArrayVisualizer arrayVisualizer, int maximumLength) { defined = new HashMap<>(); this.highlights = new int[maximumLength]; this.markCounts = new byte[maximumLength]; - this.colorMarks = new boolean[maximumLength]; - this.colorColors = new Color[maximumLength]; + this.colorMarks = new HashMap<>(); + this.colorColors = new HashMap<>(); } catch (OutOfMemoryError e) { JErrorPane.invokeCustomErrorMessage("Failed to allocate mark arrays. The program will now exit."); System.exit(1); @@ -84,11 +87,11 @@ public Highlights(ArrayVisualizer arrayVisualizer, int maximumLength) { this.showFancyFinishes = true; this.maxHighlightMarked = 0; this.markCount = 0; + this.main = arrayVisualizer.getArray(); Arrays.fill(highlights, -1); Arrays.fill(markCounts, (byte)0); - Arrays.fill(colorMarks, false); - Arrays.fill(colorColors, null); + this.registerColorMarks(main); } public boolean fancyFinishEnabled() { @@ -170,50 +173,127 @@ public Color getColorFromName(String color) { public synchronized void defineColor(String alias, Color col) { defined.put(alias, col); } - public synchronized void colorCode(int position, String color) { + + public synchronized boolean[] getColorMarks(int[] array) { + return colorMarks.get(array); + } + + public synchronized Color[] getColorColors(int[] array) { + return colorColors.get(array); + } + public synchronized void registerColorMarks(int[] array) { + boolean[] colorMark = new boolean[array.length]; + Color[] colorColor = new Color[array.length]; + colorMarks.putIfAbsent(array, colorMark); + colorColors.putIfAbsent(array, colorColor); + } + public synchronized void unregisterColors(int[] array) { + if (colorMarks.containsKey(array)) { + colorMarks.remove(array); + colorColors.remove(array); + } + } + // Ambitious function: Set the color directly + public synchronized void setRawColor(int[] array, int position, String color) { + try { + if (position < 0) { + throw new Exception("Highlights.setRawColor(): Invalid position!"); + } else { + boolean[] colorMark = getColorMarks(array); + if (colorMark != null) { + colorMark[position] = true; + getColorColors(array)[position] = getColorFromName(color); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + arrayVisualizer.updateNow(); + } + + public synchronized void setRawColor(int position, String color) { + setRawColor(main, position, color); + } + + // Convenience function: Set the color using a predefined alias + public synchronized void colorCode(int[] array, int position, String color) { try { if (position < 0) { throw new Exception("Highlights.colorCode(): Invalid position!"); } else { - colorMarks[position] = true; - colorColors[position] = defined.getOrDefault(color, Color.WHITE); + boolean[] colorMark = getColorMarks(array); + if (colorMark != null) { + colorMark[position] = true; + getColorColors(array)[position] = getColorFromName(color); + } } } catch (Exception e) { e.printStackTrace(); } arrayVisualizer.updateNow(); } - public synchronized void colorCode(String color, int... positions) { + + public synchronized void colorCode(int position, String color) { + colorCode(main, position, color); + } + + // Convenience function 2: Batch-colorcode a set of positions under one common name + public synchronized void colorCode(int[] array, String color, int... positions) { for (int i : positions) { - colorCode(i, color); + colorCode(array, i, color); } } - public synchronized void clearColorList() { - defined.clear(); - retainColorMarks = false; + + // Convenience function 2: Batch-colorcode a set of positions under one common name + public synchronized void colorCode(String color, int... positions) { + colorCode(main, color, positions); } - public synchronized void clearColor(int position) { - if (colorMarks[position]) { - colorMarks[position] = false; - colorColors[position] = null; + + public synchronized void clearColor(int[] array, int position) { + boolean[] colorMark = getColorMarks(array); + if (colorMark == null) + return; + if (colorMark[position]) { + colorMark[position] = false; + getColorColors(array)[position] = null; } } + + public synchronized void clearColor(int position) { + clearColor(main, position); + } + + public synchronized boolean hasColor(int[] array, int position) { + return colorMarks.containsKey(array) && getColorMarks(array)[position]; + } + public synchronized boolean hasColor(int position) { - return colorMarks[position]; + return hasColor(main, position); + } + + public synchronized Color colorAt(int[] array, int position) { + return getColorColors(array)[position]; } + public synchronized Color colorAt(int position) { - return colorColors[position]; + return colorAt(main, position); } - public synchronized void clearAllColors() { - Arrays.fill(colorMarks, false); // dirty way + + public void swapColors(int[] array, int locA, int locB) { + boolean[] colorMark = getColorMarks(array); + Color[] colorColor = getColorColors(array); + if (colorMark == null) + return; + boolean t0 = colorMark[locA]; + Color t1 = colorColor[locA]; + colorMark[locA] = colorMark[locB]; + colorMark[locB] = t0; + colorColor[locA] = colorColor[locB]; + colorColor[locB] = t1; } + public void swapColors(int locA, int locB) { - boolean t0 = colorMarks[locA]; - Color t1 = colorColors[locA]; - colorMarks[locA] = colorMarks[locB]; - colorMarks[locB] = t0; - colorColors[locA] = colorColors[locB]; - colorColors[locB] = t1; + swapColors(main, locA, locB); } public synchronized void markArray(int marker, int markPosition) { try { @@ -260,6 +340,26 @@ public synchronized void clearMark(int marker) { } arrayVisualizer.updateNow(); } + + public synchronized void clearColorList() { + defined.clear(); + retainColorMarks = false; + } + + public synchronized void clearAllColors(int[] array) { + Arrays.fill(getColorMarks(array), false); + } + + public synchronized void clearAllColors() { + clearAllColors(main); + } + + public synchronized void clearAllColorsReferenced() { + for (boolean[] list : colorMarks.values()) { + Arrays.fill(list, false); + } + } + public synchronized void clearAllMarks() { for (int i = 0; i < this.maxHighlightMarked; i++) { if (highlights[i] != -1) { diff --git a/src/main/java/io/github/arrayv/utils/Writes.java b/src/main/java/io/github/arrayv/utils/Writes.java index 2ffb9981..7d0a6155 100644 --- a/src/main/java/io/github/arrayv/utils/Writes.java +++ b/src/main/java/io/github/arrayv/utils/Writes.java @@ -427,6 +427,7 @@ public int[] createExternalArray(int length) { public void deleteExternalArray(int[] array) { this.allocAmount -= array.length; arrayVisualizer.getArrays().remove(array); + Highlights.unregisterColors(array); arrayVisualizer.updateNow(); } diff --git a/src/main/java/io/github/arrayv/visuals/bars/BarGraph.java b/src/main/java/io/github/arrayv/visuals/bars/BarGraph.java index e505684f..1f5dfdf8 100644 --- a/src/main/java/io/github/arrayv/visuals/bars/BarGraph.java +++ b/src/main/java/io/github/arrayv/visuals/bars/BarGraph.java @@ -24,8 +24,8 @@ public void drawVisual(int[] array, ArrayVisualizer arrayVisualizer, Renderer re else if (arrayVisualizer.colorEnabled()) { int val = arrayVisualizer.doingStabilityCheck() && arrayVisualizer.colorEnabled() ? arrayVisualizer.getIndexValue(array[i]): array[i]; this.mainRender.setColor(getIntColor(val, arrayVisualizer.getCurrentLength())); - } else if (Highlights.hasColor(i)) { - this.mainRender.setColor(Highlights.colorAt(i)); + } else if (Highlights.hasColor(array, i)) { + this.mainRender.setColor(Highlights.colorAt(array, i)); } else this.mainRender.setColor(Color.WHITE); int val = arrayVisualizer.doingStabilityCheck() && arrayVisualizer.colorEnabled() ? arrayVisualizer.getStabilityValue(array[i]): array[i]; diff --git a/src/main/java/io/github/arrayv/visuals/bars/DisparityBarGraph.java b/src/main/java/io/github/arrayv/visuals/bars/DisparityBarGraph.java index 029f8bd0..166a37e9 100644 --- a/src/main/java/io/github/arrayv/visuals/bars/DisparityBarGraph.java +++ b/src/main/java/io/github/arrayv/visuals/bars/DisparityBarGraph.java @@ -24,7 +24,8 @@ public void drawVisual(int[] array, ArrayVisualizer arrayVisualizer, Renderer re else if (arrayVisualizer.colorEnabled()) this.mainRender.setColor(getIntColor(array[i], arrayVisualizer.getCurrentLength())); - + else if (Highlights.hasColor(array, i)) + this.mainRender.setColor(Highlights.colorAt(array, i)); else this.mainRender.setColor(Color.WHITE); double disp = (1 + Math.sin((Math.PI * (array[i] - i)) / arrayVisualizer.getCurrentLength())) * 0.5; diff --git a/src/main/java/io/github/arrayv/visuals/bars/SineWave.java b/src/main/java/io/github/arrayv/visuals/bars/SineWave.java index 16737f5d..24af4cea 100644 --- a/src/main/java/io/github/arrayv/visuals/bars/SineWave.java +++ b/src/main/java/io/github/arrayv/visuals/bars/SineWave.java @@ -49,7 +49,9 @@ public void drawVisual(int[] array, ArrayVisualizer arrayVisualizer, Renderer re else if (arrayVisualizer.colorEnabled()) this.mainRender.setColor(getIntColor(array[i], arrayVisualizer.getCurrentLength())); - else this.mainRender.setColor(Color.WHITE); + else if (Highlights.hasColor(array, i)) { + this.mainRender.setColor(Highlights.colorAt(array, i)); + } else this.mainRender.setColor(Color.WHITE); int width = (int) (renderer.getXScale() * (i + 1)) - j; diff --git a/src/main/java/io/github/arrayv/visuals/dots/DisparityDots.java b/src/main/java/io/github/arrayv/visuals/dots/DisparityDots.java index 05b28fa1..523668f5 100644 --- a/src/main/java/io/github/arrayv/visuals/dots/DisparityDots.java +++ b/src/main/java/io/github/arrayv/visuals/dots/DisparityDots.java @@ -65,8 +65,9 @@ public void drawVisual(int[] array, ArrayVisualizer arrayVisualizer, Renderer re this.mainRender.setStroke(arrayVisualizer.getCustomStroke(4)); } else if (arrayVisualizer.colorEnabled()) this.mainRender.setColor(getIntColor(array[i], arrayVisualizer.getCurrentLength())); - - else this.mainRender.setColor(Color.WHITE); + else if (Highlights.hasColor(array, i)) { + this.mainRender.setColor(Highlights.colorAt(array, i)); + } else this.mainRender.setColor(Color.WHITE); disp = (1 + Math.cos((Math.PI * (array[i] - i)) / (arrayVisualizer.getCurrentLength() * 0.5))) * 0.5; int x = width/2 + (int)(disp * r * Math.cos(Math.PI * (2d*i / n - 0.5))); diff --git a/src/main/java/io/github/arrayv/visuals/dots/ScatterPlot.java b/src/main/java/io/github/arrayv/visuals/dots/ScatterPlot.java index a3b4dce0..d4ddd0d6 100644 --- a/src/main/java/io/github/arrayv/visuals/dots/ScatterPlot.java +++ b/src/main/java/io/github/arrayv/visuals/dots/ScatterPlot.java @@ -57,6 +57,8 @@ public void drawVisual(int[] array, ArrayVisualizer arrayVisualizer, Renderer re } else if (arrayVisualizer.colorEnabled()) { int val = arrayVisualizer.doingStabilityCheck() && arrayVisualizer.colorEnabled() ? arrayVisualizer.getIndexValue(array[i]): array[i]; this.mainRender.setColor(getIntColor(val, arrayVisualizer.getCurrentLength())); + } else if (Highlights.hasColor(array, i)) { + this.mainRender.setColor(Highlights.colorAt(array, i)); } else this.mainRender.setColor(Color.WHITE); int val = arrayVisualizer.doingStabilityCheck() && arrayVisualizer.colorEnabled() ? arrayVisualizer.getStabilityValue(array[i]): array[i]; diff --git a/src/main/java/io/github/arrayv/visuals/dots/SpiralDots.java b/src/main/java/io/github/arrayv/visuals/dots/SpiralDots.java index 2d72f21c..f3bda784 100644 --- a/src/main/java/io/github/arrayv/visuals/dots/SpiralDots.java +++ b/src/main/java/io/github/arrayv/visuals/dots/SpiralDots.java @@ -65,8 +65,9 @@ public void drawVisual(int[] array, ArrayVisualizer arrayVisualizer, Renderer re this.mainRender.setStroke(arrayVisualizer.getCustomStroke(4)); } else if (arrayVisualizer.colorEnabled()) this.mainRender.setColor(getIntColor(array[i], arrayVisualizer.getCurrentLength())); - - else this.mainRender.setColor(Color.WHITE); + else if (Highlights.hasColor(array, i)) { + this.mainRender.setColor(Highlights.colorAt(array, i)); + } else this.mainRender.setColor(Color.WHITE); mult = (double) array[i] / arrayVisualizer.getCurrentLength(); int x = width/2 + (int)(mult * r * Math.cos(Math.PI * (2d*i / n - 0.5))); diff --git a/src/main/java/io/github/arrayv/visuals/dots/WaveDots.java b/src/main/java/io/github/arrayv/visuals/dots/WaveDots.java index 9d9f8676..0c85a400 100644 --- a/src/main/java/io/github/arrayv/visuals/dots/WaveDots.java +++ b/src/main/java/io/github/arrayv/visuals/dots/WaveDots.java @@ -58,7 +58,9 @@ public void drawVisual(int[] array, ArrayVisualizer arrayVisualizer, Renderer re this.mainRender.setStroke(arrayVisualizer.getCustomStroke(4)); } else if (arrayVisualizer.colorEnabled()) this.mainRender.setColor(getIntColor(array[i-1], arrayVisualizer.getCurrentLength())); - else this.mainRender.setColor(Color.WHITE); + else if (Highlights.hasColor(array, i)) { + this.mainRender.setColor(Highlights.colorAt(array, i)); + } else this.mainRender.setColor(Color.WHITE); int y = (int) (((renderer.getViewSize() - 20) / 2.5) * Math.sin((2 * Math.PI * ((double) array[i] / renderer.getArrayLength()))) + renderer.halfViewSize() - 20); From c6aa3c64e78cfec1545d6400432c1b673526f342 Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Sun, 27 Feb 2022 16:30:35 -0700 Subject: [PATCH 10/29] Uninitialized variables are not fun (ArrayVList.java) --- src/main/java/io/github/arrayv/utils/ArrayVList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/github/arrayv/utils/ArrayVList.java b/src/main/java/io/github/arrayv/utils/ArrayVList.java index 87ffb3ca..0456681b 100644 --- a/src/main/java/io/github/arrayv/utils/ArrayVList.java +++ b/src/main/java/io/github/arrayv/utils/ArrayVList.java @@ -29,7 +29,7 @@ public class ArrayVList extends AbstractList implements RandomAccess, C int[] internal; double growFactor; int count, capacity; - boolean colorsEnabled; + boolean colorsEnabled = false; public ArrayVList() { this(DEFAULT_CAPACITY, DEFAULT_GROW_FACTOR); From 1b46832900b9dee7006a553a5f9805f65aa63ab5 Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Tue, 1 Mar 2022 11:38:41 -0700 Subject: [PATCH 11/29] Add ArrayVList colorcoding methods And a method for writing colors between auxarrays. Thanks for suggesting it, Control. --- .../io/github/arrayv/utils/ArrayVList.java | 34 +++++++++++++++++++ .../io/github/arrayv/utils/Highlights.java | 23 +++++++++++-- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/github/arrayv/utils/ArrayVList.java b/src/main/java/io/github/arrayv/utils/ArrayVList.java index 0456681b..9bc9e995 100644 --- a/src/main/java/io/github/arrayv/utils/ArrayVList.java +++ b/src/main/java/io/github/arrayv/utils/ArrayVList.java @@ -1,5 +1,6 @@ package io.github.arrayv.utils; +import java.awt.Color; import java.util.AbstractList; import java.util.ArrayList; import java.util.Arrays; @@ -139,6 +140,39 @@ public boolean add(Integer e) { return add(e, 0, false); } + public void colorCode(int position, String alias) { + try { + if (!colorsEnabled) { + throw new Exception("ArrayVList.colorCode(): List can't be colorcoded!"); + } + arrayVisualizer.getHighlights().colorCode(internal, position, alias); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void colorCode(String alias, int... positions) { + try { + if (!colorsEnabled) { + throw new Exception("ArrayVList.colorCode(): List can't be colorcoded!"); + } + arrayVisualizer.getHighlights().colorCode(internal, alias, positions); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void rawColorCode(int position, Color color) { + try { + if (!colorsEnabled) { + throw new Exception("ArrayVList.rawColorCode(): List can't be colorcoded!"); + } + arrayVisualizer.getHighlights().setRawColor(internal, position, color); + } catch (Exception e) { + e.printStackTrace(); + } + } + private void fastRemove(int index) { int numMoved = count - index - 1; if (numMoved > 0) diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index 2bbe3548..88f19e55 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -194,7 +194,7 @@ public synchronized void unregisterColors(int[] array) { } } // Ambitious function: Set the color directly - public synchronized void setRawColor(int[] array, int position, String color) { + public synchronized void setRawColor(int[] array, int position, Color color) { try { if (position < 0) { throw new Exception("Highlights.setRawColor(): Invalid position!"); @@ -202,7 +202,7 @@ public synchronized void setRawColor(int[] array, int position, String color) { boolean[] colorMark = getColorMarks(array); if (colorMark != null) { colorMark[position] = true; - getColorColors(array)[position] = getColorFromName(color); + getColorColors(array)[position] = color; } } } catch (Exception e) { @@ -211,10 +211,26 @@ public synchronized void setRawColor(int[] array, int position, String color) { arrayVisualizer.updateNow(); } - public synchronized void setRawColor(int position, String color) { + // Convenience function: Set the color using a predefined alias + public synchronized void setRawColor(int position, Color color) { setRawColor(main, position, color); } + // Convenience function: Set the color using a predefined alias + public synchronized void writeColor(int[] fromArray, int fromPosition, int[] toArray, int toPosition) { + try { + if (colorMarks.containsKey(fromArray) && colorMarks.containsKey(toArray)) { + getColorMarks(toArray)[toPosition] = getColorMarks(fromArray)[fromPosition]; + getColorColors(toArray)[toPosition] = getColorColors(fromArray)[fromPosition]; + } else { + throw new Exception("Highlights.writeColor(): One or more arrays not colorcodeable!"); + } + } catch (Exception e) { + e.printStackTrace(); + } + arrayVisualizer.updateNow(); + } + // Convenience function: Set the color using a predefined alias public synchronized void colorCode(int[] array, int position, String color) { try { @@ -233,6 +249,7 @@ public synchronized void colorCode(int[] array, int position, String color) { arrayVisualizer.updateNow(); } + // Convenience function: Set the color using a predefined alias public synchronized void colorCode(int position, String color) { colorCode(main, position, color); } From c37b2131c0d3b6ada62eca32dbaa46143579f4cc Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Fri, 4 Mar 2022 16:05:13 -0700 Subject: [PATCH 12/29] Fix non-linked ScatterPlot colorcodes --- src/main/java/io/github/arrayv/visuals/dots/ScatterPlot.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/io/github/arrayv/visuals/dots/ScatterPlot.java b/src/main/java/io/github/arrayv/visuals/dots/ScatterPlot.java index d4ddd0d6..975e2ebb 100644 --- a/src/main/java/io/github/arrayv/visuals/dots/ScatterPlot.java +++ b/src/main/java/io/github/arrayv/visuals/dots/ScatterPlot.java @@ -84,6 +84,8 @@ public void drawVisual(int[] array, ArrayVisualizer arrayVisualizer, Renderer re else if (arrayVisualizer.colorEnabled()) { int val = arrayVisualizer.doingStabilityCheck() && arrayVisualizer.colorEnabled() ? arrayVisualizer.getIndexValue(array[i]): array[i]; this.mainRender.setColor(getIntColor(val, arrayVisualizer.getCurrentLength())); + } else if (Highlights.hasColor(array, i)) { + this.mainRender.setColor(Highlights.colorAt(array, i)); } else this.mainRender.setColor(Color.WHITE); int val = arrayVisualizer.doingStabilityCheck() && arrayVisualizer.colorEnabled() ? arrayVisualizer.getStabilityValue(array[i]): array[i]; From 7098c8956ac282b833c76af0f51b0ee156b0b2b9 Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Wed, 9 Mar 2022 09:29:44 -0700 Subject: [PATCH 13/29] Add colorcoding to more visual styles --- .../io/github/arrayv/visuals/circles/DisparityCircle.java | 4 +++- src/main/java/io/github/arrayv/visuals/circles/Spiral.java | 5 +++-- .../java/io/github/arrayv/visuals/image/CustomImage.java | 5 +++++ src/main/java/io/github/arrayv/visuals/misc/HoopStack.java | 2 ++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/github/arrayv/visuals/circles/DisparityCircle.java b/src/main/java/io/github/arrayv/visuals/circles/DisparityCircle.java index 6c7aaa31..827a3dda 100644 --- a/src/main/java/io/github/arrayv/visuals/circles/DisparityCircle.java +++ b/src/main/java/io/github/arrayv/visuals/circles/DisparityCircle.java @@ -75,7 +75,9 @@ else if (Highlights.containsPosition(i)) { this.extraRender.drawPolygon(x, y, 3); } else if (arrayVisualizer.colorEnabled()) this.mainRender.setColor(getIntColor(array[i], arrayVisualizer.getCurrentLength())); - else this.mainRender.setColor(Color.WHITE); + else if (Highlights.hasColor(array, i)) { + this.mainRender.setColor(Highlights.colorAt(array, i)); + } else this.mainRender.setColor(Color.WHITE); this.mainRender.fillPolygon(x, y, 3); } diff --git a/src/main/java/io/github/arrayv/visuals/circles/Spiral.java b/src/main/java/io/github/arrayv/visuals/circles/Spiral.java index ae7817e7..776e17af 100644 --- a/src/main/java/io/github/arrayv/visuals/circles/Spiral.java +++ b/src/main/java/io/github/arrayv/visuals/circles/Spiral.java @@ -80,8 +80,9 @@ else if (Highlights.containsPosition(i)) { this.extraRender.drawPolygon(x, y, 3); } else if (arrayVisualizer.colorEnabled()) this.mainRender.setColor(getIntColor(array[i], arrayVisualizer.getCurrentLength())); - - else this.mainRender.setColor(Color.WHITE); + else if (Highlights.hasColor(array, i)) { + this.mainRender.setColor(Highlights.colorAt(array, i)); + } else this.mainRender.setColor(Color.WHITE); this.mainRender.fillPolygon(x, y, 3); } diff --git a/src/main/java/io/github/arrayv/visuals/image/CustomImage.java b/src/main/java/io/github/arrayv/visuals/image/CustomImage.java index 8a99b39d..a48f84c8 100644 --- a/src/main/java/io/github/arrayv/visuals/image/CustomImage.java +++ b/src/main/java/io/github/arrayv/visuals/image/CustomImage.java @@ -348,6 +348,11 @@ public void drawVisual(int[] array, ArrayVisualizer arrayVisualizer, Renderer re else this.mainRender.setColor(new Color(1, 0, 0, .5f)); this.mainRender.fillRect(j + 20, 40, Math.max(width, 2), arrayVisualizer.windowHeight()-10); + } else if (Highlights.hasColor(array, i)) { + Color original = Highlights.colorAt(array, i); + this.mainRender.setColor(new Color(original.getRed(), original.getGreen(), original.getBlue(), 63)); + + if (width > 0) this.mainRender.fillRect(j + 20, 40, width, arrayVisualizer.windowHeight()-10); } j += width; } diff --git a/src/main/java/io/github/arrayv/visuals/misc/HoopStack.java b/src/main/java/io/github/arrayv/visuals/misc/HoopStack.java index d918757a..f1d310eb 100644 --- a/src/main/java/io/github/arrayv/visuals/misc/HoopStack.java +++ b/src/main/java/io/github/arrayv/visuals/misc/HoopStack.java @@ -68,6 +68,8 @@ else if (Highlights.containsPosition(i)) { else this.mainRender.setColor(Color.WHITE); this.mainRender.setStroke(arrayVisualizer.getDefaultStroke()); + } else if (Highlights.hasColor(array, i)) { + this.mainRender.setColor(Highlights.colorAt(array, i)); } else this.mainRender.setColor(getIntColor(array[i], length)); this.drawEllipseFromCenter(width / 2, y + radiusY * 2, (int) (scale * radiusX + 0.5), (int) (scale * radiusY + 0.5)); From 4e9c51113d1d903f57ea5f7e7a3b45772640e577 Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Sat, 26 Mar 2022 14:56:02 -0600 Subject: [PATCH 14/29] Consistency --- src/main/java/io/github/arrayv/utils/Highlights.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index 88f19e55..016d5796 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -40,7 +40,7 @@ public final class Highlights { private volatile HashMap colorMarks; private volatile HashMap colorColors; - private volatile boolean retainColorMarks = true; + private volatile boolean retainColorMarks = false; private volatile HashMap defined; private static int[] main; From 018eda70ed13c9f1cd7652fe0c40020f67a4b535 Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Wed, 30 Mar 2022 11:40:19 -0600 Subject: [PATCH 15/29] Stepping --- .../github/arrayv/main/ArrayVisualizer.java | 4 ++ .../java/io/github/arrayv/utils/Delays.java | 49 +++++++++++++++++-- .../io/github/arrayv/utils/Highlights.java | 27 ++++++++++ 3 files changed, 76 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java index c629b7a5..c1d057f0 100644 --- a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java +++ b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java @@ -268,6 +268,8 @@ public void keyTyped(KeyEvent e) { public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_K || e.getKeyCode() == KeyEvent.VK_SPACE) { ArrayVisualizer.this.getDelays().togglePaused(); + } else if (e.getKeyCode() == KeyEvent.VK_B) { + Delays.beginStepping(); } else if (e.getKeyCode() == KeyEvent.VK_F12) { System.gc(); } @@ -493,6 +495,8 @@ public void run() { this.Writes = new Writes(this); this.antiQSort = new AntiQSort(this); + Highlights.postInit(); + SoundFrame test = new SoundFrame(this.Sounds); test.setVisible(true); diff --git a/src/main/java/io/github/arrayv/utils/Delays.java b/src/main/java/io/github/arrayv/utils/Delays.java index f7e1773f..23a649b5 100644 --- a/src/main/java/io/github/arrayv/utils/Delays.java +++ b/src/main/java/io/github/arrayv/utils/Delays.java @@ -10,6 +10,7 @@ MIT License Copyright (c) 2019 w0rthy +Copyright (c) 2020-2022 ArrayV Team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -39,6 +40,8 @@ public final class Delays { private volatile double currentDelay; private volatile boolean paused; + private volatile int noStepping; + private volatile boolean stepping; private DecimalFormat formatter; @@ -55,7 +58,7 @@ public Delays(ArrayVisualizer arrayVisualizer) { public String displayCurrentDelay() { if (this.skipped) return "Canceled"; - if (this.paused) + if (this.paused && !stepping) return "Paused"; String currDelay = ""; @@ -96,6 +99,7 @@ public void updateDelayForTimeSort(double value) { public double getSleepRatio() { return this.sleepRatio; } + public void setSleepRatio(double sleepRatio) { this.sleepRatio = sleepRatio; } @@ -103,6 +107,7 @@ public void setSleepRatio(double sleepRatio) { public boolean skipped() { return this.skipped; } + public void changeSkipped(boolean skipped) { this.skipped = skipped; if (this.skipped) this.Sounds.changeNoteDelayAndFilter(1); @@ -111,12 +116,48 @@ public void changeSkipped(boolean skipped) { public boolean paused() { return this.paused; } + public void changePaused(boolean paused) { this.paused = paused; this.Sounds.toggleSound(!paused); } + public void togglePaused() { - this.changePaused(!this.paused);; + this.changePaused(!this.paused); + } + + public void disableStepping() { + noStepping++; + if (noStepping < 0) { + noStepping = 0; + throw new IllegalStateException("Stepping toggle overflow"); + } + } + + public void enableStepping() { + noStepping--; + if (noStepping < 0) { + noStepping = 0; + throw new IllegalStateException("Stepping toggle underflow"); + } + if (canStep()) { + // Step has ended + stepping = false; + } + } + + public boolean canStep() { + return noStepping == 0; + } + + public boolean isStepping() { + return stepping; + } + + public void beginStepping() { + if (canStep()) { + stepping = true; + } } public void sleep(double millis) { @@ -132,9 +173,9 @@ public void sleep(double millis) { try { // With this for loop, you can change the speed of sorts without waiting for the current delay to finish. if (!this.skipped) { - while (this.paused || this.delay >= 1) { + while (this.delay >= 1) { Thread.sleep(1); - if (!this.paused) + if (!this.paused || stepping) this.delay--; } } else { diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index 016d5796..1e92a7ac 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -70,6 +70,7 @@ public final class Highlights { private volatile int trackFinish; private ArrayVisualizer arrayVisualizer; + private Delays Delays; public Highlights(ArrayVisualizer arrayVisualizer, int maximumLength) { this.arrayVisualizer = arrayVisualizer; @@ -94,6 +95,13 @@ public Highlights(ArrayVisualizer arrayVisualizer, int maximumLength) { this.registerColorMarks(main); } + public void postInit() { + if(Delays != null) { + throw new IllegalStateException(); + } + this.Delays = arrayVisualizer.getDelays(); + } + public boolean fancyFinishEnabled() { return this.showFancyFinishes; } @@ -200,6 +208,7 @@ public synchronized void setRawColor(int[] array, int position, Color color) { throw new Exception("Highlights.setRawColor(): Invalid position!"); } else { boolean[] colorMark = getColorMarks(array); + Delays.disableStepping(); if (colorMark != null) { colorMark[position] = true; getColorColors(array)[position] = color; @@ -209,6 +218,7 @@ public synchronized void setRawColor(int[] array, int position, Color color) { e.printStackTrace(); } arrayVisualizer.updateNow(); + Delays.enableStepping(); } // Convenience function: Set the color using a predefined alias @@ -219,6 +229,7 @@ public synchronized void setRawColor(int position, Color color) { // Convenience function: Set the color using a predefined alias public synchronized void writeColor(int[] fromArray, int fromPosition, int[] toArray, int toPosition) { try { + Delays.disableStepping(); if (colorMarks.containsKey(fromArray) && colorMarks.containsKey(toArray)) { getColorMarks(toArray)[toPosition] = getColorMarks(fromArray)[fromPosition]; getColorColors(toArray)[toPosition] = getColorColors(fromArray)[fromPosition]; @@ -229,6 +240,7 @@ public synchronized void writeColor(int[] fromArray, int fromPosition, int[] toA e.printStackTrace(); } arrayVisualizer.updateNow(); + Delays.enableStepping(); } // Convenience function: Set the color using a predefined alias @@ -238,6 +250,7 @@ public synchronized void colorCode(int[] array, int position, String color) { throw new Exception("Highlights.colorCode(): Invalid position!"); } else { boolean[] colorMark = getColorMarks(array); + Delays.disableStepping(); if (colorMark != null) { colorMark[position] = true; getColorColors(array)[position] = getColorFromName(color); @@ -245,8 +258,10 @@ public synchronized void colorCode(int[] array, int position, String color) { } } catch (Exception e) { e.printStackTrace(); + return; } arrayVisualizer.updateNow(); + Delays.enableStepping(); } // Convenience function: Set the color using a predefined alias @@ -270,10 +285,13 @@ public synchronized void clearColor(int[] array, int position) { boolean[] colorMark = getColorMarks(array); if (colorMark == null) return; + Delays.disableStepping(); if (colorMark[position]) { colorMark[position] = false; getColorColors(array)[position] = null; } + arrayVisualizer.updateNow(); + Delays.enableStepping(); } public synchronized void clearColor(int position) { @@ -322,6 +340,7 @@ public synchronized void markArray(int marker, int markPosition) { if (highlights[marker] == markPosition) { return; } + Delays.disableStepping(); if (highlights[marker] != -1) { decrementIndexMarkCount(highlights[marker]); } @@ -339,11 +358,13 @@ public synchronized void markArray(int marker, int markPosition) { e.printStackTrace(); } arrayVisualizer.updateNow(); + Delays.enableStepping(); } public synchronized void clearMark(int marker) { if (highlights[marker] == -1) { return; } + Delays.disableStepping(); if (!retainColorMarks) { clearColor(highlights[marker]); } @@ -356,6 +377,7 @@ public synchronized void clearMark(int marker) { } } arrayVisualizer.updateNow(); + Delays.enableStepping(); } public synchronized void clearColorList() { @@ -364,7 +386,10 @@ public synchronized void clearColorList() { } public synchronized void clearAllColors(int[] array) { + Delays.disableStepping(); Arrays.fill(getColorMarks(array), false); + arrayVisualizer.updateNow(); + Delays.enableStepping(); } public synchronized void clearAllColors() { @@ -378,6 +403,7 @@ public synchronized void clearAllColorsReferenced() { } public synchronized void clearAllMarks() { + Delays.disableStepping(); for (int i = 0; i < this.maxHighlightMarked; i++) { if (highlights[i] != -1) { markCounts[highlights[i]] = 0; @@ -387,6 +413,7 @@ public synchronized void clearAllMarks() { this.maxHighlightMarked = 0; this.markCount = 0; arrayVisualizer.updateNow(); + Delays.enableStepping(); } public synchronized boolean isRetainingColorMarks() { From 6bfed0b78428ef10051199bf82aa001372af5a66 Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Wed, 30 Mar 2022 11:47:26 -0600 Subject: [PATCH 16/29] Resolve conflicts attempt 1 --- .../io/github/arrayv/utils/Highlights.java | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index 1e92a7ac..e09349f8 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -365,9 +365,12 @@ public synchronized void clearMark(int marker) { return; } Delays.disableStepping(); + + // conflict #1: I have no idea how to fix this one if (!retainColorMarks) { clearColor(highlights[marker]); } + decrementIndexMarkCount(highlights[marker]); highlights[marker] = -1; // -1 is used as the magic number to unmark a position in the main array if (marker == this.maxHighlightMarked) { @@ -380,6 +383,8 @@ public synchronized void clearMark(int marker) { Delays.enableStepping(); } + // conflict #2: This should not happen + public synchronized void clearColorList() { defined.clear(); retainColorMarks = false; @@ -402,6 +407,14 @@ public synchronized void clearAllColorsReferenced() { } } + public synchronized boolean isRetainingColorMarks() { + return retainColorMarks; + } + + public synchronized void retainColorMarks(boolean retainColorMarks) { + this.retainColorMarks = retainColorMarks; + } + public synchronized void clearAllMarks() { Delays.disableStepping(); for (int i = 0; i < this.maxHighlightMarked; i++) { @@ -415,12 +428,4 @@ public synchronized void clearAllMarks() { arrayVisualizer.updateNow(); Delays.enableStepping(); } - - public synchronized boolean isRetainingColorMarks() { - return retainColorMarks; - } - - public synchronized void retainColorMarks(boolean retainColorMarks) { - this.retainColorMarks = retainColorMarks; - } } From 62ff332155c5640165bec0f721366c12c743765f Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Wed, 30 Mar 2022 11:53:45 -0600 Subject: [PATCH 17/29] Resolve conflicts attempt 2 GitHub is being stubborn --- .../io/github/arrayv/utils/Highlights.java | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index e09349f8..ed444c58 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -330,6 +330,7 @@ public void swapColors(int[] array, int locA, int locB) { public void swapColors(int locA, int locB) { swapColors(main, locA, locB); } + public synchronized void markArray(int marker, int markPosition) { try { if (markPosition < 0) { @@ -360,6 +361,7 @@ public synchronized void markArray(int marker, int markPosition) { arrayVisualizer.updateNow(); Delays.enableStepping(); } + public synchronized void clearMark(int marker) { if (highlights[marker] == -1) { return; @@ -385,35 +387,35 @@ public synchronized void clearMark(int marker) { // conflict #2: This should not happen - public synchronized void clearColorList() { - defined.clear(); - retainColorMarks = false; - } - - public synchronized void clearAllColors(int[] array) { - Delays.disableStepping(); - Arrays.fill(getColorMarks(array), false); - arrayVisualizer.updateNow(); - Delays.enableStepping(); - } - - public synchronized void clearAllColors() { - clearAllColors(main); - } - - public synchronized void clearAllColorsReferenced() { - for (boolean[] list : colorMarks.values()) { - Arrays.fill(list, false); - } - } - - public synchronized boolean isRetainingColorMarks() { - return retainColorMarks; - } - - public synchronized void retainColorMarks(boolean retainColorMarks) { - this.retainColorMarks = retainColorMarks; - } + public synchronized void clearColorList() { + defined.clear(); + retainColorMarks = false; + } + + public synchronized void clearAllColors(int[] array) { + Delays.disableStepping(); + Arrays.fill(getColorMarks(array), false); + arrayVisualizer.updateNow(); + Delays.enableStepping(); + } + + public synchronized void clearAllColors() { + clearAllColors(main); + } + + public synchronized void clearAllColorsReferenced() { + for (boolean[] list : colorMarks.values()) { + Arrays.fill(list, false); + } + } + + public synchronized boolean isRetainingColorMarks() { + return retainColorMarks; + } + + public synchronized void retainColorMarks(boolean retainColorMarks) { + this.retainColorMarks = retainColorMarks; + } public synchronized void clearAllMarks() { Delays.disableStepping(); From cc9ad39b71f6eb6e04dc4e19bb99a723c06db902 Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Wed, 30 Mar 2022 11:56:54 -0600 Subject: [PATCH 18/29] Resolve conflicts attempt 3 Seriously, GitHub? --- src/main/java/io/github/arrayv/utils/Highlights.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index ed444c58..6e9f063b 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -366,13 +366,12 @@ public synchronized void clearMark(int marker) { if (highlights[marker] == -1) { return; } - Delays.disableStepping(); - - // conflict #1: I have no idea how to fix this one if (!retainColorMarks) { clearColor(highlights[marker]); } + Delays.disableStepping(); + decrementIndexMarkCount(highlights[marker]); highlights[marker] = -1; // -1 is used as the magic number to unmark a position in the main array if (marker == this.maxHighlightMarked) { @@ -385,7 +384,7 @@ public synchronized void clearMark(int marker) { Delays.enableStepping(); } - // conflict #2: This should not happen + // *fix conflict #2: spaces added to separate stupidity* public synchronized void clearColorList() { defined.clear(); From dfdbabff0464ec3b32892169d811e397e46aff55 Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Wed, 30 Mar 2022 11:58:23 -0600 Subject: [PATCH 19/29] Resolve conflicts attempt 4 This is getting stupid --- src/main/java/io/github/arrayv/utils/Highlights.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index 6e9f063b..1a066a6e 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -366,13 +366,11 @@ public synchronized void clearMark(int marker) { if (highlights[marker] == -1) { return; } + Delays.disableStepping(); + decrementIndexMarkCount(highlights[marker]); if (!retainColorMarks) { clearColor(highlights[marker]); } - - Delays.disableStepping(); - - decrementIndexMarkCount(highlights[marker]); highlights[marker] = -1; // -1 is used as the magic number to unmark a position in the main array if (marker == this.maxHighlightMarked) { this.maxHighlightMarked = marker; From a0ba5074c7beb1be046033c0dd2b2801738ace6d Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Wed, 30 Mar 2022 12:04:57 -0600 Subject: [PATCH 20/29] "Fix" checkstyle --- src/main/java/io/github/arrayv/utils/Highlights.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index 1a066a6e..3e77de2f 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -96,7 +96,7 @@ public Highlights(ArrayVisualizer arrayVisualizer, int maximumLength) { } public void postInit() { - if(Delays != null) { + if (Delays != null) { throw new IllegalStateException(); } this.Delays = arrayVisualizer.getDelays(); @@ -382,7 +382,7 @@ public synchronized void clearMark(int marker) { Delays.enableStepping(); } - // *fix conflict #2: spaces added to separate stupidity* + // @checkstyle:off Indentation - Creates a merge conflict without the extra space public synchronized void clearColorList() { defined.clear(); @@ -414,6 +414,8 @@ public synchronized void retainColorMarks(boolean retainColorMarks) { this.retainColorMarks = retainColorMarks; } + // @checkstyle:on Indentation + public synchronized void clearAllMarks() { Delays.disableStepping(); for (int i = 0; i < this.maxHighlightMarked; i++) { From b7fa84760444028623cb749629b717a37d441d92 Mon Sep 17 00:00:00 2001 From: "Josiah (Gaming32) Glosson" Date: Wed, 30 Mar 2022 19:57:21 -0500 Subject: [PATCH 21/29] If Git is causing issues, that doesn't mean checkstyle should be ignored We'll see if we can work out a better solution. --- .../io/github/arrayv/utils/Highlights.java | 63 +++++++++---------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index 3e77de2f..38f1671d 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -382,39 +382,36 @@ public synchronized void clearMark(int marker) { Delays.enableStepping(); } - // @checkstyle:off Indentation - Creates a merge conflict without the extra space - - public synchronized void clearColorList() { - defined.clear(); - retainColorMarks = false; - } - - public synchronized void clearAllColors(int[] array) { - Delays.disableStepping(); - Arrays.fill(getColorMarks(array), false); - arrayVisualizer.updateNow(); - Delays.enableStepping(); - } - - public synchronized void clearAllColors() { - clearAllColors(main); - } - - public synchronized void clearAllColorsReferenced() { - for (boolean[] list : colorMarks.values()) { - Arrays.fill(list, false); - } - } - - public synchronized boolean isRetainingColorMarks() { - return retainColorMarks; - } - - public synchronized void retainColorMarks(boolean retainColorMarks) { - this.retainColorMarks = retainColorMarks; - } - - // @checkstyle:on Indentation + + public synchronized void clearColorList() { + defined.clear(); + retainColorMarks = false; + } + + public synchronized void clearAllColors(int[] array) { + Delays.disableStepping(); + Arrays.fill(getColorMarks(array), false); + arrayVisualizer.updateNow(); + Delays.enableStepping(); + } + + public synchronized void clearAllColors() { + clearAllColors(main); + } + + public synchronized void clearAllColorsReferenced() { + for (boolean[] list : colorMarks.values()) { + Arrays.fill(list, false); + } + } + + public synchronized boolean isRetainingColorMarks() { + return retainColorMarks; + } + + public synchronized void retainColorMarks(boolean retainColorMarks) { + this.retainColorMarks = retainColorMarks; + } public synchronized void clearAllMarks() { Delays.disableStepping(); From 11bc21b68f816ba19c7ee694bf767c5d4f3c2a97 Mon Sep 17 00:00:00 2001 From: "Josiah (Gaming32) Glosson" Date: Wed, 30 Mar 2022 20:01:55 -0500 Subject: [PATCH 22/29] Fix oddly duplicated code Git, what the heck? --- .../java/io/github/arrayv/utils/Delays.java | 34 ------------------- .../io/github/arrayv/utils/Highlights.java | 7 ---- 2 files changed, 41 deletions(-) diff --git a/src/main/java/io/github/arrayv/utils/Delays.java b/src/main/java/io/github/arrayv/utils/Delays.java index c6349b0b..23a649b5 100644 --- a/src/main/java/io/github/arrayv/utils/Delays.java +++ b/src/main/java/io/github/arrayv/utils/Delays.java @@ -160,40 +160,6 @@ public void beginStepping() { } } - public void disableStepping() { - noStepping++; - if (noStepping < 0) { - noStepping = 0; - throw new IllegalStateException("Stepping toggle overflow"); - } - } - - public void enableStepping() { - noStepping--; - if (noStepping < 0) { - noStepping = 0; - throw new IllegalStateException("Stepping toggle underflow"); - } - if (canStep()) { - // Step has ended - stepping = false; - } - } - - public boolean canStep() { - return noStepping == 0; - } - - public boolean isStepping() { - return stepping; - } - - public void beginStepping() { - if (canStep()) { - stepping = true; - } - } - public void sleep(double millis) { if (millis <= 0) { return; diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index 414f2902..38f1671d 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -102,13 +102,6 @@ public void postInit() { this.Delays = arrayVisualizer.getDelays(); } - public void postInit() { - if (Delays != null) { - throw new IllegalStateException(); - } - this.Delays = arrayVisualizer.getDelays(); - } - public boolean fancyFinishEnabled() { return this.showFancyFinishes; } From 078cdde58ba07a70ce9b3bd0e635375a58782890 Mon Sep 17 00:00:00 2001 From: "Josiah (Gaming32) Glosson" Date: Sat, 2 Apr 2022 19:47:00 -0500 Subject: [PATCH 23/29] Polymorphism --- src/main/java/io/github/arrayv/utils/Highlights.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index 38f1671d..943c0c2c 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -5,6 +5,7 @@ import io.github.arrayv.main.ArrayVisualizer; import io.github.arrayv.panes.JErrorPane; import java.util.HashMap; +import java.util.Map; /* * @@ -37,12 +38,12 @@ public final class Highlights { private volatile byte[] markCounts; // This is in desperate need of optimization. - private volatile HashMap colorMarks; - private volatile HashMap colorColors; + private volatile Map colorMarks; + private volatile Map colorColors; private volatile boolean retainColorMarks = false; - private volatile HashMap defined; + private volatile Map defined; private static int[] main; private volatile int maxHighlightMarked; // IMPORTANT: This stores the index one past the farthest highlight used, so that a value From e1587fae1c395a8881d14d4734fdcd816e046700 Mon Sep 17 00:00:00 2001 From: "Josiah (Gaming32) Glosson" Date: Sat, 2 Apr 2022 19:53:35 -0500 Subject: [PATCH 24/29] Some slight optimizations --- .../io/github/arrayv/main/ArrayVisualizer.java | 2 +- .../java/io/github/arrayv/utils/Highlights.java | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java index c1d057f0..76c3766e 100644 --- a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java +++ b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java @@ -726,7 +726,7 @@ private void drawStats(Color textColor, boolean dropShadow) { stat = null; // Unreachable } mainRender.drawString(stat, xOffset, (int)(windowRatio * yPos) + yOffset); - if (step++ == 0 && Highlights.getDeclaredColors().length > 0) { + if (step++ == 0 && Highlights.getDeclaredColors().size() > 0) { int startOffset = currentWidth(), copy = startOffset, metricFontHeight = mainRender.getFontMetrics().getHeight(), startStat = mainRender.getFontMetrics().stringWidth(stat) + xOffset + 24, diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index 943c0c2c..fba5820c 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -5,7 +5,9 @@ import io.github.arrayv.main.ArrayVisualizer; import io.github.arrayv.panes.JErrorPane; import java.util.HashMap; +import java.util.IdentityHashMap; import java.util.Map; +import java.util.Set; /* * @@ -80,8 +82,8 @@ public Highlights(ArrayVisualizer arrayVisualizer, int maximumLength) { defined = new HashMap<>(); this.highlights = new int[maximumLength]; this.markCounts = new byte[maximumLength]; - this.colorMarks = new HashMap<>(); - this.colorColors = new HashMap<>(); + this.colorMarks = new IdentityHashMap<>(); + this.colorColors = new IdentityHashMap<>(); } catch (OutOfMemoryError e) { JErrorPane.invokeCustomErrorMessage("Failed to allocate mark arrays. The program will now exit."); System.exit(1); @@ -173,8 +175,8 @@ public boolean containsPosition(int arrayPosition) { if (arrayPosition >= markCounts.length) return false; return this.markCounts[arrayPosition] != 0; } - public String[] getDeclaredColors() { - return defined.keySet().toArray(new String[0]); + public Set getDeclaredColors() { + return defined.keySet(); } public Color getColorFromName(String color) { return defined.getOrDefault(color, Color.WHITE); @@ -197,10 +199,8 @@ public synchronized void registerColorMarks(int[] array) { colorColors.putIfAbsent(array, colorColor); } public synchronized void unregisterColors(int[] array) { - if (colorMarks.containsKey(array)) { - colorMarks.remove(array); - colorColors.remove(array); - } + colorMarks.remove(array); + colorColors.remove(array); } // Ambitious function: Set the color directly public synchronized void setRawColor(int[] array, int position, Color color) { From ee77bb6a29a213e766c240f9dca1d6d5532bb798 Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Wed, 28 Feb 2024 15:27:37 -0700 Subject: [PATCH 25/29] Fix conflicts attempt 1 oops! bad coding practice --- .../github/arrayv/main/ArrayVisualizer.java | 26 ++++++++++++------- .../io/github/arrayv/utils/ArrayVList.java | 17 +++--------- .../io/github/arrayv/utils/Highlights.java | 5 ++-- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java index 76c3766e..04306181 100644 --- a/src/main/java/io/github/arrayv/main/ArrayVisualizer.java +++ b/src/main/java/io/github/arrayv/main/ArrayVisualizer.java @@ -664,6 +664,8 @@ public void refreshSorts() { private void drawStats(Color textColor, boolean dropShadow) { int xOffset = 15; int yOffset = 30; + int drawingFirstStat = 1; + if (dropShadow) { xOffset += 3; yOffset += 3; @@ -674,15 +676,13 @@ private void drawStats(Color textColor, boolean dropShadow) { this.mainRender.setColor(textColor); - int step = 0; - statLoop: for (StatisticType statType : statsConfig) { // System.out.println(yPos); String stat; switch (statType) { case LINE_BREAK: yPos += (int)(fontSelectionScale / 25.0 * 15); - continue statLoop; + continue; case SORT_IDENTITY: stat = statSnapshot.getSortIdentity(); break; @@ -726,26 +726,34 @@ private void drawStats(Color textColor, boolean dropShadow) { stat = null; // Unreachable } mainRender.drawString(stat, xOffset, (int)(windowRatio * yPos) + yOffset); - if (step++ == 0 && Highlights.getDeclaredColors().size() > 0) { - int startOffset = currentWidth(), - copy = startOffset, metricFontHeight = mainRender.getFontMetrics().getHeight(), + + if (drawingFirstStat == 1 && Highlights.getDeclaredColors().size() > 0) { + int startOffset = currentWidth(), metricFontHeight = mainRender.getFontMetrics().getHeight(), startStat = mainRender.getFontMetrics().stringWidth(stat) + xOffset + 24, copyYPos = (int)(windowRatio * yPos) + yOffset, textWidth; + for (String color : Highlights.getDeclaredColors()) { textWidth = mainRender.getFontMetrics().stringWidth(color); startOffset -= textWidth + metricFontHeight + 20; if (startOffset <= startStat) { - startOffset = copy - textWidth - metricFontHeight - 20; + startOffset = currentWidth() - textWidth - metricFontHeight - 20; copyYPos += metricFontHeight + 8; } - if (!dropShadow) + + if (!dropShadow) { mainRender.setColor(Highlights.getColorFromName(color)); + } + mainRender.fillRect(startOffset, copyYPos - metricFontHeight + (metricFontHeight / 3), metricFontHeight, metricFontHeight); - if (!dropShadow) + + if (!dropShadow) { mainRender.setColor(textColor); + } + mainRender.drawString(color, startOffset + metricFontHeight + 6, copyYPos); } } + drawingFirstStat = 0; yPos += fontSelectionScale; } } diff --git a/src/main/java/io/github/arrayv/utils/ArrayVList.java b/src/main/java/io/github/arrayv/utils/ArrayVList.java index 9bc9e995..cf234d26 100644 --- a/src/main/java/io/github/arrayv/utils/ArrayVList.java +++ b/src/main/java/io/github/arrayv/utils/ArrayVList.java @@ -1,22 +1,11 @@ package io.github.arrayv.utils; +import io.github.arrayv.main.ArrayVisualizer; + import java.awt.Color; -import java.util.AbstractList; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.NoSuchElementException; -import java.util.Objects; -import java.util.RandomAccess; -import java.util.Spliterator; +import java.util.*; import java.util.function.Consumer; -import io.github.arrayv.main.ArrayVisualizer; - public class ArrayVList extends AbstractList implements RandomAccess, Cloneable, java.io.Serializable { private static final int DEFAULT_CAPACITY = 128; private static final double DEFAULT_GROW_FACTOR = 2; diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index fba5820c..b1725c4b 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -1,14 +1,15 @@ package io.github.arrayv.utils; -import java.util.Arrays; -import java.awt.Color; import io.github.arrayv.main.ArrayVisualizer; import io.github.arrayv.panes.JErrorPane; +import java.awt.Color; import java.util.HashMap; import java.util.IdentityHashMap; import java.util.Map; import java.util.Set; +import java.util.Arrays; + /* * MIT License From fc62dff34c55223244f5457c16a77ba0e3cf06fe Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Wed, 28 Feb 2024 15:36:44 -0700 Subject: [PATCH 26/29] Fix conflicts attempt 2 AtomicInteger-related type changes I desperately want to avoid a conflict for and removing an interface from ArrayVlist --- .../io/github/arrayv/utils/ArrayVList.java | 3 ++- .../io/github/arrayv/utils/Highlights.java | 21 ++++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/main/java/io/github/arrayv/utils/ArrayVList.java b/src/main/java/io/github/arrayv/utils/ArrayVList.java index cf234d26..0329a483 100644 --- a/src/main/java/io/github/arrayv/utils/ArrayVList.java +++ b/src/main/java/io/github/arrayv/utils/ArrayVList.java @@ -3,10 +3,11 @@ import io.github.arrayv.main.ArrayVisualizer; import java.awt.Color; + import java.util.*; import java.util.function.Consumer; -public class ArrayVList extends AbstractList implements RandomAccess, Cloneable, java.io.Serializable { +public class ArrayVList extends AbstractList implements RandomAccess, java.io.Serializable { private static final int DEFAULT_CAPACITY = 128; private static final double DEFAULT_GROW_FACTOR = 2; diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index b1725c4b..295f8b57 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -9,6 +9,7 @@ import java.util.Set; import java.util.Arrays; +import java.util.concurrent.atomic.AtomicInteger; /* * @@ -67,11 +68,11 @@ public final class Highlights { // This way, the program runs more efficiently, and looks pretty. :) - private volatile int markCount; + private final AtomicInteger markCount; private boolean showFancyFinishes; private volatile boolean fancyFinish; - private volatile int trackFinish; + private final AtomicInteger trackFinish = new AtomicInteger(); private ArrayVisualizer arrayVisualizer; private Delays Delays; @@ -91,7 +92,7 @@ public Highlights(ArrayVisualizer arrayVisualizer, int maximumLength) { } this.showFancyFinishes = true; this.maxHighlightMarked = 0; - this.markCount = 0; + this.markCount = new AtomicInteger(); this.main = arrayVisualizer.getArray(); Arrays.fill(highlights, -1); @@ -121,13 +122,13 @@ public void toggleFancyFinish(boolean fancyFinish) { } public int getFancyFinishPosition() { - return this.trackFinish; + return this.trackFinish.get(); } public void incrementFancyFinishPosition() { - this.trackFinish++; + this.trackFinish.incrementAndGet(); } public void resetFancyFinish() { - this.trackFinish = -1; // Magic number that clears the green sweep animation + this.trackFinish.set(-1); // Magic number that clears the green sweep animation } public void toggleAnalysis(boolean analysis) { @@ -138,14 +139,14 @@ public int getMaxHighlight() { return this.maxHighlightMarked; } public int getMarkCount() { - return this.markCount; + return this.markCount.get(); } private void incrementIndexMarkCount(int i) { if (i >= markCounts.length) return; if (markCounts[i] != (byte)-1) { if (markCounts[i] == 0) { - markCount++; + markCount.incrementAndGet(); } markCounts[i]++; } @@ -163,7 +164,7 @@ private void decrementIndexMarkCount(int i) { } } } else if (markCounts[i] == 0) { - markCount--; + markCount.decrementAndGet(); } markCounts[i]--; } @@ -424,7 +425,7 @@ public synchronized void clearAllMarks() { } Arrays.fill(this.highlights, 0, this.maxHighlightMarked, -1); this.maxHighlightMarked = 0; - this.markCount = 0; + this.markCount.set(0); arrayVisualizer.updateNow(); Delays.enableStepping(); } From f1bc5bd1183e8b4646a7d7e57192d3a86c74d455 Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Wed, 28 Feb 2024 15:42:10 -0700 Subject: [PATCH 27/29] Fix conflicts attempt 3 _why doesn't it want me to change the packages imported for ArrayVList_ --- src/main/java/io/github/arrayv/utils/ArrayVList.java | 4 ++-- src/main/java/io/github/arrayv/utils/Highlights.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/github/arrayv/utils/ArrayVList.java b/src/main/java/io/github/arrayv/utils/ArrayVList.java index 0329a483..a9fd7a02 100644 --- a/src/main/java/io/github/arrayv/utils/ArrayVList.java +++ b/src/main/java/io/github/arrayv/utils/ArrayVList.java @@ -2,11 +2,11 @@ import io.github.arrayv.main.ArrayVisualizer; -import java.awt.Color; - import java.util.*; import java.util.function.Consumer; +import java.awt.Color; + public class ArrayVList extends AbstractList implements RandomAccess, java.io.Serializable { private static final int DEFAULT_CAPACITY = 128; private static final double DEFAULT_GROW_FACTOR = 2; diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index 295f8b57..17f9bea5 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -93,7 +93,8 @@ public Highlights(ArrayVisualizer arrayVisualizer, int maximumLength) { this.showFancyFinishes = true; this.maxHighlightMarked = 0; this.markCount = new AtomicInteger(); - this.main = arrayVisualizer.getArray(); + + main = arrayVisualizer.getArray(); // Colorcoding shorthand thing Arrays.fill(highlights, -1); Arrays.fill(markCounts, (byte)0); From 210e48746ccde0d23172fee7a6bfaf6d36356471 Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Wed, 28 Feb 2024 15:51:52 -0700 Subject: [PATCH 28/29] Fix conflicts attempt 4 the conflict checker is running off black magic and all the spells in it are specifically against pushing Groovy support into this PR --- src/main/java/io/github/arrayv/utils/ArrayVList.java | 4 ++-- src/main/java/io/github/arrayv/utils/Highlights.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/github/arrayv/utils/ArrayVList.java b/src/main/java/io/github/arrayv/utils/ArrayVList.java index a9fd7a02..fa9f2553 100644 --- a/src/main/java/io/github/arrayv/utils/ArrayVList.java +++ b/src/main/java/io/github/arrayv/utils/ArrayVList.java @@ -1,12 +1,12 @@ package io.github.arrayv.utils; +import java.awt.Color; // i beg of you stop rejecting this import + import io.github.arrayv.main.ArrayVisualizer; import java.util.*; import java.util.function.Consumer; -import java.awt.Color; - public class ArrayVList extends AbstractList implements RandomAccess, java.io.Serializable { private static final int DEFAULT_CAPACITY = 128; private static final double DEFAULT_GROW_FACTOR = 2; diff --git a/src/main/java/io/github/arrayv/utils/Highlights.java b/src/main/java/io/github/arrayv/utils/Highlights.java index 17f9bea5..b62f9169 100644 --- a/src/main/java/io/github/arrayv/utils/Highlights.java +++ b/src/main/java/io/github/arrayv/utils/Highlights.java @@ -48,7 +48,7 @@ public final class Highlights { private volatile boolean retainColorMarks = false; private volatile Map defined; - private static int[] main; + private final int[] main; private volatile int maxHighlightMarked; // IMPORTANT: This stores the index one past the farthest highlight used, so that a value // of 0 means no highlights are in use, and iteration is more convenient. @@ -94,10 +94,10 @@ public Highlights(ArrayVisualizer arrayVisualizer, int maximumLength) { this.maxHighlightMarked = 0; this.markCount = new AtomicInteger(); - main = arrayVisualizer.getArray(); // Colorcoding shorthand thing - Arrays.fill(highlights, -1); Arrays.fill(markCounts, (byte)0); + + this.main = arrayVisualizer.getArray(); // I refuse to remove this line of code without putting up a fight this.registerColorMarks(main); } @@ -299,7 +299,7 @@ public synchronized void clearColor(int[] array, int position) { } public synchronized void clearColor(int position) { - clearColor(main, position); + clearColor(this.main, position); } public synchronized boolean hasColor(int[] array, int position) { From 9d8f799a01475e6ec64a7a6967f6908b328ee551 Mon Sep 17 00:00:00 2001 From: distay0xGit <39865752+distay0xGit@users.noreply.github.com> Date: Wed, 28 Feb 2024 15:58:02 -0700 Subject: [PATCH 29/29] Fix conflicts attempt 5 I just hope I can revert this weird hack after this PR is brought up to speed with all the changes in main --- src/main/java/io/github/arrayv/utils/ArrayVList.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/io/github/arrayv/utils/ArrayVList.java b/src/main/java/io/github/arrayv/utils/ArrayVList.java index fa9f2553..8a093182 100644 --- a/src/main/java/io/github/arrayv/utils/ArrayVList.java +++ b/src/main/java/io/github/arrayv/utils/ArrayVList.java @@ -1,7 +1,5 @@ package io.github.arrayv.utils; -import java.awt.Color; // i beg of you stop rejecting this import - import io.github.arrayv.main.ArrayVisualizer; import java.util.*; @@ -152,7 +150,7 @@ public void colorCode(String alias, int... positions) { } } - public void rawColorCode(int position, Color color) { + public void rawColorCode(int position, java.awt.Color color) { // i am appalled at the lengths git wants to go to stop me from using the Color class try { if (!colorsEnabled) { throw new Exception("ArrayVList.rawColorCode(): List can't be colorcoded!");