diff --git a/.classpath b/.classpath
index a948582b..7b88b967 100644
--- a/.classpath
+++ b/.classpath
@@ -1,13 +1,7 @@
-
-
-
-
-
-
-
+
diff --git a/.gitignore b/.gitignore
index 5241a722..cee99345 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-*.class
\ No newline at end of file
+*.class
+/bin/
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index c8c17f8b..3926e52f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,7 @@
MIT License
Copyright (c) 2019 w0rthy
-Copyright (c) 2019 MusicTheorist
+Copyright (c) 2020 MusicTheorist
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index e596d4ba..e06f4f94 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,21 @@
# w0rthy's Array Visualizer, Revamped
[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=Q5QLCFZ8G7WY6¤cy_code=USD&source=url)
-76 sorting algorithms demonstrated through 10 unique graphic designs
+**DEPRECATED** - Visit the new home of ArrayV over here where I'll be contributing from time to time! https://github.com/Gaming32/ArrayV-v4.0
+I'll be working on a brand new algorithm visualizer of my own over the next few months, so stay tuned... Visit our community Discord for updates!!
+
+Over 75 sorting algorithms animated with 12 unique graphic designs
+
+Follow the project's development behind-the-scenes in our Discord: https://discord.com/invite/2xGkKC2
This new version of the program features additions inspired by Timo Bingmann's "The Sound of Sorting" and w0rthy's updates to the original visualizer.
-To build (After -cp, use ";" with Windows and ":" with Mac/Linux):
+To compile (After -cp, use ";" with Windows and ":" with Mac/Linux):
```
ant
java -cp bin;lib/classgraph-4.8.47.jar main.ArrayVisualizer
```
+To build a runnable jar, simply run Apache Ant inside the 'dist' directory!
### Features:
- 40+ new sorting algorithms
@@ -23,6 +29,65 @@ java -cp bin;lib/classgraph-4.8.47.jar main.ArrayVisualizer
- Toggle Timo Bingmann's "end sweep" animation
- Refactored / optimized code
+## 6/8/2020 - Version 3.5
+- NEW VISUALS: Sine Wave and Wave Dots!!
+- New sort: Bogobogosort
+- The bogo shuffle method is now unbiased
+- MultipleSortThreads further refactored
+- Visuals, VisualStyles enum, and Renderer significantly refactored (more to come!)
+
+## 6/4/2020 - Version 3.2
+- New sort: Optimized Cocktail Shaker Sort
+- Significant refactoring for MultipleSortThreads and RunAllSorts
+- "Run All" button approx. time simplified
+- Modified delays for Binary Gnomesort
+- Documentation of GCC's median-of-three pivot selection in Introsort
+
+## 6/3/2020 - Version 3.12
+- Counting Sort fixed
+- Optimized Bubblesort now optimized for already sorted inputs
+- Speeds for Quicksorts and Weave Merge during "Run All Sorts" improved
+
+## 6/2/2020 - Version 3.11
+- Minor update to MIT license
+- Fixed typo in Flipped Min Heapsort
+- Improved highlights on Heapsorts (Already sorted heaps now display redundant comparisons)
+- Bug fix for Patiencesort on reversed arrays
+- Quicksorts exhibiting worst-case behavior during "Run All Sorts" run much faster
+- Same tweak as above to Weave Merge Sort
+
+## 5/30/2020 - Version 3.1
+- Error messages with detailed information will now appear within the program!
+- Sound effects are now consistent on all platforms
+- New sort: "Flipped Min Heap Sort" by 'landfillbaby'!
+- Minor changes to code organization
+- New webhook to my Discord server! Check it out here: https://discord.com/invite/2xGkKC2
+
+## 5/22/2020 - Version 3.01
+- Quick bug fix to the "Linked Dots" visual;
+ The first line is no longer horizontal.
+
+## 5/21/2020 - Version 3.0 is now released!
+- Sound effects are much more pleasant at slower speeds
+- Revamped "Run All Sorts" (It is now easier to create your own sequence of sorts!)
+- More accurate delay algorithm
+- Improved random shuffle algorithm (now with 0% bias!)
+- Cleaner statistics
+- Sort an array up to 16,384 (2^14) numbers!
+- The "green sweep" animation also verifies an array is properly sorted after watching a sort.
+ If a sort fails, a warning message pops up, highlighting where the first out-of-order item is.
+- Minor tweak to the sort time method. It should be a slight bit more accurate now.
+- Slowsort and Sillysort's comparisons are now shown.
+- Gravity Sort has a more detailed visual now
+- Pancake Sorting is fixed
+- Counting Sort is fixed
+- Holy Grail Sort is enabled, but just note that it's a mock algorithm; not finished yet.
+- "Auxillary" typo fixed; program now says 'Writes to Auxiliary Array(s)'
+- Bug fixes and minor tweaks
+ - Minor fixes to "Skip Sort" button
+ - Weird static line bug with linked dots squashed
+ - Other miscellaneous fixes and changes here and there
+
## 10/19/2019 - Version 2.1
- Both Odd-Even Mergesorts now display comparisons
- PDQSort's Insertion Sorts have been slowed down
@@ -74,7 +139,6 @@ java -cp bin;lib/classgraph-4.8.47.jar main.ArrayVisualizer
**KNOWN BUGS:**
- Certain sorts (comb sort, radix sorts) cause the program to forget the current speed
- Certain sorts do not work with the "Skip Sort" button
-- Linked Dots visual has an extra, static line
- Missing soundfont
- SkaSort and HolyGrailSort produce errors -- this is normal, they aren't finished yet
- No circular pointer -- will be fixed soon
@@ -96,14 +160,12 @@ java -cp bin;lib/classgraph-4.8.47.jar main.ArrayVisualizer
- Organize list of sorts into more categories
- Run All Sorts in specific category
- Subheadings for customizable sorts (e.g. display the number of buckets during a bucket sort)
-- Justified statistics(??)
-- Sort an array up to 16,384 (2^14) numbers
- "Many Similar" distribution ((i/5) * 5, as an example)
+- "Pipe organ" distribution (half ascending, half descending)
- Fixed circular pointer with much cleaner math
- Toogle between pointer and black bar with circular visuals
- Refactor/reorganize prompts and frames
- Cleaner:
- - Counting Sort
- Tree Sort
- getters/setters
- method parameters
diff --git a/bin/SortPrompt.form b/bin/SortPrompt.form
deleted file mode 100644
index 08d82518..00000000
--- a/bin/SortPrompt.form
+++ /dev/null
@@ -1,138 +0,0 @@
-
-
-
diff --git a/bin/UtilFrame.form b/bin/UtilFrame.form
deleted file mode 100644
index 13edae8e..00000000
--- a/bin/UtilFrame.form
+++ /dev/null
@@ -1,123 +0,0 @@
-
-
-
diff --git a/bin/ViewPrompt.form b/bin/ViewPrompt.form
deleted file mode 100644
index 9860af11..00000000
--- a/bin/ViewPrompt.form
+++ /dev/null
@@ -1,169 +0,0 @@
-
-
-
diff --git a/build.xml b/build.xml
index aafdcb33..9b54fdea 100644
--- a/build.xml
+++ b/build.xml
@@ -10,39 +10,29 @@
-
-
-
-
+
-
-
-
+
-
-
-
+
-
-
-
+
-
@@ -57,6 +47,7 @@
+
diff --git a/dist/arrayVisualizer.jar b/dist/arrayVisualizer.jar
index 18954343..a22f4497 100644
Binary files a/dist/arrayVisualizer.jar and b/dist/arrayVisualizer.jar differ
diff --git a/dist/build.xml b/dist/build.xml
new file mode 100644
index 00000000..7ee04433
--- /dev/null
+++ b/dist/build.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dist/jar-in-jar-loader.zip b/dist/jar-in-jar-loader.zip
new file mode 100644
index 00000000..7e5a3ab3
Binary files /dev/null and b/dist/jar-in-jar-loader.zip differ
diff --git a/lib/classgraph-4.8.47-javadoc.jar b/lib/classgraph-4.8.47-javadoc.jar
deleted file mode 100644
index 62aed633..00000000
Binary files a/lib/classgraph-4.8.47-javadoc.jar and /dev/null differ
diff --git a/lib/classgraph-4.8.47-sources.jar b/lib/classgraph-4.8.47-sources.jar
deleted file mode 100644
index 0542dbc8..00000000
Binary files a/lib/classgraph-4.8.47-sources.jar and /dev/null differ
diff --git a/src/frames/ArrayFrame.java b/src/frames/ArrayFrame.java
index aa2c99c3..2ed88a0c 100644
--- a/src/frames/ArrayFrame.java
+++ b/src/frames/ArrayFrame.java
@@ -90,7 +90,7 @@ public void reposition(){
private void initComponents() {
this.jLabel1 = new javax.swing.JLabel();
- this.jSlider = new javax.swing.JSlider(SwingConstants.VERTICAL, 1, 12, 11);
+ this.jSlider = new javax.swing.JSlider(SwingConstants.VERTICAL, 1, 14, 11);
jLabel1.setText("Array Size");
@@ -109,6 +109,8 @@ private void initComponents() {
labels.put(10, new JLabel("1024"));
labels.put(11, new JLabel("2048"));
labels.put(12, new JLabel("4096"));
+ labels.put(13, new JLabel("8192"));
+ labels.put(14, new JLabel("16384"));
jSlider.setMajorTickSpacing(1);
jSlider.setLabelTable(labels);
@@ -120,6 +122,7 @@ private void initComponents() {
public void stateChanged(ChangeEvent event) {
if(ArrayManager.isLengthMutable()) {
ArrayVisualizer.setCurrentLength((int) Math.pow(2, jSlider.getValue()));
+ //ArrayVisualizer.setEqualItems((int) Math.pow(2, jSlider.getValue()));
ArrayManager.initializeArray(array);
}
else jSlider.setValue(ArrayVisualizer.getLogBaseTwoOfLength());
diff --git a/src/frames/UtilFrame.java b/src/frames/UtilFrame.java
index e58297c1..bd62ec7c 100644
--- a/src/frames/UtilFrame.java
+++ b/src/frames/UtilFrame.java
@@ -382,11 +382,26 @@ else if(!this.abstractFrame.isVisible()) {
}
if(speedPromptAllowed) {
- try{
- Delays.setSleepRatio(Double.parseDouble(JOptionPane.showInputDialog(null, "Modify the visual's speed below (Ex. 10 = Ten times faster)", Delays.getSleepRatio())));
- }
- catch(Exception e) { //TODO: Disable exception on Dialog cancel
- System.out.println("Not a number! (" + e.getMessage() + ")");
+ boolean showPrompt = true;
+ while(showPrompt) {
+ try {
+ double oldRatio = Delays.getSleepRatio();
+ String userInput = JOptionPane.showInputDialog(null, "Modify the visual's speed below (Ex. 10 = Ten times faster)", oldRatio);
+ if(userInput == null) {
+ showPrompt = false;
+ }
+ else {
+ double newRatio = Double.parseDouble(userInput);
+ if(newRatio == 0) throw new Exception("Divide by zero");
+ Delays.setSleepRatio(newRatio);
+ Delays.updateCurrentDelay(oldRatio, Delays.getSleepRatio());
+ showPrompt = false;
+ }
+ }
+ catch(Exception e) {
+ showPrompt = true;
+ JOptionPane.showMessageDialog(null, "Not a number! (" + e.getMessage() + ")", "Error", JOptionPane.ERROR_MESSAGE);
+ }
}
}
}//GEN-LAST:event_jButton3ActionPerformed
@@ -404,7 +419,6 @@ private void jCheckBox3ActionPerformed() {//GEN-FIRST:event_jCheckBox3ActionPerf
}//GEN-LAST:event_jCheckBox3ActionPerformed
private void jButton4ActionPerformed() {//GEN-FIRST:event_jButton4ActionPerformed
- Delays.setSleepRatio(Double.MAX_VALUE);
Delays.changeSkipped(true);
}//GEN-LAST:event_jButton4ActionPerformed
@@ -418,10 +432,10 @@ private void jButton5ActionPerformed() {//GEN-FIRST:event_jButton4ActionPerforme
private void jCheckBox5ActionPerformed() {//GEN-FIRST:event_jButton4ActionPerformed
if(jCheckBox5.isSelected()) {
- Sounds.changeVolume(0.01);
+ Sounds.toggleSofterSounds(true);
}
else {
- Sounds.changeVolume(1);
+ Sounds.toggleSofterSounds(false);
}
}//GEN-LAST:event_jCheckBox5ActionPerformed
diff --git a/src/main/ArrayManager.java b/src/main/ArrayManager.java
index a194cddc..dd66e1bb 100644
--- a/src/main/ArrayManager.java
+++ b/src/main/ArrayManager.java
@@ -1,5 +1,8 @@
package main;
+import javax.swing.JOptionPane;
+
+import templates.JErrorPane;
import utils.Delays;
import utils.Highlights;
import utils.Shuffles;
@@ -65,9 +68,11 @@ public void toggleMutableLength(boolean Bool) {
this.MUTABLE = Bool;
}
+ //TODO: Fix minimum to zero
public void initializeArray(int[] array) {
+ int equalFactor = ArrayVisualizer.getEqualItems();
for (int i = 0; i < array.length; i++) {
- array[i] = i;
+ array[i] = (i / equalFactor) * equalFactor;
}
}
@@ -106,6 +111,8 @@ public void shuffleArray(int[] array, int currentLen, ArrayVisualizer ArrayVisua
double sleepRatio;
switch(ArrayVisualizer.getLogBaseTwoOfLength()) {
+ case 14: sleepRatio = 16d; break;
+ case 13: sleepRatio = 8d; break;
case 12: sleepRatio = 4d; break;
case 11: sleepRatio = 2d; break;
case 10: sleepRatio = 3/2d; break;
@@ -135,7 +142,7 @@ public void refreshArray(int[] array, int currentLen, ArrayVisualizer ArrayVisua
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
- e.printStackTrace();
+ JErrorPane.invokeErrorMessage(e);
}
ArrayVisualizer.resetAllStatistics();
@@ -149,7 +156,7 @@ public void refreshArray(int[] array, int currentLen, ArrayVisualizer ArrayVisua
try {
Thread.sleep(500);
} catch (InterruptedException e) {
- e.printStackTrace();
+ JErrorPane.invokeErrorMessage(e);
}
ArrayVisualizer.resetAllStatistics();
diff --git a/src/main/ArrayVisualizer.java b/src/main/ArrayVisualizer.java
index 408de023..1f0f745a 100644
--- a/src/main/ArrayVisualizer.java
+++ b/src/main/ArrayVisualizer.java
@@ -20,13 +20,19 @@
import frames.ArrayFrame;
import frames.UtilFrame;
+import templates.Visual;
import utils.Delays;
-import utils.Renderer;
import utils.Highlights;
import utils.Reads;
+import utils.Renderer;
import utils.Sounds;
import utils.Timer;
import utils.Writes;
+import visuals.Bars;
+import visuals.Circular;
+import visuals.Hoops;
+import visuals.Mesh;
+import visuals.Pixels;
import visuals.VisualStyles;
/* TO-DO LIST:
@@ -35,16 +41,15 @@
* - CLEAN UP GETTERS AND SETTERS
* - CLEAN UP METHOD PARAMETERS
* - SHOW/HIDE BASIC SORTS, ADVANCED SORTS, AND OBSCURE SORTS
+ * - GIVE COMPARE METHODS DELAY AND MARK ARGUMENTS
* - Implement:
* - - Entering in your own set of data
- * - - Justified statistics?
- * - - Up to 2^14 numbers.
+ * - - Pass ArrayVisualizer as "observer object" to sorts
+ * - - Pass formatter/symbols from ArrayVisualizer into utils
* - Fix:
* - - Circular pointer
* - - Combsort / Radix Sorts not complying with "Skip Sort"
* - - "Skip Sort" / changing array size saving previous speed
- * - - Counting Sort
- * - - "0th" Linked Dot
* - - .dls file in soundfont dir
* - - 1080p in OBS(?)
* - Create:
@@ -54,6 +59,7 @@
* - - options to choose timsort minrun
* - - subheadings for sort customizations (e.g. number of buckets for all bucket sorts)
* - - toggle between pointer and black bar
+ * - - SINE WAVE VISUAL!!!
* - Make:
* - - "Many Similar" distribution ((i / 5) * 5, as an example)
* - - Better names/clean up code in frames/prompts
@@ -66,11 +72,10 @@
* - - run all sorts in specific category
* - - option for custom parts for intro sorts
* - - option for simple shatter rate???
- * - - Timo Bingmann's green sweep also *verify* a sorted array
* - Finish:
* - - SkaSort
* - - HolyGrailSort
- * - - Run All/Run All Sorts in Category
+ * - - Run All Sorts in Category
* - Cleanup:
* - - Treesort
*/
@@ -133,15 +138,16 @@ final public class ArrayVisualizer {
final boolean OBS = false; // Change to true if you want 1080p for recording with OBS
final private int MIN_ARRAY_VAL = 2;
- final private int MAX_ARRAY_VAL = 4096;
+ final private int MAX_ARRAY_VAL = 16384;
final int[] array = new int[this.MAX_ARRAY_VAL];
- private String[][] ComparisonSorts; //First row of Comparison/DistributionSorts arrays consists of class names
- private String[][] DistributionSorts; //Second row consists of user-friendly names
+ private String[][] ComparisonSorts; // First row of Comparison/DistributionSorts arrays consists of class names
+ private String[][] DistributionSorts; // Second row consists of user-friendly names
private String[] InvalidSorts;
private volatile int currentLen;
+ private volatile int equalItems;
private ArrayManager ArrayManager;
private SortAnalyzer SortAnalyzer;
@@ -149,6 +155,8 @@ final public class ArrayVisualizer {
private UtilFrame UtilFrame;
private ArrayFrame ArrayFrame;
+ private Visual[] visualClasses;
+
private Thread sortingThread;
private Thread visualsThread;
@@ -173,6 +181,7 @@ final public class ArrayVisualizer {
private volatile boolean PIXELDRAW;
private volatile boolean RAINBOW;
private volatile boolean SPIRALDRAW;
+ private volatile boolean WAVEDRAW;
private volatile int cx;
private volatile int cy;
@@ -195,10 +204,11 @@ final public class ArrayVisualizer {
public ArrayVisualizer() {
this.currentLen = 2048;
+ this.equalItems = 1;
- this.Delays = new Delays();
- this.Highlights = new Highlights(this.MAX_ARRAY_VAL);
+ this.Highlights = new Highlights(this, this.MAX_ARRAY_VAL);
this.Sounds = new Sounds(this.array, this);
+ this.Delays = new Delays(this);
this.Timer = new Timer();
this.Reads = new Reads(this);
this.Renderer = new Renderer(this);
@@ -207,23 +217,23 @@ public ArrayVisualizer() {
this.ArrayManager = new ArrayManager(this);
this.SortAnalyzer = new SortAnalyzer(this);
- SortAnalyzer.analyzeSorts();
- this.ComparisonSorts = SortAnalyzer.getComparisonSorts();
- this.DistributionSorts = SortAnalyzer.getDistributionSorts();
- this.InvalidSorts = SortAnalyzer.getInvalidSorts();
+ this.SortAnalyzer.analyzeSorts();
+ this.ComparisonSorts = this.SortAnalyzer.getComparisonSorts();
+ this.DistributionSorts = this.SortAnalyzer.getDistributionSorts();
+ this.InvalidSorts = this.SortAnalyzer.getInvalidSorts();
this.category = "";
this.heading = "";
this.typeFace = new Font("Times New Roman", Font.PLAIN, (int) (640 / (1280.0 * 25)));
this.formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US);
- this.symbols = formatter.getDecimalFormatSymbols();
+ this.symbols = this.formatter.getDecimalFormatSymbols();
this.formatter.setRoundingMode(RoundingMode.HALF_UP);
this.UtilFrame = new UtilFrame(this.array, this);
this.ArrayFrame = new ArrayFrame(this.array, this);
- UtilFrame.reposition(this.ArrayFrame);
+ this.UtilFrame.reposition(this.ArrayFrame);
this.SHUFFLEANIM = true;
this.ANALYZE = false;
@@ -242,41 +252,61 @@ public ArrayVisualizer() {
this.ch = 0;
this.cw = 0;
- ArrayManager.initializeArray(this.array);
+ this.ArrayManager.initializeArray(this.array);
+
+ //TODO: Overhaul visual code to properly reflect Swing (JavaFX?) style and conventions
//DRAW THREAD
this.visualsThread = new Thread() {
@Override
public void run() {
- Renderer.initializeVisuals(ArrayVisualizer.this, ArrayVisualizer.this.VisualStyles);
+ utils.Renderer.initializeVisuals(ArrayVisualizer.this);
+
+ Graphics background = ArrayVisualizer.this.window.getGraphics();
+ background.setColor(Color.BLACK);
+
+ ArrayVisualizer.this.visualClasses = new Visual[5];
+ ArrayVisualizer.this.visualClasses[0] = new Bars(ArrayVisualizer.this);
+ ArrayVisualizer.this.visualClasses[1] = new Circular(ArrayVisualizer.this);
+ ArrayVisualizer.this.visualClasses[2] = new Hoops(ArrayVisualizer.this);
+ ArrayVisualizer.this.visualClasses[3] = new Mesh(ArrayVisualizer.this);
+ ArrayVisualizer.this.visualClasses[4] = new Pixels(ArrayVisualizer.this);
while(true) {
- Renderer.updateVisuals(ArrayVisualizer.this);
- Renderer.drawVisual(ArrayVisualizer.this.VisualStyles, array, ArrayVisualizer.this, mainRender, extraRender, Highlights);
-
- int coltmp = 255;
- mainRender.setColor(new Color(coltmp,coltmp,coltmp));
- if(TEXTDRAW) {
- Font f = mainRender.getFont();
- mainRender.setFont(typeFace);
- mainRender.drawString(category + ": " + heading, 15, (int)(cw/1280.0*40)+30);
- mainRender.drawString(formatter.format(currentLen) + " Numbers", 15, (int)(cw/1280.0*65)+30);
- mainRender.drawString(String.format("Delay: " + formatter.format(Delays.getCurrentDelay()) + "ms"), 15, (int)(cw/1280.0*105)+30);
- mainRender.drawString(String.format("Visual Time: " + Timer.getVisualTime()), 15, (int)(cw/1280.0*130)+30);
- mainRender.drawString(String.format("Estimated Real Time: " + Timer.getRealTime()), 15, (int)(cw/1280.0*155)+30);
- mainRender.drawString(Reads.getComparisons(), 15, (int)(cw/1280.0*195)+30);
- mainRender.drawString(Writes.getSwaps(), 15, (int)(cw/1280.0*220)+30);
- mainRender.drawString(Writes.getReversals(), 15, (int)(cw/1280.0*245)+30);
- mainRender.drawString(Writes.getWrites(), 15, (int)(cw/1280.0*270)+30);
- mainRender.drawString(Writes.getTempWrites(), 15, (int)(cw/1280.0*295)+30);
- mainRender.setFont(f);
+ ArrayVisualizer.this.Renderer.updateVisuals(ArrayVisualizer.this);
+ ArrayVisualizer.this.Renderer.drawVisual(ArrayVisualizer.this.VisualStyles, ArrayVisualizer.this.array, ArrayVisualizer.this, ArrayVisualizer.this.Highlights);
+
+ if(ArrayVisualizer.this.TEXTDRAW) {
+ Font f = ArrayVisualizer.this.mainRender.getFont();
+ ArrayVisualizer.this.mainRender.setFont(ArrayVisualizer.this.typeFace);
+ ArrayVisualizer.this.mainRender.setColor(Color.BLACK);
+ ArrayVisualizer.this.mainRender.drawString(ArrayVisualizer.this.category + ": " + ArrayVisualizer.this.heading, 17, (int)(ArrayVisualizer.this.cw/1280.0*30)+32);
+ ArrayVisualizer.this.mainRender.drawString(ArrayVisualizer.this.formatter.format(ArrayVisualizer.this.currentLen) + " Numbers", 17, (int)(ArrayVisualizer.this.cw/1280.0*55)+32);
+ ArrayVisualizer.this.mainRender.drawString(String.format("Delay: " + ArrayVisualizer.this.Delays.displayCurrentDelay() + "ms"), 17, (int)(ArrayVisualizer.this.cw/1280.0*95)+32);
+ ArrayVisualizer.this.mainRender.drawString(String.format("Visual Time: " + ArrayVisualizer.this.Timer.getVisualTime()), 17, (int)(ArrayVisualizer.this.cw/1280.0*120)+32);
+ ArrayVisualizer.this.mainRender.drawString(String.format("Sort Time: " + ArrayVisualizer.this.Timer.getRealTime()), 17, (int)(ArrayVisualizer.this.cw/1280.0*145)+32);
+ ArrayVisualizer.this.mainRender.drawString(ArrayVisualizer.this.Reads.displayComparisons(), 17, (int)(ArrayVisualizer.this.cw/1280.0*185)+32);
+ ArrayVisualizer.this.mainRender.drawString(ArrayVisualizer.this.Writes.getSwaps(), 17, (int)(ArrayVisualizer.this.cw/1280.0*210)+32);
+ ArrayVisualizer.this.mainRender.drawString(ArrayVisualizer.this.Writes.getReversals(), 17, (int)(ArrayVisualizer.this.cw/1280.0*235)+32);
+ ArrayVisualizer.this.mainRender.drawString(ArrayVisualizer.this.Writes.getWrites(), 17, (int)(ArrayVisualizer.this.cw/1280.0*275)+32);
+ ArrayVisualizer.this.mainRender.drawString(ArrayVisualizer.this.Writes.getTempWrites(), 17, (int)(ArrayVisualizer.this.cw/1280.0*300)+32);
+ ArrayVisualizer.this.mainRender.setColor(Color.WHITE);
+ ArrayVisualizer.this.mainRender.drawString(ArrayVisualizer.this.category + ": " + ArrayVisualizer.this.heading, 15, (int)(ArrayVisualizer.this.cw/1280.0*30)+30);
+ ArrayVisualizer.this.mainRender.drawString(ArrayVisualizer.this.formatter.format(ArrayVisualizer.this.currentLen) + " Numbers", 15, (int)(ArrayVisualizer.this.cw/1280.0*55)+30);
+ ArrayVisualizer.this.mainRender.drawString(String.format("Delay: " + ArrayVisualizer.this.Delays.displayCurrentDelay() + "ms"), 15, (int)(ArrayVisualizer.this.cw/1280.0*95)+30);
+ ArrayVisualizer.this.mainRender.drawString(String.format("Visual Time: " + ArrayVisualizer.this.Timer.getVisualTime()), 15, (int)(ArrayVisualizer.this.cw/1280.0*120)+30);
+ ArrayVisualizer.this.mainRender.drawString(String.format("Sort Time: " + ArrayVisualizer.this.Timer.getRealTime()), 15, (int)(ArrayVisualizer.this.cw/1280.0*145)+30);
+ ArrayVisualizer.this.mainRender.drawString(ArrayVisualizer.this.Reads.displayComparisons(), 15, (int)(ArrayVisualizer.this.cw/1280.0*185)+30);
+ ArrayVisualizer.this.mainRender.drawString(ArrayVisualizer.this.Writes.getSwaps(), 15, (int)(ArrayVisualizer.this.cw/1280.0*210)+30);
+ ArrayVisualizer.this.mainRender.drawString(ArrayVisualizer.this.Writes.getReversals(), 15, (int)(ArrayVisualizer.this.cw/1280.0*235)+30);
+ ArrayVisualizer.this.mainRender.drawString(ArrayVisualizer.this.Writes.getWrites(), 15, (int)(ArrayVisualizer.this.cw/1280.0*275)+30);
+ ArrayVisualizer.this.mainRender.drawString(ArrayVisualizer.this.Writes.getTempWrites(), 15, (int)(ArrayVisualizer.this.cw/1280.0*300)+30);
+ ArrayVisualizer.this.mainRender.setFont(f);
}
- Graphics background = window.getGraphics();
- background.setColor(Color.BLACK);
- background.drawImage(img, 0, 0, null);
+ background.drawImage(ArrayVisualizer.this.img, 0, 0, null);
}}};
- Sounds.startAudioThread();
+ this.Sounds.startAudioThread();
this.drawWindows();
}
@@ -308,6 +338,10 @@ public Writes getWrites() {
return this.Writes;
}
+ public Visual[] getVisuals() {
+ return this.visualClasses;
+ }
+
public UtilFrame getUtilFrame() {
return this.UtilFrame;
}
@@ -326,7 +360,7 @@ public void setSortingThread(Thread thread) {
this.sortingThread = thread;
}
public void runSortingThread() {
- sortingThread.start();
+ this.sortingThread.start();
}
public int getMinimumLength() {
@@ -337,12 +371,12 @@ public int getMaximumLength() {
}
public void resetAllStatistics() {
- Reads.resetStatistics();
- Writes.resetStatistics();
- Timer.manualSetTime(0);
+ this.Reads.resetStatistics();
+ this.Writes.resetStatistics();
+ this.Timer.manualSetTime(0);
}
- // These next three methods should be part of ArrayManager
+ // These next five methods should be part of ArrayManager
public int getCurrentLength() {
return this.currentLen;
}
@@ -350,6 +384,13 @@ public void setCurrentLength(int newLength) {
this.currentLen = newLength;
}
+ public int getEqualItems() {
+ return this.equalItems;
+ }
+ public void setEqualItems(int newCount) {
+ this.equalItems = newCount;
+ }
+
public int getLogBaseTwoOfLength() {
return (int) (Math.log(this.currentLen) / Math.log(2));
}
@@ -380,10 +421,10 @@ public JFrame getMainWindow() {
}
public void setWindowHeight() {
- this.ch = window.getHeight();
+ this.ch = this.window.getHeight();
}
public void setWindowWidth() {
- this.cw = window.getWidth();
+ this.cw = this.window.getWidth();
}
// TODO:
@@ -391,16 +432,16 @@ public void setWindowWidth() {
// AND WINDOW HEIGHT/WIDTH/X/Y SHOULD CORRESPOND TO WINDOW FIELD
public int currentHeight() {
- return window.getHeight();
+ return this.window.getHeight();
}
public int currentWidth() {
- return window.getWidth();
+ return this.window.getWidth();
}
public int currentX() {
- return window.getX();
+ return this.window.getX();
}
public int currentY() {
- return window.getY();
+ return this.window.getY();
}
public int windowHeight() {
@@ -423,7 +464,7 @@ public int windowYCoordinate() {
}
public void createVolatileImage() {
- this.img = window.createVolatileImage(cw, ch);
+ this.img = this.window.createVolatileImage(this.cw, this.ch);
}
public void setThickStroke(Stroke stroke) {
this.thickStroke = stroke;
@@ -434,28 +475,39 @@ public Stroke getThickStroke() {
public Stroke getDefaultStroke() {
return new BasicStroke(3f * (this.currentWidth() / 1280f));
}
+ public Graphics2D getMainRender() {
+ return this.mainRender;
+ }
+ public Graphics2D getExtraRender() {
+ return this.extraRender;
+ }
public void setMainRender() {
- this.mainRender = (Graphics2D) img.getGraphics();
+ this.mainRender = (Graphics2D) this.img.getGraphics();
}
public void setExtraRender() {
- this.extraRender = (Graphics2D) img.getGraphics();
+ this.extraRender = (Graphics2D) this.img.getGraphics();
+ }
+ public void updateVisuals() {
+ for(Visual visual : this.visualClasses) {
+ visual.updateRender(this);
+ }
}
public void resetMainStroke() {
- mainRender.setStroke(this.getDefaultStroke());
+ this.mainRender.setStroke(this.getDefaultStroke());
}
public void renderBackground() {
- mainRender.setColor(new Color(0, 0, 0)); // Pure black
- mainRender.fillRect(0, 0, img.getWidth(null), img.getHeight(null));
+ this.mainRender.setColor(new Color(0, 0, 0)); // Pure black
+ this.mainRender.fillRect(0, 0, this.img.getWidth(null), this.img.getHeight(null));
}
public void updateCoordinates() {
- this.cx = window.getX();
- this.cy = window.getY();
+ this.cx = this.window.getX();
+ this.cy = this.window.getY();
}
public void updateDimensions() {
- this.cw = window.getWidth();
- this.ch = window.getHeight();
+ this.cw = this.window.getWidth();
+ this.ch = this.window.getHeight();
}
public void updateFontSize() {
this.typeFace = new Font("Times New Roman",Font.PLAIN,(int)(this.cw/1280.0*25));
@@ -472,52 +524,89 @@ public int halfCircle() {
return (this.currentLen / 2);
}
- public synchronized void fancyFinish() {
- Highlights.toggleFancyFinish(true);
- Highlights.resetFancyFinish();
+ //TODO: This method is *way* too long. Break it apart.
+ public synchronized void verifySortAndSweep() {
+ this.Highlights.toggleFancyFinish(true);
+ this.Highlights.resetFancyFinish();
- Delays.setSleepRatio(1);
+ this.Delays.setSleepRatio(1);
double sleepRatio = 0;
switch(this.getLogBaseTwoOfLength()) {
- case 12: sleepRatio = 1; break;
- case 11: sleepRatio = 2; break;
- case 10: sleepRatio = 4; break;
- case 9: sleepRatio = 6; break;
- case 8: sleepRatio = 8; break;
- case 7: sleepRatio = 16; break;
- case 6: sleepRatio = 24; break;
+ case 14: sleepRatio = 0.25; break;
+ case 13: sleepRatio = 0.5; break;
+ case 12: sleepRatio = 1; break;
+ case 11: sleepRatio = 2; break;
+ case 10: sleepRatio = 4; break;
+ case 9: sleepRatio = 6; break;
+ case 8: sleepRatio = 8; break;
+ case 7: sleepRatio = 16; break;
+ case 6: sleepRatio = 24; break;
case 5:
- case 4: sleepRatio = 32; break;
+ case 4: sleepRatio = 32; break;
case 3:
case 2:
default: sleepRatio = 64;
}
+ long tempComps = this.Reads.getComparisons();
+ this.Reads.setComparisons(0);
+
+ String temp = this.heading;
+ this.heading = "Verifying sort...";
+
for(int i = 0; i < this.currentLen + this.getLogBaseTwoOfLength(); i++) {
- if(i < this.currentLen) Highlights.markArray(1, i);
- Highlights.incrementFancyFinishPosition();
+ if(i < this.currentLen) this.Highlights.markArray(1, i);
+ this.Highlights.incrementFancyFinishPosition();
- Delays.sleep(sleepRatio / this.getLogBaseTwoOfLength());
+ if(i < this.currentLen - 1) {
+ if(this.Reads.compare(this.array[i], this.array[i + 1]) == 1) {
+ this.Highlights.clearMark(1);
+
+ this.Sounds.toggleSound(false);
+ this.Highlights.toggleFancyFinish(false);
+
+ for(int j = i + 1; j < this.currentLen; j++) {
+ this.Highlights.markArray(j, j);
+ this.Delays.sleep(sleepRatio / this.getLogBaseTwoOfLength());
+ }
+
+ JOptionPane.showMessageDialog(this.window, "The sort was unsuccessful;\nIndices " + i + " and " + (i + 1) + " are out of order!", "Error", JOptionPane.OK_OPTION, null);
+
+ this.Highlights.clearAllMarks();
+
+ i = this.currentLen + this.getLogBaseTwoOfLength();
+
+ this.Sounds.toggleSound(true);
+ }
+ }
+
+ if(this.Highlights.fancyFinishEnabled()) {
+ this.Delays.sleep(sleepRatio / this.getLogBaseTwoOfLength());
+ }
}
- Highlights.clearMark(1);
+ this.Highlights.clearMark(1);
- Highlights.toggleFancyFinish(false);
- Highlights.resetFancyFinish();
+ this.heading = temp;
+ this.Reads.setComparisons(tempComps);
+
+ if(this.Highlights.fancyFinishActive()) {
+ this.Highlights.toggleFancyFinish(false);
+ }
+ this.Highlights.resetFancyFinish();
}
public void endSort() {
- Timer.disableRealTimer();
- Highlights.clearAllMarks();
+ this.Timer.disableRealTimer();
+ this.Highlights.clearAllMarks();
- if(Highlights.fancyFinishEnabled()) {
- double speed = Delays.getSleepRatio();
- this.fancyFinish();
- Delays.setSleepRatio(speed);
-
- Highlights.clearAllMarks();
- }
+ double speed = this.Delays.getSleepRatio();
+ this.verifySortAndSweep();
+ this.Delays.setSleepRatio(speed);
+ this.Delays.changeSkipped(false);
+
+ this.Highlights.clearAllMarks();
}
public void togglePointer(boolean Bool) {
@@ -544,6 +633,9 @@ public void toggleStatistics(boolean Bool) {
public void toggleColor(boolean Bool) {
this.COLOR = Bool;
}
+ public void toggleWave(boolean Bool) {
+ this.WAVEDRAW = Bool;
+ }
public void setVisual(VisualStyles choice) {
this.VisualStyles = choice;
@@ -557,8 +649,8 @@ public void setCurrentGap(int gap) {
}
public void repositionFrames() {
- ArrayFrame.reposition();
- UtilFrame.reposition(ArrayFrame);
+ this.ArrayFrame.reposition();
+ this.UtilFrame.reposition(this.ArrayFrame);
}
public boolean rainbowEnabled() {
@@ -579,6 +671,9 @@ public boolean pixelsEnabled() {
public boolean linesEnabled() {
return this.LINEDRAW;
}
+ public boolean waveEnabled() {
+ return this.WAVEDRAW;
+ }
public DecimalFormat getNumberFormat() {
return this.formatter;
@@ -589,40 +684,40 @@ private void drawWindows() {
this.category = "Select a Sort";
// For recording with OBS (don't ask where these numbers came from. I don't get it myself)
- if(OBS) {
+ if(this.OBS) {
int x = (int) (1920 * (double) (1920 / 1916));
int y = (int) (1080 * (double) (1080 / 1020));
- window.setSize(new Dimension(x, y));
+ this.window.setSize(new Dimension(x, y));
}
else { // Consider changing back to discrete 16:9 dimension
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
- window.setSize((int) (screenSize.getWidth() / 2d), (int) (screenSize.getHeight() / 2d));
+ this.window.setSize((int) (screenSize.getWidth() / 2d), (int) (screenSize.getHeight() / 2d));
}
- window.setLocation(0, 0);
- window.setVisible(true);
- window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- window.setTitle("w0rthy's Array Visualizer - " + (ComparisonSorts[0].length + DistributionSorts[0].length) + " Sorting Algorithms with 10 Different Visual Styles");
- window.setBackground(Color.BLACK);
+ this.window.setLocation(0, 0);
+ this.window.setVisible(true);
+ this.window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ this.window.setTitle("w0rthy's Array Visualizer - " + (this.ComparisonSorts[0].length + this.DistributionSorts[0].length) + " Sorting Algorithms with 12 Different Visual Styles");
+ this.window.setBackground(Color.BLACK);
- symbols.setGroupingSeparator(',');
- formatter.setDecimalFormatSymbols(symbols);
+ this.symbols.setGroupingSeparator(',');
+ this.formatter.setDecimalFormatSymbols(this.symbols);
//TODO: Consider removing insets from window size
- this.cw = window.getWidth();
- this.ch = window.getHeight();
+ this.cw = this.window.getWidth();
+ this.ch = this.window.getHeight();
- visualsThread.start();
+ this.visualsThread.start();
- UtilFrame.setVisible(true);
- ArrayFrame.setVisible(true);
+ this.UtilFrame.setVisible(true);
+ this.ArrayFrame.setVisible(true);
if(this.InvalidSorts != null) {
String output = "";
- for(int i = 0; i < InvalidSorts.length; i++) {
- output += InvalidSorts[i] + "\n";
+ for(int i = 0; i < this.InvalidSorts.length; i++) {
+ output += this.InvalidSorts[i] + "\n";
}
- JOptionPane.showMessageDialog(window, "The following algorithms were not loaded due to errors:\n" + output);
+ JOptionPane.showMessageDialog(this.window, "The following algorithms were not loaded due to errors:\n" + output, "Warning", JOptionPane.WARNING_MESSAGE);
}
}
diff --git a/src/main/SortAnalyzer.java b/src/main/SortAnalyzer.java
index b33e1b43..e3b99824 100644
--- a/src/main/SortAnalyzer.java
+++ b/src/main/SortAnalyzer.java
@@ -4,10 +4,12 @@
import java.util.ArrayList;
import java.util.List;
+import javax.swing.JOptionPane;
+
import io.github.classgraph.ClassGraph;
import io.github.classgraph.ClassInfo;
import io.github.classgraph.ScanResult;
-
+import templates.JErrorPane;
import templates.Sort;
import utils.Delays;
import utils.Highlights;
@@ -71,7 +73,7 @@ public void analyzeSorts() {
Class> sortClass = Class.forName(sortFiles.get(i).getName());
Constructor> newSort = sortClass.getConstructor(new Class[] {Delays.class, Highlights.class, Reads.class, Writes.class});
Sort sort = (Sort) newSort.newInstance(this.Delays, this.Highlights, this.Reads, this.Writes);
-
+
try {
if(verifySort(sort)) {
if(sort.comparisonBased()) {
@@ -95,10 +97,8 @@ public void analyzeSorts() {
e.printStackTrace();
}
}
- } catch (SecurityException e) {
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
+ } catch (SecurityException | IllegalArgumentException e) {
+ JErrorPane.invokeErrorMessage(e);
}
}
diff --git a/src/prompts/ShufflePrompt.java b/src/prompts/ShufflePrompt.java
index b6144d30..ea471a72 100644
--- a/src/prompts/ShufflePrompt.java
+++ b/src/prompts/ShufflePrompt.java
@@ -5,10 +5,12 @@
package prompts;
import javax.swing.JFrame;
+import javax.swing.JOptionPane;
import frames.UtilFrame;
import main.ArrayManager;
import templates.Frame;
+import templates.JErrorPane;
import utils.Shuffles;
/*
@@ -108,7 +110,7 @@ public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
try {
jList1ValueChanged(evt);
} catch (Exception e) {
- e.printStackTrace();
+ JErrorPane.invokeErrorMessage(e);
}
}
});
diff --git a/src/prompts/SortPrompt.java b/src/prompts/SortPrompt.java
index 1dc03b3c..37f835f6 100644
--- a/src/prompts/SortPrompt.java
+++ b/src/prompts/SortPrompt.java
@@ -9,9 +9,10 @@
import frames.UtilFrame;
import main.ArrayVisualizer;
import templates.Frame;
+import templates.JErrorPane;
+import threads.RunAllSorts;
import threads.RunComparisonSort;
import threads.RunDistributionSort;
-import threads.RunSelectionSorts;
/*
*
@@ -138,8 +139,7 @@ public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
jScrollPane2.setViewportView(this.jList1);
- //TODO: Better time estimate
- jButton1.setText("Run All (approx. " + (int) Math.max(Math.ceil(30 * (ArrayVisualizer.getCurrentLength() / 2048d)), 2) + " minutes)");
+ jButton1.setText("Run All (approx. 30-60 minutes)");
jButton1.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
@@ -187,34 +187,10 @@ private void jButton1ActionPerformed() {//GEN-FIRST:event_jButton1ActionPerforme
@Override
public void run(){
try {
- /*
- RunMergeSorts sortThread = new RunMergeSorts(ArrayVisualizer);
- sortThread.ReportMergeSorts(array);
- */
-
- RunSelectionSorts sortThread2 = new RunSelectionSorts(ArrayVisualizer);
- sortThread2.ReportSelectionSorts(array);
-
-
- /*
- RunExchangeSorts sortThread1 = new RunExchangeSorts(ArrayVisualizer);
- sortThread1.ReportExchangeSorts(array);
- while(ArrayVisualizer.getSortingThread() != null) {
- sleep(1000);
- }
- RunSelectionSorts sortThread2 = new RunSelectionSorts(ArrayVisualizer);
- sortThread2.ReportSelectionSorts(array);
- while(ArrayVisualizer.getSortingThread() != null) {
- sleep(1000);
- }
- RunInsertionSorts sortThread3 = new RunInsertionSorts(ArrayVisualizer);
- sortThread3.ReportInsertionSorts(array);
- */
-
- //RunAllSorts.RunAllSorts();
+ RunAllSorts RunAllSorts = new RunAllSorts(ArrayVisualizer);
+ RunAllSorts.reportAllSorts(array);
} catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ JErrorPane.invokeErrorMessage(e);
}
}
}.start();
@@ -232,8 +208,7 @@ public void run(){
RunDistributionSort sortThread = new RunDistributionSort(ArrayVisualizer);
sortThread.ReportDistributiveSort(array, selection);
} catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ JErrorPane.invokeErrorMessage(e);
}
}
}.start();
diff --git a/src/prompts/ViewPrompt.java b/src/prompts/ViewPrompt.java
index b2d76efe..92c6043d 100644
--- a/src/prompts/ViewPrompt.java
+++ b/src/prompts/ViewPrompt.java
@@ -10,6 +10,10 @@
import main.ArrayVisualizer;
import templates.Frame;
import visuals.VisualStyles;
+import javax.swing.JButton;
+import javax.swing.GroupLayout.Alignment;
+import javax.swing.GroupLayout;
+import javax.swing.LayoutStyle.ComponentPlacement;
/*
*
@@ -81,6 +85,8 @@ private void initComponents() {
this.spiralDots= new javax.swing.JButton();
this.rainbow = new javax.swing.JButton();
this.hoops = new javax.swing.JButton();
+ this.sineWave = new javax.swing.JButton();
+ this.waveDots = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setResizable(false);
@@ -166,58 +172,77 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
spiralDotsActionPerformed(evt);
}
});
-
+
+ sineWave.setText("Sine Wave");
+ sineWave.addActionListener(new java.awt.event.ActionListener() {
+ @Override
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ sineWaveActionPerformed(evt);
+ }
+ });
+ waveDots.setText("Wave Dots");
+ waveDots.addActionListener(new java.awt.event.ActionListener() {
+ @Override
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ waveDotsActionPerformed(evt);
+ }
+ });
+
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
- getContentPane().setLayout(layout);
layout.setHorizontalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER, true)
- .addGroup(layout.createSequentialGroup()
- .addGap(18, 18, 18)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, true)
- .addComponent(this.barGraph, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(this.rainbow, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(this.colorCircle, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(this.disparity, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(this.disparityDots, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, true)
- .addComponent(this.dotGraph, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(this.triangleMesh, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(this.spiral, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(this.hoops, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(this.spiralDots, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addGap(18, 18, 18))
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER, true)
- .addComponent(this.jLabel1))
- );
+ layout.createParallelGroup(Alignment.CENTER)
+ .addComponent(jLabel1)
+ .addGroup(Alignment.LEADING, layout.createSequentialGroup()
+ .addGap(18)
+ .addGroup(layout.createParallelGroup(Alignment.LEADING)
+ .addComponent(barGraph, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 105, Short.MAX_VALUE)
+ .addComponent(rainbow, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 105, Short.MAX_VALUE)
+ .addComponent(colorCircle, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 105, Short.MAX_VALUE)
+ .addComponent(disparity, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(disparityDots, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 105, Short.MAX_VALUE)
+ .addComponent(sineWave, GroupLayout.DEFAULT_SIZE, 105, Short.MAX_VALUE))
+ .addPreferredGap(ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(Alignment.LEADING)
+ .addComponent(waveDots, GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE)
+ .addComponent(dotGraph, GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE)
+ .addComponent(triangleMesh, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(spiral, GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE)
+ .addComponent(hoops, GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE)
+ .addComponent(spiralDots, GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE))
+ .addGap(18))
+ );
layout.setVerticalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER, true)
+ layout.createParallelGroup(Alignment.CENTER)
.addGroup(layout.createSequentialGroup()
- .addGap(7, 7, 7)
- .addComponent(this.jLabel1)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE, true)
- .addComponent(this.barGraph, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(this.dotGraph, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE, true)
- .addComponent(this.rainbow, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(this.triangleMesh, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE, true)
- .addComponent(this.colorCircle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(this.hoops, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE, true)
- .addComponent(this.disparity, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(this.spiral, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE, true)
- .addComponent(this.disparityDots, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(this.spiralDots, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addContainerGap(18, Short.MAX_VALUE))
- );
+ .addGap(7)
+ .addComponent(jLabel1)
+ .addPreferredGap(ComponentPlacement.UNRELATED)
+ .addGroup(layout.createParallelGroup(Alignment.BASELINE)
+ .addComponent(barGraph)
+ .addComponent(dotGraph))
+ .addPreferredGap(ComponentPlacement.UNRELATED)
+ .addGroup(layout.createParallelGroup(Alignment.BASELINE)
+ .addComponent(rainbow)
+ .addComponent(triangleMesh))
+ .addPreferredGap(ComponentPlacement.UNRELATED)
+ .addGroup(layout.createParallelGroup(Alignment.BASELINE)
+ .addComponent(colorCircle)
+ .addComponent(hoops))
+ .addPreferredGap(ComponentPlacement.UNRELATED)
+ .addGroup(layout.createParallelGroup(Alignment.BASELINE)
+ .addComponent(disparity)
+ .addComponent(spiral))
+ .addPreferredGap(ComponentPlacement.UNRELATED)
+ .addGroup(layout.createParallelGroup(Alignment.BASELINE)
+ .addComponent(disparityDots)
+ .addComponent(spiralDots))
+ .addPreferredGap(ComponentPlacement.UNRELATED)
+ .addGroup(layout.createParallelGroup(Alignment.LEADING)
+ .addComponent(sineWave)
+ .addComponent(waveDots))
+ .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ getContentPane().setLayout(layout);
pack();
}// //GEN-END:initComponents
@@ -228,6 +253,7 @@ private void setAllFieldsFalse(){
ArrayVisualizer.togglePixels(false);
ArrayVisualizer.toggleRainbow(false);
ArrayVisualizer.toggleSpiral(false);
+ ArrayVisualizer.toggleWave(false);
}
private void barGraphActionPerformed(java.awt.event.ActionEvent evt) {
@@ -306,6 +332,21 @@ private void spiralDotsActionPerformed(java.awt.event.ActionEvent evt) {
UtilFrame.jButton2ResetText();
dispose();
}
+ private void sineWaveActionPerformed(java.awt.event.ActionEvent evt) {
+ setAllFieldsFalse();
+ ArrayVisualizer.setVisual(VisualStyles.BARS);
+ ArrayVisualizer.toggleWave(true);
+ UtilFrame.jButton2ResetText();
+ dispose();
+ }
+ private void waveDotsActionPerformed(java.awt.event.ActionEvent evt) {
+ setAllFieldsFalse();
+ ArrayVisualizer.setVisual(VisualStyles.PIXELS);
+ ArrayVisualizer.togglePixels(true);
+ ArrayVisualizer.toggleWave(true);
+ UtilFrame.jButton2ResetText();
+ dispose();
+ }
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton barGraph;
@@ -318,7 +359,7 @@ private void spiralDotsActionPerformed(java.awt.event.ActionEvent evt) {
private javax.swing.JButton disparityDots;
private javax.swing.JButton rainbow;
private javax.swing.JButton hoops;
+ private javax.swing.JButton sineWave;
+ private javax.swing.JButton waveDots;
private javax.swing.JLabel jLabel1;
- // End of variables declaration//GEN-END:variables
-
}
\ No newline at end of file
diff --git a/src/sorts/AmericanFlagSort.java b/src/sorts/AmericanFlagSort.java
index a81e5f0e..ed2c16cc 100644
--- a/src/sorts/AmericanFlagSort.java
+++ b/src/sorts/AmericanFlagSort.java
@@ -143,6 +143,7 @@ private void sort(int[] array, int start, int length, int divisor) {
@Override
public void runSort(int[] array, int currentLen, int bucketCount) {
this.NUMBER_OF_BUCKETS = bucketCount;
+ this.setRunAllID("American Flag Sort, " + this.NUMBER_OF_BUCKETS + " Buckets");
int numberOfDigits = this.getMaxNumberOfDigits(array, currentLen); // Max number of digits
int max = 1;
diff --git a/src/sorts/BadSort.java b/src/sorts/BadSort.java
index 05597961..9ef47de9 100644
--- a/src/sorts/BadSort.java
+++ b/src/sorts/BadSort.java
@@ -31,7 +31,6 @@ public BadSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writeO
public void runSort(int[] array, int currentLen, int bucketCount) {
for (int i = 0; i < currentLen; i++) {
int shortest = i;
- Highlights.markArray(3, shortest);
Delays.sleep(0.05);
for (int j = i; j < currentLen; j++) {
@@ -53,7 +52,7 @@ public void runSort(int[] array, int currentLen, int bucketCount) {
break;
}
}
- Writes.swap(array, i, shortest, 1, true, false);
+ Writes.swap(array, i, shortest, 0.05, true, false);
}
}
}
\ No newline at end of file
diff --git a/src/sorts/BinaryGnomeSort.java b/src/sorts/BinaryGnomeSort.java
index 4c21dbda..eca2b99e 100644
--- a/src/sorts/BinaryGnomeSort.java
+++ b/src/sorts/BinaryGnomeSort.java
@@ -32,10 +32,10 @@ public void runSort(int[] array, int length, int bucketCount) {
int mid = lo + ((hi - lo) / 2);
Highlights.markArray(1, lo);
- Highlights.markArray(2, mid);
- Highlights.markArray(3, hi);
+ Highlights.markArray(3, mid);
+ Highlights.markArray(2, hi);
- Delays.sleep(0.025);
+ Delays.sleep(1);
if (Reads.compare(num, array[mid]) < 0) { // do NOT shift equal elements past each other; this maintains stability!
hi = mid;
@@ -48,7 +48,7 @@ public void runSort(int[] array, int length, int bucketCount) {
// item has to go into position lo
Highlights.clearMark(1);
- Highlights.clearMark(3);
+ Highlights.clearMark(2);
int j = i;
while (j > lo) {
diff --git a/src/sorts/BinaryInsertionSort.java b/src/sorts/BinaryInsertionSort.java
index 32c37044..5c0d0bec 100644
--- a/src/sorts/BinaryInsertionSort.java
+++ b/src/sorts/BinaryInsertionSort.java
@@ -54,6 +54,6 @@ public void customBinaryInsert(int[] array, int start, int end, double sleep) {
@Override
public void runSort(int[] array, int currentLength, int bucketCount) {
- this.binaryInsertSort(array, 0, currentLength, 0.05, 0.015);
+ this.binaryInsertSort(array, 0, currentLength, 1, 0.05);
}
}
\ No newline at end of file
diff --git a/src/sorts/BogoBogoSort.java b/src/sorts/BogoBogoSort.java
new file mode 100644
index 00000000..4445add5
--- /dev/null
+++ b/src/sorts/BogoBogoSort.java
@@ -0,0 +1,41 @@
+package sorts;
+
+import templates.BogoSorting;
+
+public final class BogoBogoSort extends BogoSorting {
+ public BogoBogoSort(utils.Delays delayOps, utils.Highlights markOps, utils.Reads readOps, utils.Writes writeOps) {
+ super(delayOps, markOps, readOps, writeOps);
+
+ this.setSortPromptID("Bogobogo");
+ this.setRunAllID("Bogobogo Sort");
+ this.setReportSortID("Bogobogosort");
+ this.setCategory("Distributive Sorts");
+ this.isComparisonBased(false); //Comparisons are not used to swap elements
+ this.isBucketSort(false);
+ this.isRadixSort(false);
+ this.isUnreasonablySlow(true);
+ this.setUnreasonableLimit(8);
+ this.isBogoSort(true);
+ }
+
+ @Override
+ public void runSort(int[] array, int currentLength, int bucketCount) {
+ int bogoLength = 2;
+ boolean arrayNotSorted = true;
+
+ while(arrayNotSorted) {
+ if(bogoIsSorted(array, bogoLength)) {
+ if(bogoLength == currentLength) {
+ arrayNotSorted = false;
+ }
+ else {
+ bogoLength++;
+ }
+ }
+ else {
+ bogoLength = 2;
+ }
+ if(arrayNotSorted) bogoSwap(array, bogoLength, 0);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/sorts/BottomUpMergeSort.java b/src/sorts/BottomUpMergeSort.java
index 813434b0..4486049e 100644
--- a/src/sorts/BottomUpMergeSort.java
+++ b/src/sorts/BottomUpMergeSort.java
@@ -11,7 +11,8 @@ public BottomUpMergeSort(Delays delayOps, Highlights markOps, Reads readOps, Wri
super(delayOps, markOps, readOps, writeOps);
this.setSortPromptID("Bottom-Up Merge");
- this.setRunAllID("Bottom-Up Merge Sort w/ Binary Insert (std::stable_sort)");
+ //this.setRunAllID("Bottom-Up Merge Sort w/ Binary Insert (std::stable_sort)");
+ this.setRunAllID("Bottom-Up Merge Sort [std::stable_sort]");
this.setReportSortID("Bottom-Up Mergesort w/ Binary Insert");
this.setCategory("Hybrid Sorts");
this.isComparisonBased(true);
@@ -119,10 +120,12 @@ private void stableSort (int[] a, int n) {
// Sort a[0:n-1] using merge sort.
int s = 16; // segment size
int[] b = new int [n];
+ int i;
- for(int i = 0; i <= n - 16; i += 16) {
+ for(i = 0; i <= n - 16; i += 16) {
binaryInserter.customBinaryInsert(a, i, i + 16, 0.35);
}
+ binaryInserter.customBinaryInsert(a, i, n, 0.35);
while (s < n)
{
diff --git a/src/sorts/BubbleSort.java b/src/sorts/BubbleSort.java
index cb9df361..3cffb038 100644
--- a/src/sorts/BubbleSort.java
+++ b/src/sorts/BubbleSort.java
@@ -62,7 +62,7 @@ public void runSort(int[] array, int length, int bucketCount) {
Highlights.markArray(1, i);
Highlights.markArray(2, i + 1);
- Delays.sleep(0.025);
+ Delays.sleep(0.05);
}
}
}
diff --git a/src/sorts/CocktailBogoSort.java b/src/sorts/CocktailBogoSort.java
index a1c7259b..00a1de2e 100644
--- a/src/sorts/CocktailBogoSort.java
+++ b/src/sorts/CocktailBogoSort.java
@@ -39,12 +39,12 @@ public void runSort(int[] array, int currentLen, int bucketCount) {
}
if(minSorted) {
- Highlights.markArray(1, minIterator);
+ //Highlights.markArray(1, minIterator);
minIterator++;
minSorted = false;
}
if(maxSorted) {
- Highlights.markArray(2, maxIterator);
+ //Highlights.markArray(2, maxIterator);
maxIterator--;
maxSorted = false;
}
diff --git a/src/sorts/CocktailMergeSort.java b/src/sorts/CocktailMergeSort.java
index 93e2da9e..ca099844 100644
--- a/src/sorts/CocktailMergeSort.java
+++ b/src/sorts/CocktailMergeSort.java
@@ -57,7 +57,7 @@ public void runSort(int[] array, int currentLength, int bucketCount) {
Highlights.clearAllMarks();
- this.timSortInstance = new TimSorting(array, currentLength, this.Highlights, this.Reads, this.Writes);
+ this.timSortInstance = new TimSorting(array, currentLength, this.Delays, this.Highlights, this.Reads, this.Writes);
TimSorting.sort(this.timSortInstance, array, currentLength);
}
}
diff --git a/src/sorts/CocktailShakerSort.java b/src/sorts/CocktailShakerSort.java
index e0ae5260..34e20f8d 100644
--- a/src/sorts/CocktailShakerSort.java
+++ b/src/sorts/CocktailShakerSort.java
@@ -59,7 +59,7 @@ private void cocktailShaker(int[] array, int start, int end, double sleep) {
Highlights.markArray(1, j);
Highlights.markArray(2, j + 1);
- Delays.sleep(0.01);
+ Delays.sleep(sleep / 2);
}
for(int j = end + start - i - 1; j > i; j--){
if(Reads.compare(array[j], array[j - 1]) == -1) {
@@ -69,7 +69,7 @@ private void cocktailShaker(int[] array, int start, int end, double sleep) {
Highlights.markArray(1, j);
Highlights.markArray(2, j - 1);
- Delays.sleep(0.01);
+ Delays.sleep(sleep / 2);
}
i++;
@@ -82,6 +82,6 @@ public void customSort(int[] array, int start, int end) {
@Override
public void runSort(int[] array, int length, int bucketCount) {
- this.cocktailShaker(array, 0, length, 0.0875);
+ this.cocktailShaker(array, 0, length, 0.1);
}
}
\ No newline at end of file
diff --git a/src/sorts/CountingSort.java b/src/sorts/CountingSort.java
index f9c5e280..1283336f 100644
--- a/src/sorts/CountingSort.java
+++ b/src/sorts/CountingSort.java
@@ -57,25 +57,25 @@ public void runSort(int[] array, int length, int bucketCount) {
int[] output = Arrays.copyOf(array, length);
int[] counts = new int[max + 1];
- for(int i = 0; i < length; i++){
- Writes.write(counts, array[i], counts[array[i]] + 1, 0.5, false, true);
+ for (int i = 0; i < length; i++) {
+ Writes.write(counts, array[i], counts[array[i]] + 1, 1, false, true);
Highlights.markArray(1, i);
- }
- for (int i = 1; i <= max; i++) {
+ }
+
+ for (int i = 1; i < counts.length; i++) {
Writes.write(counts, i, counts[i] + counts[i - 1], 1, true, true);
+ }
+
+ for (int i = length - 1; i >= 0; i--) {
+ output[counts[array[i]] - 1] = array[i];
+ counts[array[i]]--;
}
- for(int i = length - 1; i >= 0; i--){
- Writes.write(counts, array[i], counts[array[i]] - 1, 0, false, true);
- Writes.write(output, counts[array[i]], array[i], 0, false, true);
-
- Writes.changeTempWrites(-2);
- }
- //Usually counting sort returns a sorted copy of the input array. The visualization pretends that happens here.
- for(int i = length - 1; i >= 0; i--) {
- Writes.write(array, i, output[i], 1, false, false);
-
+
+ // Extra loop to simulate the results from the "output" array being written
+ // to the visual array.
+ for (int i = length - 1; i >= 0; i--) {
+ Writes.write(array, i, output[i], 1, true, false);
Writes.changeTempWrites(1);
- Highlights.markArray(1, i);
}
}
}
\ No newline at end of file
diff --git a/src/sorts/FlashSort.java b/src/sorts/FlashSort.java
index 9b2bd387..075350ad 100644
--- a/src/sorts/FlashSort.java
+++ b/src/sorts/FlashSort.java
@@ -6,12 +6,9 @@
import utils.Delays;
import utils.Highlights;
import utils.Reads;
-import utils.Shuffles;
import utils.Writes;
final public class FlashSort extends Sort {
- private Shuffles currentShuffle;
-
public FlashSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps) {
super(delayOps, markOps, readOps, writeOps);
@@ -27,10 +24,6 @@ public FlashSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writ
this.isBogoSort(false);
}
- public void setCurrentShuffle(Shuffles choice) {
- this.currentShuffle = choice;
- }
-
private static int indexOfIntArray(int[] array, int length, int key) {
int returnvalue = -1;
for (int i = 0; i < length; ++i) {
@@ -273,30 +266,29 @@ else if(Reads.compare(array[length - 1], max) == 1)
//skip the K == m class because it is already sorted
//since all of the elements have the same value
- if(!currentShuffle.equals(Shuffles.SIMILAR)) {
- for(K = m - 1; K >= 1; K--)
+ for(K = m - 1; K >= 1; K--)
+ {
+ //determine the number of elments in the Kth class
+ int classSize = L[K + 1] - L[K];
+
+ //if the class size is larger than expected but not
+ //so small that insertion sort could make quick work
+ //of it then...
+ if(classSize > threshold && classSize > minElements)
{
- //determine the number of elments in the Kth class
- int classSize = L[K + 1] - L[K];
-
- //if the class size is larger than expected but not
- //so small that insertion sort could make quick work
- //of it then...
- if(classSize > threshold && classSize > minElements)
- {
- //...attempt to flashsort the class. This will work
- //well if the elements inside the class are uniformly
- //distributed throughout the class otherwise it will
- //perform badly, O(n^2) worst case, since we will have
- //performed another classification and permutation step
- //and not succeeded in making the problem significantly
- //smaller for the next level of recursion. However,
- //progress is assured since at each level the elements
- //with the maximum value will get sorted.
- runSort(Arrays.copyOfRange(array, FlashSort.indexOfIntArray(array, length, L[K]), FlashSort.indexOfIntArray(array, length, L[K+1])), classSize, 0);
- }
+ //...attempt to flashsort the class. This will work
+ //well if the elements inside the class are uniformly
+ //distributed throughout the class otherwise it will
+ //perform badly, O(n^2) worst case, since we will have
+ //performed another classification and permutation step
+ //and not succeeded in making the problem significantly
+ //smaller for the next level of recursion. However,
+ //progress is assured since at each level the elements
+ //with the maximum value will get sorted.
+ runSort(Arrays.copyOfRange(array, L[K], L[K + 1]), classSize, 0);
}
}
+
InsertionSort insertSorter = new InsertionSort(this.Delays, this.Highlights, this.Reads, this.Writes);
insertSorter.customInsertSort(array, 0, length, 0.75, false);
}
diff --git a/src/sorts/FlippedMinHeapSort.java b/src/sorts/FlippedMinHeapSort.java
new file mode 100644
index 00000000..6313c2b5
--- /dev/null
+++ b/src/sorts/FlippedMinHeapSort.java
@@ -0,0 +1,67 @@
+package sorts;
+
+import templates.Sort;
+import utils.Delays;
+import utils.Highlights;
+import utils.Reads;
+import utils.Writes;
+
+/*
+ *
+Copyright (c) rosettacode.org.
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2
+or any later version published by the Free Software Foundation;
+with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+Texts. A copy of the license is included in the section entitled "GNU
+Free Documentation License".
+ *
+ */
+
+/*
+modified by Lucy Phipps from ../templates/HeapSorting.java and MinHeapSort.java
+the only real changes are subtracting every array access from (length - 1)
+and removing the Writes.reverse() at the end
+the rest is just compacting the code a bit
+*/
+
+final public class FlippedMinHeapSort extends Sort {
+ public FlippedMinHeapSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps) {
+ super(delayOps, markOps, readOps, writeOps);
+ this.setSortPromptID("Flipped Min Heap");
+ this.setRunAllID("Flipped Min Heap Sort");
+ this.setReportSortID("Flipped Reverse Heapsort");
+ this.setCategory("Selection Sorts");
+ this.isComparisonBased(true);
+ this.isBucketSort(false);
+ this.isRadixSort(false);
+ this.isUnreasonablySlow(false);
+ this.setUnreasonableLimit(0);
+ this.isBogoSort(false);
+ }
+ private void siftDown(int[] array, int length, int root, int dist) {
+ while (root <= dist / 2) {
+ int leaf = 2 * root;
+ if (leaf < dist && Reads.compare(array[length - leaf], array[length - leaf - 1]) == 1) {
+ leaf++;
+ }
+ Highlights.markArray(1, length - root);
+ Highlights.markArray(2, length - leaf);
+ Delays.sleep(1);
+ if (Reads.compare(array[length - root], array[length - leaf]) == 1) {
+ Writes.swap(array, length - root, length - leaf, 0, true, false);
+ root = leaf;
+ } else break;
+ }
+ }
+ @Override
+ public void runSort(int[] array, int length, int bucketCount) {
+ for (int i = length / 2; i >= 1; i--) {
+ siftDown(array, length, i, length);
+ }
+ for (int i = length; i > 1; i--) {
+ Writes.swap(array, length - 1, length - i, 1, true, false);
+ siftDown(array, length, 1, i - 1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/sorts/GnomeSort.java b/src/sorts/GnomeSort.java
index 607ff664..6d8729aa 100644
--- a/src/sorts/GnomeSort.java
+++ b/src/sorts/GnomeSort.java
@@ -32,7 +32,7 @@ public void runSort(int[] array, int length, int bucketCount) {
{
i++;
Highlights.markArray(1, i);
- Delays.sleep(0.02);
+ Delays.sleep(0.04);
}
else
{
@@ -43,7 +43,7 @@ public void runSort(int[] array, int length, int bucketCount) {
if (i > 1) {
i--;
Highlights.markArray(1, i);
- Delays.sleep(0.01);
+ Delays.sleep(0.02);
}
}
}
diff --git a/src/sorts/GrailSort.java b/src/sorts/GrailSort.java
index c4c83e0e..2651e1bc 100644
--- a/src/sorts/GrailSort.java
+++ b/src/sorts/GrailSort.java
@@ -57,7 +57,8 @@ public GrailSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writ
super(delayOps, markOps, readOps, writeOps);
this.setSortPromptID("Grail");
- this.setRunAllID("Grail Sort (Block Merge Sort)");
+ //this.setRunAllID("Grail Sort (Block Merge Sort)");
+ this.setRunAllID("Grail Sort [Block Merge Sort]");
this.setReportSortID("Grailsort");
this.setCategory("Hybrid Sorts");
this.isComparisonBased(true);
diff --git a/src/sorts/GravitySort.java b/src/sorts/GravitySort.java
index b2019dd3..7df2ce27 100644
--- a/src/sorts/GravitySort.java
+++ b/src/sorts/GravitySort.java
@@ -37,7 +37,8 @@ public GravitySort(Delays delayOps, Highlights markOps, Reads readOps, Writes wr
super(delayOps, markOps, readOps, writeOps);
this.setSortPromptID("Gravity");
- this.setRunAllID("Gravity (Bead) Sort");
+ this.setRunAllID("Gravity Sort");
+ //this.setRunAllID("Gravity (Bead) Sort");
this.setReportSortID("Beadsort");
this.setCategory("Distributive Sorts");
this.isComparisonBased(false);
@@ -50,7 +51,7 @@ public GravitySort(Delays delayOps, Highlights markOps, Reads readOps, Writes wr
@Override
public void runSort(int[] array, int length, int bucketCount) {
- int max = Reads.analyzeMax(array, length, 0.25, true);
+ int max = Reads.analyzeMax(array, length, 1, true);
int[][] abacus = new int[length][max];
for(int i = 0; i < length; i++) {
@@ -60,14 +61,18 @@ public void runSort(int[] array, int length, int bucketCount) {
}
//apply gravity
- for(int i = 0; i < abacus[0].length; i++) {
+ for(int i = 0; i < abacus[0].length; i++) {
for(int j = 0; j < abacus.length; j++) {
- if(abacus[j][i] == 1) {
+ Highlights.markArray(1, j);
+ if(abacus[j][i] == 1) {
//Drop it
int dropPos = j;
- while(dropPos + 1 < abacus.length && abacus[dropPos][i] == 1)
+ Writes.startLap();
+ while(dropPos + 1 < abacus.length && abacus[dropPos][i] == 1) {
dropPos++;
+ }
+ Writes.stopLap();
if(abacus[dropPos][i] == 0) {
Writes.multiDimWrite(abacus, j, i, 0, 0, true, true);
@@ -80,13 +85,15 @@ public void runSort(int[] array, int length, int bucketCount) {
for(int x = 0; x < abacus.length; x++){
count = 0;
- for(int y = 0; y < abacus[0].length; y++)
+ Writes.startLap();
+ for(int y = 0; y < abacus[0].length; y++) {
count += abacus[x][y];
+ }
+ Writes.stopLap();
- Writes.write(array, x, count, 0.002, true, false);
+ Writes.write(array, x, count, 0.001, true, false);
}
Highlights.markArray(2, length - i - 1);
- Delays.sleep(0.001);
}
}
}
\ No newline at end of file
diff --git a/src/sorts/HolyGrailSort.java b/src/sorts/HolyGrailSort.java
index 3d63c343..4e06c63d 100644
--- a/src/sorts/HolyGrailSort.java
+++ b/src/sorts/HolyGrailSort.java
@@ -74,7 +74,7 @@ final public class HolyGrailSort extends HolyGrailSorting {
public HolyGrailSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps) {
super(delayOps, markOps, readOps, writeOps);
- this.setSortPromptID(""); // Sort disabled
+ this.setSortPromptID("Holy Grail");
this.setRunAllID("Holy Grail Sort (Block Merge Sort)");
this.setReportSortID("Holygrailsort");
this.setCategory("Hybrid Sorts");
diff --git a/src/sorts/InPlaceLSDRadixSort.java b/src/sorts/InPlaceLSDRadixSort.java
index 2b381bcd..0c973d5d 100644
--- a/src/sorts/InPlaceLSDRadixSort.java
+++ b/src/sorts/InPlaceLSDRadixSort.java
@@ -33,13 +33,12 @@ of this software and associated documentation files (the "Software"), to deal
*/
final public class InPlaceLSDRadixSort extends Sort {
- private int buckets = 2; // default choice
-
public InPlaceLSDRadixSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps) {
super(delayOps, markOps, readOps, writeOps);
this.setSortPromptID("In-Place LSD Radix");
- this.setRunAllID("In-Place LSD Radix Sort, Base " + buckets);
+ //this.setRunAllID("In-Place LSD Radix Sort, Base 2");
+ this.setRunAllID("In-Place LSD Radix Sort, Base 10");
this.setReportSortID("In-Place LSD Radix Sort");
this.setCategory("Distributive Sorts");
this.isComparisonBased(false);
@@ -52,12 +51,12 @@ public InPlaceLSDRadixSort(Delays delayOps, Highlights markOps, Reads readOps, W
@Override
public void runSort(int[] array, int length, int bucketCount) {
- this.buckets = bucketCount;
+ this.setRunAllID("In-Place LSD Radix Sort, Base " + bucketCount);
int pos = 0;
int[] vregs = new int[bucketCount-1];
- int maxpower = Reads.analyzeMaxLog(array, length, bucketCount, 0.25, true);
+ int maxpower = Reads.analyzeMaxLog(array, length, bucketCount, 0.5, true);
for(int p = 0; p <= maxpower; p++){
for(int i = 0; i < vregs.length; i++) {
@@ -77,7 +76,7 @@ public void runSort(int[] array, int length, int bucketCount) {
for(int j = 0; j < vregs.length;j++)
Highlights.markArray(j + 1, vregs[j]);
- Writes.multiSwap(array, pos, vregs[digit - 1], 0.00075, false, false);
+ Writes.multiSwap(array, pos, vregs[digit - 1], bucketCount / 10000d, false, false);
for(int j = digit - 1; j > 0; j--) {
Writes.write(vregs, j - 1, vregs[j - 1] - 1, 0, false, true);
diff --git a/src/sorts/IntroSort.java b/src/sorts/IntroSort.java
index 0224a2f1..3b14abc0 100644
--- a/src/sorts/IntroSort.java
+++ b/src/sorts/IntroSort.java
@@ -1,5 +1,8 @@
package sorts;
+import java.util.Arrays;
+
+import templates.JErrorPane;
import templates.Sort;
import utils.Delays;
import utils.Highlights;
@@ -21,7 +24,8 @@ public IntroSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writ
super(delayOps, markOps, readOps, writeOps);
this.setSortPromptID("Intro");
- this.setRunAllID("Introspective Sort (std::sort)");
+ //this.setRunAllID("Introspective Sort (std::sort)");
+ this.setRunAllID("Introspective Sort [std::sort]");
this.setReportSortID("Introsort");
this.setCategory("Hybrid Sorts");
this.isComparisonBased(true);
@@ -36,6 +40,33 @@ private static int floorLogBaseTwo(int a) {
return (int) (Math.floor(Math.log(a) / Math.log(2)));
}
+ // Swaps the median of arr[left], arr[mid], and arr[right] to index left.
+ // taken from gcc source code found here: https://gcc.gnu.org/onlinedocs/gcc-4.7.2/libstdc++/api/a01462_source.html
+ private int gccmedianof3(int[] arr, int left, int mid, int right) {
+ if (Reads.compare(arr[left], arr[mid]) < 0) {
+ if (Reads.compare(arr[mid], arr[right]) < 0) {
+ Writes.swap(arr, left, mid, 1, true, false);
+ }
+ else if (Reads.compare(arr[left], arr[right]) < 0) {
+ Writes.swap(arr, left, right, 1, true, false);
+ }
+ }
+ else if (Reads.compare(arr[left], arr[right]) < 0) {
+ middle = left;
+ Highlights.markArray(3, left);
+ return arr[left];
+ }
+ else if (Reads.compare(arr[mid], arr[right]) < 0) {
+ Writes.swap(arr, left, right, 1, true, false);
+ }
+ else {
+ Writes.swap(arr, left, mid, 1, true, false);
+ }
+ middle = left;
+ Highlights.markArray(3, left);
+ return arr[left];
+ }
+
private int medianof3(int[] arr, int left, int mid, int right) {
if(Reads.compare(arr[right], arr[left]) == -1) {
Writes.swap(arr, left, right, 1, true, false);
@@ -94,7 +125,7 @@ private void introsortLoop (int[] a, int lo, int hi, int depthLimit) {
return;
}
depthLimit--;
- int p = partition(a, lo, hi, medianof3(a, lo, lo + ((hi - lo) / 2) + 1, hi - 1));
+ int p = partition(a, lo, hi, medianof3(a, lo, lo + ((hi - lo) / 2), hi - 1));
introsortLoop(a, p, hi, depthLimit);
hi = p;
}
diff --git a/src/sorts/LLQuickSort.java b/src/sorts/LLQuickSort.java
index 7d18b5dd..b948b261 100644
--- a/src/sorts/LLQuickSort.java
+++ b/src/sorts/LLQuickSort.java
@@ -27,10 +27,12 @@ private int partition(int[] array, int lo, int hi) {
int i = lo;
for(int j = lo; j < hi; j++) {
+ Highlights.markArray(1, j);
if(Reads.compare(array[j], pivot) < 0) {
Writes.swap(array, i, j, 1, true, false);
i++;
}
+ Delays.sleep(1);
}
Writes.swap(array, i, hi, 1, true, false);
return i;
diff --git a/src/sorts/LSDRadixSort.java b/src/sorts/LSDRadixSort.java
index 547aca11..5a6a1d3c 100644
--- a/src/sorts/LSDRadixSort.java
+++ b/src/sorts/LSDRadixSort.java
@@ -39,7 +39,7 @@ public LSDRadixSort(Delays delayOps, Highlights markOps, Reads readOps, Writes w
super(delayOps, markOps, readOps, writeOps);
this.setSortPromptID("LSD Radix");
- this.setRunAllID("Least Significant Digit Radix Sort");
+ this.setRunAllID("Least Significant Digit Radix Sort, Base 4");
this.setReportSortID("Least Significant Digit Radixsort");
this.setCategory("Distributive Sorts");
this.isComparisonBased(false);
@@ -52,7 +52,9 @@ public LSDRadixSort(Delays delayOps, Highlights markOps, Reads readOps, Writes w
@Override
public void runSort(int[] array, int length, int bucketCount) {
- int highestpower = Reads.analyzeMaxLog(array, length, bucketCount, 0.25, true);
+ this.setRunAllID("Least Significant Digit Radix Sort, Base " + bucketCount);
+
+ int highestpower = Reads.analyzeMaxLog(array, length, bucketCount, 0.5, true);
@SuppressWarnings("unchecked")
ArrayList[] registers = new ArrayList[bucketCount];
@@ -67,20 +69,10 @@ public void runSort(int[] array, int length, int bucketCount) {
int digit = Reads.getDigit(array[i], p, bucketCount);
registers[digit].add(array[i]);
- Writes.mockWrite(length, digit, array[i], 0.5);
- }
-
- double tempSleep = Delays.getSleepRatio();
-
- if(!Delays.skipped()) {
- Delays.setSleepRatio((Math.log(length) / Math.log(2)) / 4);
+ Writes.mockWrite(length, digit, array[i], 1);
}
- Writes.fancyTranscribe(array, length, registers);
-
- if(!Delays.skipped()) {
- Delays.setSleepRatio(tempSleep);
- }
+ Writes.fancyTranscribe(array, length, registers, bucketCount * 0.8);
}
}
}
\ No newline at end of file
diff --git a/src/sorts/LessBogoSort.java b/src/sorts/LessBogoSort.java
index bca26dad..813322a3 100644
--- a/src/sorts/LessBogoSort.java
+++ b/src/sorts/LessBogoSort.java
@@ -30,7 +30,7 @@ public void runSort(int[] array, int currentLen, int bucketCount) {
while(!this.isMinSorted(array, currentLen, iterator)) {
this.bogoSwap(array, currentLen, iterator);
}
- Highlights.markArray(1, iterator);
+ //Highlights.markArray(1, iterator);
iterator++;
}
}
diff --git a/src/sorts/MSDRadixSort.java b/src/sorts/MSDRadixSort.java
index daa53138..52b49190 100644
--- a/src/sorts/MSDRadixSort.java
+++ b/src/sorts/MSDRadixSort.java
@@ -39,7 +39,8 @@ public MSDRadixSort(Delays delayOps, Highlights markOps, Reads readOps, Writes w
super(delayOps, markOps, readOps, writeOps);
this.setSortPromptID("MSD Radix");
- this.setRunAllID("Most Significant Digit Radix Sort");
+ //this.setRunAllID("Most Significant Digit Radix Sort");
+ this.setRunAllID("Most Significant Digit Radix Sort, Base 4");
this.setReportSortID("Most Significant Digit Radixsort");
this.setCategory("Distributive Sorts");
this.isComparisonBased(false);
@@ -69,23 +70,13 @@ private void radixMSD(int[] array, int length, int min, int max, int radix, int
int digit = Reads.getDigit(array[i], pow, radix);
registers[digit].add(array[i]);
- Writes.mockWrite(length, digit, array[i], 0.5);
+ Writes.mockWrite(length, digit, array[i], 1);
}
Highlights.clearMark(2);
Highlights.clearMark(3);
- double tempSleep = Delays.getSleepRatio();
-
- if(!Delays.skipped()) {
- Delays.setSleepRatio((Math.log(length) / Math.log(2)) / 6);
- }
-
- Writes.transcribeMSD(array, registers, 0, min, true, false);
-
- if(!Delays.skipped()) {
- Delays.setSleepRatio(tempSleep);
- }
+ Writes.transcribeMSD(array, registers, 0, min, 0.8, true, false);
int sum = 0;
for(int i = 0; i < registers.length; i++) {
@@ -99,7 +90,7 @@ private void radixMSD(int[] array, int length, int min, int max, int radix, int
@Override
public void runSort(int[] array, int length, int bucketCount) {
- int highestpower = Reads.analyzeMaxLog(array, length, bucketCount, 0.25, true);
+ int highestpower = Reads.analyzeMaxLog(array, length, bucketCount, 0.5, true);
radixMSD(array, length, 0, length, bucketCount, highestpower);
}
diff --git a/src/sorts/OptimizedDualPivotQuickSort.java b/src/sorts/OptimizedDualPivotQuickSort.java
index e3f7102c..6c530e59 100644
--- a/src/sorts/OptimizedDualPivotQuickSort.java
+++ b/src/sorts/OptimizedDualPivotQuickSort.java
@@ -16,7 +16,8 @@ public OptimizedDualPivotQuickSort(Delays delayOps, Highlights markOps, Reads re
super(delayOps, markOps, readOps, writeOps);
this.setSortPromptID("Opti. Dual-Pivot Quick");
- this.setRunAllID("Optimized Dual-Pivot Quick Sort");
+ //this.setRunAllID("Optimized Dual-Pivot Quick Sort");
+ this.setRunAllID("Optimized Dual-Pivot Quick Sort [Arrays.sort]");
this.setReportSortID("Optimized Dual-Pivot Quicksort");
this.setCategory("Hybrid Sorts");
this.isComparisonBased(true);
@@ -33,7 +34,7 @@ private void dualPivot(int[] array, int left, int right, int divisor) {
// insertion sort for tiny array
if(length < 27) {
Highlights.clearMark(2);
- insertSorter.customInsertSort(array, left, right + 1, 0.75, false);
+ insertSorter.customInsertSort(array, left, right + 1, 1, false);
return;
}
@@ -74,8 +75,11 @@ private void dualPivot(int[] array, int left, int right, int divisor) {
else if(Reads.compare(array[k], pivot2) == 1) {
while(k < great && Reads.compare(array[great], pivot2) == 1) {
great--;
+ Highlights.markArray(3, great);
+ Delays.sleep(1);
}
Writes.swap(array, k, great--, 1, true, false);
+ Highlights.clearMark(3);
if(Reads.compare(array[k], pivot1) == -1) {
Writes.swap(array, k, less++, 1, true, false);
diff --git a/src/sorts/PancakeSort.java b/src/sorts/PancakeSort.java
index b63a9b59..852fed1d 100644
--- a/src/sorts/PancakeSort.java
+++ b/src/sorts/PancakeSort.java
@@ -20,8 +20,8 @@ public PancakeSort(Delays delayOps, Highlights markOps, Reads readOps, Writes wr
super(delayOps, markOps, readOps, writeOps);
this.setSortPromptID("Pancake");
- this.setRunAllID("Pancake Sort");
- this.setReportSortID("Pancake Sorting");
+ this.setRunAllID("Pancake Sorting");
+ this.setReportSortID("Pancake Sort");
this.setCategory("Miscellaneous Sorts");
this.isComparisonBased(true);
this.isBucketSort(false);
@@ -32,7 +32,7 @@ public PancakeSort(Delays delayOps, Highlights markOps, Reads readOps, Writes wr
}
private boolean sorted(int[] array, int length) {
- for(int i = 0; i < length - 1; i++) {
+ for(int i = 0; i < length; i++) {
Highlights.markArray(1, i);
Delays.sleep(0.025);
@@ -49,6 +49,7 @@ private int findMax(int[] arr, int end) {
if (Reads.compare(arr[i], max) == 1) {
max = arr[i];
index = i;
+ Highlights.markArray(2, i);
}
Delays.sleep(0.025);
@@ -61,7 +62,6 @@ private int findMax(int[] arr, int end) {
public void runSort(int[] array, int length, int bucketCount) {
for (int i = length - 1; i >= 0; i--) {
if(!this.sorted(array, i)) {
- if(i + 1 != length) Highlights.markArray(3, i + 1);
int index = this.findMax(array, i);
if(index == 0) {
diff --git a/src/sorts/PatienceSort.java b/src/sorts/PatienceSort.java
index 908df65c..c02494e3 100644
--- a/src/sorts/PatienceSort.java
+++ b/src/sorts/PatienceSort.java
@@ -81,7 +81,7 @@ public void runSort(int[] array, int length, int bucketCount) {
Pile newPile = new Pile();
Highlights.markArray(2, x);
- Writes.mockWrite(length, newPile.size(), array[x], 1);
+ Writes.mockWrite(length, Math.min(newPile.size(), length - 1), array[x], 1);
newPile.push(array[x]);
@@ -91,11 +91,11 @@ public void runSort(int[] array, int length, int bucketCount) {
}
if (i < 0) i = ~i;
if (i != piles.size()) {
- Writes.mockWrite(length, piles.get(i).size(), array[x], 0);
+ Writes.mockWrite(length, Math.min(piles.get(i).size(), length - 1), array[x], 0);
piles.get(i).push(array[x]);
}
else {
- Writes.mockWrite(length, piles.size(), newPile.get(0), 0);
+ Writes.mockWrite(length, Math.min(piles.size(), length - 1), newPile.get(0), 0);
piles.add(newPile);
}
}
@@ -106,16 +106,14 @@ public void runSort(int[] array, int length, int bucketCount) {
PriorityQueue heap = new PriorityQueue<>(piles);
for (int c = 0; c < length; c++) {
- Writes.mockWrite(length, heap.size(), 0, 0);
+ Writes.mockWrite(length, Math.min(heap.size(), length - 1), 0, 0);
Pile smallPile = heap.poll();
- Writes.mockWrite(length, smallPile.size(), 0, 0);
- Writes.write(array, c, smallPile.pop(), 1, false, false);
-
- Highlights.markArray(1, c);
+ Writes.mockWrite(length, Math.min(smallPile.size(), length - 1), 0, 0);
+ Writes.write(array, c, smallPile.pop(), 1, true, false);
if (!smallPile.isEmpty()) {
- Writes.mockWrite(length, heap.size(), smallPile.get(0), 0);
+ Writes.mockWrite(length, Math.min(heap.size(), length - 1), smallPile.get(0), 0);
heap.offer(smallPile);
}
}
diff --git a/src/sorts/RecursiveCombSort.java b/src/sorts/RecursiveCombSort.java
index 876e9470..2f51344c 100644
--- a/src/sorts/RecursiveCombSort.java
+++ b/src/sorts/RecursiveCombSort.java
@@ -9,6 +9,7 @@
/*
*
MIT License
+Copyright (c) 2019 w0rthy
Copyright (c) 2019 PiotrGrochowski
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -94,4 +95,4 @@ private void finishrecucomb(int[] array, int start, int end, int gap, double sle
public void runSort(int[] array, int length, int bucketCount) {
this.recursivecomb(array, 0, length, 1, 1);
}
-}
+}
\ No newline at end of file
diff --git a/src/sorts/RotateMergeSort.java b/src/sorts/RotateMergeSort.java
index 426d1a43..36e42298 100644
--- a/src/sorts/RotateMergeSort.java
+++ b/src/sorts/RotateMergeSort.java
@@ -49,7 +49,8 @@ public RotateMergeSort(Delays delayOps, Highlights markOps, Reads readOps, Write
super(delayOps, markOps, readOps, writeOps);
this.setSortPromptID("Rotate Merge");
- this.setRunAllID("In-Place Merge Sort with Rotations");
+ this.setRunAllID("Rotate Merge Sort");
+ //this.setRunAllID("In-Place Merge Sort with Rotations");
this.setReportSortID("In-Place Rotate Mergesort");
this.setCategory("Merge Sorts");
this.isComparisonBased(true);
diff --git a/src/sorts/SillySort.java b/src/sorts/SillySort.java
index 70f1201d..25a0eecb 100644
--- a/src/sorts/SillySort.java
+++ b/src/sorts/SillySort.java
@@ -28,12 +28,12 @@ public SillySort(Delays delayOps, Highlights markOps, Reads readOps, Writes writ
private void sillySort(int[] array, int i, int j) {
int m;
+ Delays.sleep(1);
+
if (i < j) {
/* find the middle of the array */
m = i + ((j - i) / 2);
- Highlights.markArray(3, m);
-
/*
* use this function (recursively) to find put the minimum elements of
* each half into the first elements of each half
diff --git a/src/sorts/SkaSort.java b/src/sorts/SkaSort_disabled.java
similarity index 100%
rename from src/sorts/SkaSort.java
rename to src/sorts/SkaSort_disabled.java
diff --git a/src/sorts/SlowSort.java b/src/sorts/SlowSort.java
index 96ad2297..7be2b1d7 100644
--- a/src/sorts/SlowSort.java
+++ b/src/sorts/SlowSort.java
@@ -25,13 +25,13 @@ public SlowSort(Delays delayOps, Highlights markOps, Reads readOps, Writes write
}
private void slowSort(int[] A, int i, int j) {
- if (i >= j) {
+ Delays.sleep(1);
+
+ if (i >= j) {
return;
}
-
+
int m = i + ((j - i) / 2);
-
- Highlights.markArray(3, m);
this.slowSort(A, i, m);
this.slowSort(A, m + 1, j);
diff --git a/src/sorts/SmartBubbleSort.java b/src/sorts/SmartBubbleSort.java
index d097f0ec..1352d402 100644
--- a/src/sorts/SmartBubbleSort.java
+++ b/src/sorts/SmartBubbleSort.java
@@ -50,16 +50,19 @@ public SmartBubbleSort(Delays delayOps, Highlights markOps, Reads readOps, Write
@Override
public void runSort(int[] array, int length, int bucketCount) {
- for(int i = length - 1; i > 0; i--){
+ for(int i = length - 1; i > 0; i--) {
+ boolean sorted = true;
for(int j = 0; j < i; j++) {
if(Reads.compare(array[j], array[j + 1]) == 1){
Writes.swap(array, j, j + 1, 0.075, true, false);
+ sorted = false;
}
Highlights.markArray(1, j);
Highlights.markArray(2, j + 1);
Delays.sleep(0.025);
}
+ if(sorted) break;
}
}
}
\ No newline at end of file
diff --git a/src/sorts/SmartCocktailSort.java b/src/sorts/SmartCocktailSort.java
new file mode 100644
index 00000000..df688c6c
--- /dev/null
+++ b/src/sorts/SmartCocktailSort.java
@@ -0,0 +1,90 @@
+package sorts;
+
+import templates.Sort;
+import utils.Delays;
+import utils.Highlights;
+import utils.Reads;
+import utils.Writes;
+
+/*
+ *
+MIT License
+
+Copyright (c) 2019 w0rthy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ *
+ */
+
+final public class SmartCocktailSort extends Sort {
+ public SmartCocktailSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps) {
+ super(delayOps, markOps, readOps, writeOps);
+
+ this.setSortPromptID("Smart Cocktail");
+ this.setRunAllID("Optimized Cocktail Shaker Sort");
+ this.setReportSortID("Optimized Cocktail Shaker Sort");
+ this.setCategory("Exchange Sorts");
+ this.isComparisonBased(true);
+ this.isBucketSort(false);
+ this.isRadixSort(false);
+ this.isUnreasonablySlow(false);
+ this.setUnreasonableLimit(0);
+ this.isBogoSort(false);
+ }
+
+ private void smartCocktailShaker(int[] array, int start, int end, double sleep) {
+ int i = start;
+ while(i < ((end / 2) + start)) {
+ boolean sorted = true;
+ for(int j = i; j < end + start - i - 1; j++) {
+ if(Reads.compare(array[j], array[j + 1]) == 1) {
+ Writes.swap(array, j, j + 1, sleep, true, false);
+ sorted = false;
+ }
+
+ Highlights.markArray(1, j);
+ Highlights.markArray(2, j + 1);
+
+ Delays.sleep(sleep / 2);
+ }
+ for(int j = end + start - i - 1; j > i; j--){
+ if(Reads.compare(array[j], array[j - 1]) == -1) {
+ Writes.swap(array, j, j - 1, sleep, true, false);
+ sorted = false;
+ }
+
+ Highlights.markArray(1, j);
+ Highlights.markArray(2, j - 1);
+
+ Delays.sleep(sleep / 2);
+ }
+ if(sorted) break;
+ else i++;
+ }
+ }
+
+ public void customSort(int[] array, int start, int end) {
+ this.smartCocktailShaker(array, start, end, 1);
+ }
+
+ @Override
+ public void runSort(int[] array, int length, int bucketCount) {
+ this.smartCocktailShaker(array, 0, length, 0.1);
+ }
+}
\ No newline at end of file
diff --git a/src/sorts/SmartGnomeSort.java b/src/sorts/SmartGnomeSort.java
index 17d30689..f65aab3c 100644
--- a/src/sorts/SmartGnomeSort.java
+++ b/src/sorts/SmartGnomeSort.java
@@ -23,19 +23,25 @@ public SmartGnomeSort(Delays delayOps, Highlights markOps, Reads readOps, Writes
}
// Taken from https://en.wikipedia.org/wiki/Gnome_sort
- private void smartGnomeSort(int[] array, int upperBound) {
+ private void smartGnomeSort(int[] array, int upperBound, double sleep) {
int pos = upperBound;
while(pos > 0 && Reads.compare(array[pos - 1], array[pos]) == 1) {
- Writes.swap(array, pos - 1, pos, 0.05, true, false);
+ Writes.swap(array, pos - 1, pos, sleep, true, false);
pos--;
}
}
+ public void customSort(int[] array, int low, int high, double sleep) {
+ for(int i = low + 1; i < high; i++) {
+ smartGnomeSort(array, i, sleep);
+ }
+ }
+
@Override
public void runSort(int[] array, int length, int bucketCount) {
for(int i = 1; i < length; i++) {
- smartGnomeSort(array, i);
+ smartGnomeSort(array, i, 0.05);
}
}
}
\ No newline at end of file
diff --git a/src/sorts/SqrtSort.java b/src/sorts/SqrtSort.java
index fcdd358d..88cf0d2d 100644
--- a/src/sorts/SqrtSort.java
+++ b/src/sorts/SqrtSort.java
@@ -69,7 +69,8 @@ public SqrtSort(Delays delayOps, Highlights markOps, Reads readOps, Writes write
super(delayOps, markOps, readOps, writeOps);
this.setSortPromptID("Sqrt");
- this.setRunAllID("Square Root Sort (Block Merge Sort");
+ //this.setRunAllID("Square Root Sort (Block Merge Sort)");
+ this.setRunAllID("Square Root Sort [Block Merge Sort]");
this.setReportSortID("Sqrtsort");
this.setCategory("Hybrid Sorts");
this.isComparisonBased(true);
diff --git a/src/sorts/TimSort.java b/src/sorts/TimSort.java
index 6409a925..abf33192 100644
--- a/src/sorts/TimSort.java
+++ b/src/sorts/TimSort.java
@@ -47,7 +47,7 @@ public TimSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writeO
@Override
public void runSort(int[] array, int currentLength, int bucketCount) {
- this.timSortInstance = new TimSorting(array, currentLength, this.Highlights, this.Reads, this.Writes);
+ this.timSortInstance = new TimSorting(array, currentLength, this.Delays, this.Highlights, this.Reads, this.Writes);
TimSorting.sort(this.timSortInstance, array, currentLength);
}
diff --git a/src/sorts/TimeSort.java b/src/sorts/TimeSort.java
index f108f3fd..50b39f69 100644
--- a/src/sorts/TimeSort.java
+++ b/src/sorts/TimeSort.java
@@ -46,7 +46,8 @@ public TimeSort(Delays delayOps, Highlights markOps, Reads readOps, Writes write
super(delayOps, markOps, readOps, writeOps);
this.setSortPromptID("Time");
- this.setRunAllID("Time Sort");
+ //this.setRunAllID("Time Sort");
+ this.setRunAllID("Time Sort, Mul 10");
this.setReportSortID("Timesort");
this.setCategory("Distributive Sorts");
this.isComparisonBased(false);
diff --git a/src/sorts/TournamentSort.java b/src/sorts/TournamentSort.java
index f4dc0a03..66aeb9df 100644
--- a/src/sorts/TournamentSort.java
+++ b/src/sorts/TournamentSort.java
@@ -150,8 +150,7 @@ private void sort(int[] arr, int currentLen) {
for (int i = 0; i < currentLen; i++) {
Integer selected = copy.get(i);
- Writes.write(arr, i, selected, 1, false, false);
- Highlights.markArray(1, i);
+ Writes.write(arr, i, selected, 1, true, false);
}
}
diff --git a/src/sorts/TreeSort.java b/src/sorts/TreeSort.java
index f3ad41bb..3e2bc4b9 100644
--- a/src/sorts/TreeSort.java
+++ b/src/sorts/TreeSort.java
@@ -6,13 +6,12 @@
import utils.Reads;
import utils.Writes;
-//TODO: Code's an absolute mess. Refactor it at some point.
final public class TreeSort extends Sort {
public TreeSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps) {
super(delayOps, markOps, readOps, writeOps);
this.setSortPromptID("Tree");
- this.setRunAllID("Tree Sort");
+ this.setRunAllID("Tree Sort (Unbalanced)");
this.setReportSortID("Treesort");
this.setCategory("Insertion Sorts");
this.isComparisonBased(true);
@@ -24,122 +23,73 @@ public TreeSort(Delays delayOps, Highlights markOps, Reads readOps, Writes write
}
// Code retrieved from https://www.geeksforgeeks.org/tree-sort/
-
- // Java program to
- // implement Tree Sort
- final class TreeSorter
- {
-
- // Class containing left and
- // right child of current
- // node and key value
- final class Node
- {
- int key;
- Node left, right;
-
- public Node(int item)
- {
- key = item;
- left = right = null;
- }
- }
-
- // Root of BST
- Node root;
-
- //Index for final result
- int index;
-
- //Field to store current length
- int length;
-
- // Constructor
- TreeSorter()
- {
- root = null;
- }
+
+ final private class Node {
+ int key;
+ Node left, right;
- //Method has to be inside TreeSort to access Node class directly
- public Node treeWrite(Node element, int at) {
- Node node = new Node(0);
-
- if(at < length) Highlights.markArray(1, at - 1);
-
- Writes.changeTempWrites(1);
-
- Writes.startLap();
-
- node = element;
-
- Writes.stopLap();
-
- Delays.sleep(0.25);
-
- return node;
- }
-
- // This method mainly
- // calls insertRec()
- void insert(int key)
- {
- this.root = treeWrite(insertRec(root, key, 1), 1);
- }
+ public Node(int item) {
+ key = item;
+ left = right = null;
+ }
+ }
+
+ private Node root;
+ private int index, length;
- /* A recursive function to
- insert a new key in BST */
- Node insertRec(Node root, int key, int depth)
- {
+ private Node treeWrite(Node element, int at) {
+ Node node = new Node(0);
+
+ if(at > 0 && at < this.length) Highlights.markArray(1, at - 1);
+ Writes.changeTempWrites(1);
+ Writes.startLap();
+ node = element;
+ Writes.stopLap();
+
+ Delays.sleep(0.25);
+
+ return node;
+ }
- /* If the tree is empty,
- return a new node */
- if (root == null)
- {
- root = treeWrite(new Node(key), 1);
- return root;
- }
+ private void insert(int key) {
+ this.root = this.treeWrite(insertRec(this.root, key, 1), 1);
+ }
+
+ private Node insertRec(Node root, int key, int depth) {
+ if (root == null) {
+ root = treeWrite(new Node(key), 1);
+ return root;
+ }
- /* Otherwise, recur
- down the tree */
- if (Reads.compare(key, root.key) == -1)
- root.left = treeWrite(insertRec(root.left, key, depth * 2), depth * 2);
- else if (Reads.compare(key, root.key) == 1)
- root.right = treeWrite(insertRec(root.right, key, (depth * 2) + 1), (depth * 2) + 1);
+ if (Reads.compare(key, root.key) == -1)
+ root.left = treeWrite(insertRec(root.left, key, depth * 2), depth * 2);
+ else if (Reads.compare(key, root.key) == 1)
+ root.right = treeWrite(insertRec(root.right, key, (depth * 2) + 1), (depth * 2) + 1);
- /* return the root */
- return root;
- }
+ return root;
+ }
- // A function to do
- // inorder traversal of BST
- void inorderRec(Node root, int[] array)
- {
- if (root != null)
- {
- inorderRec(root.left, array);
- Writes.write(array, this.index++, root.key, 1, true, false);
- inorderRec(root.right, array);
- }
- }
+ private void traverseRec(Node root, int[] array) {
+ if (root != null) {
+ this.traverseRec(root.left, array);
+ Writes.write(array, this.index++, root.key, 1, true, false);
+ this.traverseRec(root.right, array);
+ }
+ }
- void treeins(int arr[], int length)
- {
- for(int i = 0; i < length; i++)
- {
- Highlights.markArray(2, i);
- insert(arr[i]);
- }
- Highlights.clearMark(2);
- }
-
- }
+ private void treeIns(int arr[]) {
+ for(int i = 0; i < this.length; i++) {
+ Highlights.markArray(2, i);
+ this.insert(arr[i]);
+ }
+ Highlights.clearMark(2);
+ }
@Override
public void runSort(int[] array, int currentLength, int bucketCount) {
- TreeSorter tree = new TreeSorter();
- tree.length = currentLength;
- tree.treeins(array, tree.length);
- tree.index = 0;
- tree.inorderRec(tree.root, array);
+ this.length = currentLength;
+ this.treeIns(array);
+ this.index = 0;
+ this.traverseRec(this.root, array);
}
}
\ No newline at end of file
diff --git a/src/sorts/WikiSort.java b/src/sorts/WikiSort.java
index 60bfff00..a47fe131 100644
--- a/src/sorts/WikiSort.java
+++ b/src/sorts/WikiSort.java
@@ -59,7 +59,8 @@ public WikiSort(Delays delayOps, Highlights markOps, Reads readOps, Writes write
super(delayOps, markOps, readOps, writeOps);
this.setSortPromptID("Wiki");
- this.setRunAllID("Wiki Sort (Block Merge Sort)");
+ //this.setRunAllID("Wiki Sort (Block Merge Sort)");
+ this.setRunAllID("Wiki Sort [Block Merge Sort]");
this.setReportSortID("Wikisort");
this.setCategory("Hybrid Sorts");
this.isComparisonBased(true);
@@ -75,7 +76,7 @@ public void runSort(int[] array, int currentLength, int bucketCount) {
this.cache = 0;
this.insertionSort = new InsertionSort(this.Delays, this.Highlights, this.Reads, this.Writes);
- this.wikiSortInstance = new WikiSorting(this.insertionSort, this.Highlights, this.Reads, this.Writes, this.cache);
+ this.wikiSortInstance = new WikiSorting(this.insertionSort, this.Delays, this.Highlights, this.Reads, this.Writes, this.cache);
WikiSorting.sort(this.wikiSortInstance, array, currentLength);
}
diff --git a/src/soundfont/SFXFetcher.java b/src/soundfont/SFXFetcher.java
new file mode 100644
index 00000000..25ec52a9
--- /dev/null
+++ b/src/soundfont/SFXFetcher.java
@@ -0,0 +1,15 @@
+package soundfont;
+
+import java.io.InputStream;
+
+final public class SFXFetcher {
+ private InputStream sfxFile;
+
+ public SFXFetcher() {
+ this.sfxFile = this.getClass().getResourceAsStream("sfx.sf2");
+ }
+
+ public InputStream getSFXFile() {
+ return this.sfxFile;
+ }
+}
\ No newline at end of file
diff --git a/src/soundfont/sfx.sf2 b/src/soundfont/sfx.sf2
new file mode 100644
index 00000000..6445a80a
Binary files /dev/null and b/src/soundfont/sfx.sf2 differ
diff --git a/src/templates/BinaryInsertionSorting.java b/src/templates/BinaryInsertionSorting.java
index 70a110d3..6e28953b 100644
--- a/src/templates/BinaryInsertionSorting.java
+++ b/src/templates/BinaryInsertionSorting.java
@@ -43,7 +43,9 @@ protected void binaryInsertSort(int[] array, int start, int end, double compSlee
while (lo < hi) {
int mid = lo + ((hi - lo) / 2); // avoid int overflow!
+ Highlights.markArray(1, lo);
Highlights.markArray(2, mid);
+ Highlights.markArray(3, hi);
Delays.sleep(compSleep);
@@ -55,6 +57,8 @@ protected void binaryInsertSort(int[] array, int start, int end, double compSlee
}
}
+ Highlights.clearMark(3);
+
// item has to go into position lo
int j = i - 1;
diff --git a/src/templates/BogoSorting.java b/src/templates/BogoSorting.java
index 706a3c32..55ae58d9 100644
--- a/src/templates/BogoSorting.java
+++ b/src/templates/BogoSorting.java
@@ -37,12 +37,12 @@ protected BogoSorting(Delays delayOps, Highlights markOps, Reads readOps, Writes
}
private static int randomPosition(int length, int offset) {
- return (int) ((Math.random() * (length - offset)) + offset);
+ return (int) (Math.random() * (length - offset));
}
protected void bogoSwap(int[] array, int length, int offset){
for(int i = offset; i < length; i++) {
- Writes.swap(array, i, BogoSorting.randomPosition(length, offset), 0, true, false);
+ Writes.swap(array, i, BogoSorting.randomPosition(length, i) + i, 0, true, false);
}
}
@@ -60,8 +60,8 @@ protected boolean bogoIsSorted(int[] array, int length){
protected boolean isMinSorted(int[] array, int length, int offset) {
Highlights.clearAllMarks();
- Highlights.markArray(2, offset);
- Highlights.markArray(3, length);
+ //Highlights.markArray(2, offset);
+ //Highlights.markArray(3, length);
for(int i = offset + 1; i < length; i++) {
Highlights.markArray(1, i);
@@ -77,8 +77,8 @@ protected boolean isMinSorted(int[] array, int length, int offset) {
protected boolean isMaxSorted(int[] array, int minIterator, int maxIterator) {
Highlights.clearAllMarks();
- Highlights.markArray(2, minIterator);
- Highlights.markArray(3, maxIterator);
+ //Highlights.markArray(2, minIterator);
+ //Highlights.markArray(3, maxIterator);
for(int i = maxIterator; i >= minIterator; i--) {
Highlights.markArray(1, i);
diff --git a/src/templates/CombSorting.java b/src/templates/CombSorting.java
index 980331f9..ce22b5f3 100644
--- a/src/templates/CombSorting.java
+++ b/src/templates/CombSorting.java
@@ -75,7 +75,7 @@ protected void combSort(ArrayVisualizer ArrayVisualizer, int[] array, int length
//ArrayVisualizer.setCurrentGap(gap);
if(gap == 1)
- Delays.setSleepRatio(10);
+ Delays.setSleepRatio(3);
}
swapped = false;
diff --git a/src/templates/GrailSorting.java b/src/templates/GrailSorting.java
index ca975090..7a3027d4 100644
--- a/src/templates/GrailSorting.java
+++ b/src/templates/GrailSorting.java
@@ -1,6 +1,6 @@
package templates;
-import sorts.InsertionSort;
+import sorts.SmartGnomeSort;
import utils.Delays;
import utils.Highlights;
import utils.Reads;
@@ -50,11 +50,11 @@ this software and associated documentation files (the "Software"), to deal in
/* */
/*********************************************************/
-final class GrailState {
+final class GrailPair {
private int leftOverLen;
private int leftOverFrag;
- protected GrailState(int len, int frag) {
+ protected GrailPair(int len, int frag) {
this.leftOverLen = len;
this.leftOverFrag = frag;
}
@@ -69,7 +69,7 @@ protected int getLeftOverFrag() {
}
public abstract class GrailSorting extends Sort {
- private InsertionSort insertSorter;
+ private SmartGnomeSort 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.
@@ -84,7 +84,7 @@ protected int getStaticBuffer() {
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) {
while(swapsLeft != 0) {
this.grailSwap(arr, a++, b++);
@@ -107,7 +107,7 @@ private void grailRotate(int[] array, int pos, int lenA, int lenB) {
}
private void grailInsertSort(int[] arr, int pos, int len) {
- insertSorter.customInsertSort(arr, pos, len, 0.25, false);
+ grailInsertSorter.customSort(arr, pos, len, 0.75);
}
//boolean argument determines direction
@@ -126,7 +126,7 @@ private int grailBinSearch(int[] arr, int pos, int len, int keyPos, boolean isLe
right = mid;
} else left = mid;
}
- Highlights.markArray(1, mid);
+ Highlights.markArray(1, pos + mid);
}
return right;
}
@@ -138,7 +138,7 @@ private int grailFindKeys(int[] arr, int pos, int len, int numKeys) {
while(dist < len && foundKeys < numKeys) {
//Binary Search left
int loc = this.grailBinSearch(arr, pos + firstKey, foundKeys, pos + dist, true);
- if(loc == foundKeys || Reads.compare(arr[pos + dist], arr[pos + (firstKey + loc)]) != 0) {
+ if(loc == foundKeys || Reads.compare(arr[pos + dist], arr[pos + (firstKey + loc)]) != 0) {
this.grailRotate(arr, pos + firstKey, foundKeys, dist - (firstKey + foundKeys));
firstKey = dist - foundKeys;
this.grailRotate(arr, pos + (firstKey + loc), foundKeys - loc, 1);
@@ -218,11 +218,11 @@ private void grailMergeBuffersLeft(int[] arr, int keysPos, int midkey, int pos,
leftOverLen = blockLen;
} else {
if(havebuf) {
- GrailState results = this.grailSmartMergeWithBuffer(arr, pos + restToProcess, leftOverLen, leftOverFrag, blockLen);
+ GrailPair results = this.grailSmartMergeWithBuffer(arr, pos + restToProcess, leftOverLen, leftOverFrag, blockLen);
leftOverLen = results.getLeftOverLen();
leftOverFrag = results.getLeftOverFrag();
} else {
- GrailState results = this.grailSmartMergeWithoutBuffer(arr, pos + restToProcess, leftOverLen, leftOverFrag, blockLen);
+ GrailPair results = this.grailSmartMergeWithoutBuffer(arr, pos + restToProcess, leftOverLen, leftOverFrag, blockLen);
leftOverLen = results.getLeftOverLen();
leftOverFrag = results.getLeftOverFrag();
}
@@ -297,8 +297,8 @@ private void grailMergeRight(int[] arr, int pos, int leftLen, int rightLen, int
}
//returns the leftover length, then the leftover fragment
- private GrailState grailSmartMergeWithoutBuffer(int[] arr, int pos, int leftOverLen, int leftOverFrag, int regBlockLen) {
- if(regBlockLen == 0) return new GrailState(leftOverLen, leftOverFrag);
+ private GrailPair grailSmartMergeWithoutBuffer(int[] arr, int pos, int leftOverLen, int leftOverFrag, int regBlockLen) {
+ if(regBlockLen == 0) return new GrailPair(leftOverLen, leftOverFrag);
int len1 = leftOverLen;
int len2 = regBlockLen;
@@ -321,7 +321,7 @@ private GrailState grailSmartMergeWithoutBuffer(int[] arr, int pos, int leftOver
len2 -= foundLen;
}
if(len2 == 0) {
- return new GrailState(len1, leftOverFrag);
+ return new GrailPair(len1, leftOverFrag);
}
do {
pos++;
@@ -329,11 +329,11 @@ private GrailState grailSmartMergeWithoutBuffer(int[] arr, int pos, int leftOver
} while(len1 != 0 && Reads.compare(arr[pos], arr[pos + len1]) - typeFrag < 0);
}
}
- return new GrailState(len2, typeFrag);
+ return new GrailPair(len2, typeFrag);
}
//returns the leftover length, then the leftover fragment
- private GrailState grailSmartMergeWithBuffer(int[] arr, int pos, int leftOverLen, int leftOverFrag, int blockLen) {
+ private GrailPair grailSmartMergeWithBuffer(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
@@ -356,14 +356,14 @@ private GrailState grailSmartMergeWithBuffer(int[] arr, int pos, int leftOverLen
length = rightEnd - right;
fragment = typeFrag;
}
- return new GrailState(length, fragment);
+ return new GrailPair(length, fragment);
}
/***** Sort With Extra Buffer *****/
//returns the leftover length, then the leftover fragment
- private GrailState grailSmartMergeWithXBuf(int[] arr, int pos, int leftOverLen, int leftOverFrag, int blockLen) {
+ 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
@@ -388,7 +388,7 @@ private GrailState grailSmartMergeWithXBuf(int[] arr, int pos, int leftOverLen,
length = rightEnd - right;
fragment = typeFrag;
}
- return new GrailState(length, fragment);
+ return new GrailPair(length, fragment);
}
// arr[dist..-1] - free, arr[0, leftEnd - 1] ++ arr[leftEnd, leftEnd + rightEnd - 1]
@@ -448,7 +448,7 @@ private void grailMergeBuffersLeftWithXBuf(int[] arr, int keysPos, int midkey, i
restToProcess = processIndex;
leftOverLen = regBlockLen;
} else {
- GrailState results = this.grailSmartMergeWithXBuf(arr, pos + restToProcess, leftOverLen, leftOverFrag, regBlockLen);
+ GrailPair results = this.grailSmartMergeWithXBuf(arr, pos + restToProcess, leftOverLen, leftOverFrag, regBlockLen);
leftOverLen = results.getLeftOverLen();
leftOverFrag = results.getLeftOverFrag();
}
@@ -581,7 +581,7 @@ private void grailCombineBlocks(int[] arr, int keyPos, int pos, int len, int bui
for(int rightIndex = index; rightIndex < blockCount; rightIndex++) {
int rightComp = Reads.compare(arr[blockPos + leftIndex * regBlockLen],
- arr[blockPos + rightIndex * regBlockLen]);
+ arr[blockPos + rightIndex * regBlockLen]);
if(rightComp > 0 || (rightComp == 0 && Reads.compare(arr[keyPos + leftIndex], arr[keyPos + rightIndex]) > 0)) {
leftIndex = rightIndex;
}
@@ -652,7 +652,7 @@ protected void grailLazyStableSort(int[] arr, int pos, int len) {
}
protected void grailCommonSort(int[] arr, int pos, int len, int[] buffer, int bufferPos, int bufferLen) {
- insertSorter = new InsertionSort(this.Delays, this.Highlights, this.Reads, this.Writes);
+ this.grailInsertSorter = new SmartGnomeSort(Delays, Highlights, Reads, Writes);
if(len <= 16) {
this.grailInsertSort(arr, pos, len);
diff --git a/src/templates/HeapSorting.java b/src/templates/HeapSorting.java
index 79cdd5d8..c0f2dfa5 100644
--- a/src/templates/HeapSorting.java
+++ b/src/templates/HeapSorting.java
@@ -33,8 +33,11 @@ private void siftDown(int[] array, int root, int dist, int start, double sleep,
if (leaf < dist && Reads.compare(array[start + leaf - 1], array[start + leaf]) == compareVal) {
leaf++;
}
+ Highlights.markArray(1, start + root - 1);
+ Highlights.markArray(2, start + leaf - 1);
+ Delays.sleep(sleep);
if (Reads.compare(array[start + root - 1], array[start + leaf - 1]) == compareVal) {
- Writes.swap(array, start + root - 1, start + leaf - 1, sleep, true, false);
+ Writes.swap(array, start + root - 1, start + leaf - 1, 0, true, false);
root = leaf;
}
else break;
diff --git a/src/templates/HolyGrailSorting.java b/src/templates/HolyGrailSorting.java
index f59f898b..b0678998 100644
--- a/src/templates/HolyGrailSorting.java
+++ b/src/templates/HolyGrailSorting.java
@@ -109,52 +109,52 @@ private void grailMultiSwap(int[] arr, int a, int b, int swapsLeft) {
// Copy element at pos, shift elements from pos + 1 to pos + len to the left by 1,
// and paste copied element at pos + len.
- private void grailForwardShift(int[] array, int pos, int len) {
- int temp = array[pos];
+ private void grailForwardShift(int[] array, int index, int shiftsLeft) {
+ int temp = array[index];
- while(len > 0) {
- Writes.write(array, pos, array[pos + 1], 1, true, false);
- pos++;
- len--;
+ while(shiftsLeft > 0) {
+ Writes.write(array, index, array[index + 1], 1, true, false);
+ index++;
+ shiftsLeft--;
}
- Writes.write(array, pos, temp, 1, true, false);
+ Writes.write(array, index, temp, 1, true, false);
}
// Copy element at pos + len, shift elements from pos to pos + len - 1 to the right by 1,
// and paste copied element at pos.
- private void grailBackwardShift(int[] array, int pos, int len) {
- int temp = array[pos + len];
+ private void grailBackwardShift(int[] array, int index, int shiftsLeft) {
+ int temp = array[index + shiftsLeft];
- while(len > 0) {
- Writes.write(array, pos + len, array[pos + len - 1], 1, true, false);
- len--;
+ while(shiftsLeft > 0) {
+ Writes.write(array, index + shiftsLeft, array[(index - 1) + shiftsLeft], 1, true, false);
+ shiftsLeft--;
}
- Writes.write(array, pos, temp, 1, true, false);
+ Writes.write(array, index, temp, 1, true, false);
}
- private void grailRotate(int[] array, int pos, int indexA, int indexB) {
- while(indexA != 0 && indexB != 0) {
- if(indexA <= indexB) {
- if(indexA != 1) {
- this.grailMultiSwap(array, pos, pos + indexA, indexA);
- pos += indexA;
- indexB -= indexA;
+ private void grailRotate(int[] array, int leftIndex, int rightIndex, int target) {
+ while(rightIndex != 0 && target != 0) {
+ if(rightIndex <= target) {
+ if(rightIndex != 1) {
+ this.grailMultiSwap(array, leftIndex, leftIndex + rightIndex, rightIndex);
+ leftIndex += rightIndex;
+ target -= rightIndex;
}
else {
Highlights.clearMark(2);
- this.grailForwardShift(array, pos, indexB);
- indexB = 0;
+ this.grailForwardShift(array, leftIndex, target);
+ target = 0;
}
}
else {
- if(indexB != 1) {
- this.grailMultiSwap(array, pos + (indexA - indexB), pos + indexA, indexB);
- indexA -= indexB;
+ if(target != 1) {
+ this.grailMultiSwap(array, leftIndex + (rightIndex - target), leftIndex + rightIndex, target);
+ rightIndex -= target;
}
else {
Highlights.clearMark(2);
- this.grailBackwardShift(array, pos, indexA);
- indexA = 0;
+ this.grailBackwardShift(array, leftIndex, rightIndex);
+ rightIndex = 0;
}
}
}
@@ -204,10 +204,12 @@ private int grailBinSearch(int[] arr, int pos, int len, int keyPos, boolean isLe
right = mid;
} else left = mid;
}
+ Highlights.markArray(1, pos + mid);
}
return right;
}
+ //TODO: *Somehow* make this more efficient.
// cost: 2 * len + numKeys^2 / 2
private int grailFindKeys(int[] arr, int pos, int len, int numKeys) {
int dist = 1, foundKeys = 1, firstKey = 0; // first key is always here
@@ -230,6 +232,19 @@ private int grailFindKeys(int[] arr, int pos, int len, int numKeys) {
return foundKeys;
}
+ private boolean grailCheckOddPairs(int[] arr, int pos, int len) {
+ for(int dist = 2; dist < (len - 2); dist += 2) {
+ Highlights.markArray(1, pos + dist - 1);
+ Highlights.markArray(2, pos + dist);
+ Delays.sleep(1);
+
+ if(Reads.compare(arr[pos + (dist - 1)], arr[pos + dist]) > 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
// cost: min(len1, len2)^2 + max(len1, len2)
private void grailMergeWithoutBuffer(int[] arr, int pos, int len1, int len2) {
if(len1 < len2) {
@@ -295,11 +310,11 @@ private void grailMergeBuffersLeft(int[] arr, int keysPos, int midkey, int pos,
leftOverLen = blockLen;
} else {
if(havebuf) {
- GrailState results = this.grailSmartMergeWithBuffer(arr, pos + restToProcess, leftOverLen, leftOverFrag, blockLen);
+ GrailPair results = this.grailSmartMergeWithBuffer(arr, pos + restToProcess, leftOverLen, leftOverFrag, blockLen);
leftOverLen = results.getLeftOverLen();
leftOverFrag = results.getLeftOverFrag();
} else {
- GrailState results = this.grailSmartMergeWithoutBuffer(arr, pos + restToProcess, leftOverLen, leftOverFrag, blockLen);
+ GrailPair results = this.grailSmartMergeWithoutBuffer(arr, pos + restToProcess, leftOverLen, leftOverFrag, blockLen);
leftOverLen = results.getLeftOverLen();
leftOverFrag = results.getLeftOverFrag();
}
@@ -374,8 +389,8 @@ private void grailMergeRight(int[] arr, int pos, int leftLen, int rightLen, int
}
//returns the leftover length, then the leftover fragment
- private GrailState grailSmartMergeWithoutBuffer(int[] arr, int pos, int leftOverLen, int leftOverFrag, int regBlockLen) {
- if(regBlockLen == 0) return new GrailState(leftOverLen, leftOverFrag);
+ private GrailPair grailSmartMergeWithoutBuffer(int[] arr, int pos, int leftOverLen, int leftOverFrag, int regBlockLen) {
+ if(regBlockLen == 0) return new GrailPair(leftOverLen, leftOverFrag);
int len1 = leftOverLen;
int len2 = regBlockLen;
@@ -398,7 +413,7 @@ private GrailState grailSmartMergeWithoutBuffer(int[] arr, int pos, int leftOver
len2 -= foundLen;
}
if(len2 == 0) {
- return new GrailState(len1, leftOverFrag);
+ return new GrailPair(len1, leftOverFrag);
}
do {
pos++;
@@ -406,11 +421,11 @@ private GrailState grailSmartMergeWithoutBuffer(int[] arr, int pos, int leftOver
} while(len1 != 0 && Reads.compare(arr[pos], arr[pos + len1]) - typeFrag < 0);
}
}
- return new GrailState(len2, typeFrag);
+ return new GrailPair(len2, typeFrag);
}
//returns the leftover length, then the leftover fragment
- private GrailState grailSmartMergeWithBuffer(int[] arr, int pos, int leftOverLen, int leftOverFrag, int blockLen) {
+ private GrailPair grailSmartMergeWithBuffer(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
@@ -433,14 +448,14 @@ private GrailState grailSmartMergeWithBuffer(int[] arr, int pos, int leftOverLen
length = rightEnd - right;
fragment = typeFrag;
}
- return new GrailState(length, fragment);
+ return new GrailPair(length, fragment);
}
/***** Sort With Extra Buffer *****/
//returns the leftover length, then the leftover fragment
- private GrailState grailSmartMergeWithXBuf(int[] arr, int pos, int leftOverLen, int leftOverFrag, int blockLen) {
+ 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
@@ -465,7 +480,7 @@ private GrailState grailSmartMergeWithXBuf(int[] arr, int pos, int leftOverLen,
length = rightEnd - right;
fragment = typeFrag;
}
- return new GrailState(length, fragment);
+ return new GrailPair(length, fragment);
}
// arr[dist..-1] - free, arr[0, leftEnd - 1] ++ arr[leftEnd, leftEnd + rightEnd - 1]
@@ -525,7 +540,7 @@ private void grailMergeBuffersLeftWithXBuf(int[] arr, int keysPos, int midkey, i
restToProcess = processIndex;
leftOverLen = regBlockLen;
} else {
- GrailState results = this.grailSmartMergeWithXBuf(arr, pos + restToProcess, leftOverLen, leftOverFrag, regBlockLen);
+ GrailPair results = this.grailSmartMergeWithXBuf(arr, pos + restToProcess, leftOverLen, leftOverFrag, regBlockLen);
leftOverLen = results.getLeftOverLen();
leftOverFrag = results.getLeftOverFrag();
}
@@ -555,7 +570,7 @@ private void grailMergeBuffersLeftWithXBuf(int[] arr, int keysPos, int midkey, i
// output: first buildLen elements are buffer, blocks 2 * buildLen and last subblock sorted
// if array is already sorted, return false
- private void grailBuildBlocks(int[] arr, int pos, int len, int buildLen,
+ private boolean grailBuildBlocks(int[] arr, int pos, int len, int buildLen,
int[] extbuf, int bufferPos, int extBufLen) {
int buildBuf = buildLen < extBufLen ? buildLen : extBufLen;
@@ -593,15 +608,34 @@ private void grailBuildBlocks(int[] arr, int pos, int len, int buildLen,
Writes.arraycopy(extbuf, bufferPos, arr, pos + len, buildBuf, 1, true, false);
}
else {
+ boolean evenPairsSorted = true;
+
for(int dist = 1; dist < len; dist += 2) {
extraDist = 0;
- if(Reads.compare(arr[pos + (dist - 1)], arr[pos + dist]) > 0) extraDist = 1;
+ if(Reads.compare(arr[pos + (dist - 1)], arr[pos + dist]) > 0) {
+ evenPairsSorted = false;
+ extraDist = 1;
+ }
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) this.grailSwap(arr, pos + (len - 1), pos + (len - 1) - 2);
pos -= 2;
part = 2;
+
+ if(evenPairsSorted) {
+ pos += 2;
+ if(this.grailCheckOddPairs(arr, pos, len)) {
+ while((len - 1) - 2 >= 0) {
+ this.grailSwap(arr, pos + (len - 1), pos + ((len--) - 1) - 2);
+ }
+ if(Reads.compare(arr[pos], arr[pos + 1]) > 0) {
+ this.grailSwap(arr, pos, pos + 1);
+ }
+ return false;
+ }
+ pos -= 2;
+ }
}
for(; part < buildLen; part *= 2) {
@@ -629,6 +663,8 @@ private void grailBuildBlocks(int[] arr, int pos, int len, int buildLen,
leftOverPos -= 2 * buildLen;
this.grailMergeRight(arr, pos + leftOverPos, buildLen, buildLen, buildLen);
}
+
+ return true;
}
// keys are on the left of arr. Blocks of length buildLen combined. We'll combine them in pairs
@@ -826,14 +862,14 @@ protected void grailCommonSort(int[] arr, int pos, int len, int[] buffer, int bu
boolean continueSort = true;
if(bufferEnabled) {
- //continueSort =
- this.grailBuildBlocks(arr, pos + dist, len - dist, buildLen, buffer, bufferPos, bufferLen);
+ continueSort = this.grailBuildBlocks(arr, pos + dist, len - dist, buildLen, buffer, bufferPos, bufferLen);
}
else {
- //continueSort =
- this.grailBuildBlocks(arr, pos + dist, len - dist, buildLen, null, bufferPos, 0);
+ continueSort = this.grailBuildBlocks(arr, pos + dist, len - dist, buildLen, null, bufferPos, 0);
}
-
+
+ System.out.println(continueSort);
+
if(continueSort) {
boolean mergeForward = true;
@@ -869,9 +905,11 @@ protected void grailCommonSort(int[] arr, int pos, int len, int[] buffer, int bu
Highlights.clearMark(2);
}
- }
- this.grailInsertSort(arr, pos, dist);
+ this.grailInsertSort(arr, pos, dist);
+ }
+
+ //TODO: O(n) best-case DOES NOT WORK for key counts LESS THAN (2 * sqrt(n))
this.grailMergeWithoutBuffer(arr, pos, dist, len - dist);
/*
diff --git a/src/templates/JEnhancedOptionPane.java b/src/templates/JEnhancedOptionPane.java
new file mode 100644
index 00000000..1fddea90
--- /dev/null
+++ b/src/templates/JEnhancedOptionPane.java
@@ -0,0 +1,32 @@
+package templates;
+
+import java.awt.HeadlessException;
+
+import javax.swing.JDialog;
+import javax.swing.JOptionPane;
+import javax.swing.UIManager;
+
+//Many thanks to Freek de Bruijn on StackOverflow for providing a custom JOptionPane.
+//https://stackoverflow.com/questions/14407804/how-to-change-the-default-text-of-buttons-in-joptionpane-showinputdialog?noredirect=1&lq=1
+final public class JEnhancedOptionPane extends JOptionPane {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public static String showInputDialog(final Object message, final Object[] options) throws HeadlessException {
+ final JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE,
+ OK_CANCEL_OPTION, null,
+ options, null);
+ pane.setWantsInput(true);
+ pane.setComponentOrientation((getRootFrame()).getComponentOrientation());
+ pane.setMessageType(QUESTION_MESSAGE);
+ pane.selectInitialValue();
+ final String title = UIManager.getString("OptionPane.inputDialogTitle", null);
+ final JDialog dialog = pane.createDialog(null, title);
+ dialog.setVisible(true);
+ dialog.dispose();
+ final Object value = pane.getInputValue();
+ return (value == UNINITIALIZED_VALUE) ? null : (String) value;
+ }
+}
\ No newline at end of file
diff --git a/src/templates/JErrorPane.java b/src/templates/JErrorPane.java
new file mode 100644
index 00000000..5d76f4cd
--- /dev/null
+++ b/src/templates/JErrorPane.java
@@ -0,0 +1,32 @@
+package templates;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javax.swing.JOptionPane;
+import javax.swing.JTextArea;
+
+final public class JErrorPane extends JOptionPane {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public volatile static boolean errorMessageActive = false;
+
+ public static void invokeErrorMessage(Exception e) {
+ errorMessageActive = true;
+
+ StringWriter exceptionString = new StringWriter();
+ e.printStackTrace(new PrintWriter(exceptionString));
+ String printException = exceptionString.toString();
+
+ JTextArea error = new JTextArea();
+ error.setText(printException);
+ error.setCaretPosition(0);
+ error.setEditable(false);
+
+ JOptionPane.showMessageDialog(null, error, "Error", JOptionPane.ERROR_MESSAGE);
+ errorMessageActive = false;
+ }
+}
\ No newline at end of file
diff --git a/src/templates/MergeSorting.java b/src/templates/MergeSorting.java
index 16bd95f4..38679195 100644
--- a/src/templates/MergeSorting.java
+++ b/src/templates/MergeSorting.java
@@ -49,7 +49,7 @@ private void merge(int[] array, int start, int mid, int end, boolean binary) {
return;
}
else if(end - start == 32 && binary) {
- binaryInserter.customBinaryInsert(array, start, end, 0.25);
+ binaryInserter.customBinaryInsert(array, start, end, 0.333);
}
else {
int[] tmp = new int[end - start];
@@ -60,30 +60,28 @@ else if(end - start == 32 && binary) {
for(int nxt = 0; nxt < tmp.length; nxt++){
if(low >= mid && high >= end) break;
+ Highlights.markArray(1, low);
+ Highlights.markArray(2, high);
+
if(low < mid && high >= end){
- Writes.write(tmp, nxt, array[low++], 0, false, true);
+ Highlights.clearMark(2);
+ Writes.write(tmp, nxt, array[low++], 1, false, true);
}
else if(low >= mid && high < end){
- Writes.write(tmp, nxt, array[high++], 0, false, true);
+ Highlights.clearMark(1);
+ Writes.write(tmp, nxt, array[high++], 1, false, true);
}
- else if(Reads.compare(array[low], array[high]) == -1){
- Writes.write(tmp, nxt, array[low++], 0, false, true);
+ else if(Reads.compare(array[low], array[high]) <= 0){
+ Writes.write(tmp, nxt, array[low++], 1, false, true);
}
else{
- Writes.write(tmp, nxt, array[high++], 0, false, true);
+ Writes.write(tmp, nxt, array[high++], 1, false, true);
}
-
- Highlights.markArray(1, low);
- Highlights.markArray(2, high);
-
- Delays.sleep(1);
}
-
Highlights.clearMark(2);
for(int i = 0; i < tmp.length; i++){
- Writes.write(array, start + i, tmp[i], 1, false, false);
- Highlights.markArray(1, start + i);
+ Writes.write(array, start + i, tmp[i], 1, true, false);
}
}
}
@@ -92,7 +90,7 @@ protected void mergeSort(int[] array, int length, boolean binary) {
binaryInserter = new BinaryInsertionSort(this.Delays, this.Highlights, this.Reads, this.Writes);
if(length < 32 && binary) {
- binaryInserter.customBinaryInsert(array, 0, length, 0.25);
+ binaryInserter.customBinaryInsert(array, 0, length, 0.333);
return;
}
diff --git a/src/templates/MultipleSortThread.java b/src/templates/MultipleSortThread.java
index 83d03761..141ac12c 100644
--- a/src/templates/MultipleSortThread.java
+++ b/src/templates/MultipleSortThread.java
@@ -22,6 +22,8 @@ public abstract class MultipleSortThread {
protected volatile int sortCount;
protected volatile int sortNumber;
+ protected volatile int categoryCount;
+
public MultipleSortThread(ArrayVisualizer ArrayVisualizer) {
this.ArrayVisualizer = ArrayVisualizer;
this.ArrayManager = ArrayVisualizer.getArrayManager();
@@ -33,8 +35,13 @@ public MultipleSortThread(ArrayVisualizer ArrayVisualizer) {
this.Timer = ArrayVisualizer.getTimer();
}
- protected synchronized void RunIndividualSort(Sort sort, int bucketCount, int[] array, double speed) throws InterruptedException {
+ protected synchronized void runIndividualSort(Sort sort, int bucketCount, int[] array, int length, double speed) throws InterruptedException {
Delays.setSleepRatio(2.5);
+
+ if(length != ArrayVisualizer.getCurrentLength()) {
+ ArrayVisualizer.setCurrentLength(length);
+ }
+
ArrayManager.refreshArray(array, ArrayVisualizer.getCurrentLength(), this.ArrayVisualizer);
ArrayVisualizer.setHeading(sort.getRunAllID() + " (Sort " + this.sortNumber + " of " + this.sortCount + ")");
@@ -49,4 +56,23 @@ protected synchronized void RunIndividualSort(Sort sort, int bucketCount, int[]
this.sortNumber++;
}
+
+ protected abstract void executeSortList(int[] array) throws Exception;
+ protected abstract void runThread(int[] array, int current, int total, boolean runAllActive) throws Exception;
+
+ public synchronized void reportCategorySorts(int[] array) throws Exception {
+ this.runThread(array, 0, 0, false);
+ }
+
+ public synchronized void reportAllSorts(int[] array, int current, int total) throws Exception {
+ this.runThread(array, current, total, true);
+ }
+
+ public int getSortCount() {
+ return this.sortCount;
+ }
+
+ public int getCategoryCount() {
+ return this.categoryCount;
+ }
}
\ No newline at end of file
diff --git a/src/templates/ShellSorting.java b/src/templates/ShellSorting.java
index b6748f6c..a253620b 100644
--- a/src/templates/ShellSorting.java
+++ b/src/templates/ShellSorting.java
@@ -53,18 +53,22 @@ protected void shellSort(ArrayVisualizer ArrayVisualizer, int[] array, int lengt
Highlights.markArray(1, j);
Highlights.markArray(2, j - h);
-
- Delays.sleep(0.2);
while (j >= h && Reads.compare(array[j - h], v) == 1)
{
+ Writes.write(array, j, array[j - h], 1, false, false);
+ j -= h;
+
Highlights.markArray(1, j);
- Highlights.markArray(2, j - h);
- Writes.write(array, j, array[j - h], 0.5, false, false);
- j -= h;
+ if(j - h >= 0) {
+ Highlights.markArray(2, j - h);
+ }
+ else {
+ Highlights.clearMark(2);
+ }
}
- Writes.write(array, j, v, 0.5, true, false);
+ Writes.write(array, j, v, 1, true, false);
}
}
}
@@ -78,18 +82,22 @@ protected void shellSort(ArrayVisualizer ArrayVisualizer, int[] array, int lengt
Highlights.markArray(1, j);
Highlights.markArray(2, j - h);
-
- Delays.sleep(0.2);
while (j >= h && Reads.compare(array[j - h], v) == 1)
{
+ Writes.write(array, j, array[j - h], 1, false, false);
+ j -= h;
+
Highlights.markArray(1, j);
- Highlights.markArray(2, j - h);
- Writes.write(array, j, array[j - h], 0.5, false, false);
- j -= h;
+ if(j - h >= 0) {
+ Highlights.markArray(2, j - h);
+ }
+ else {
+ Highlights.clearMark(2);
+ }
}
- Writes.write(array, j, v, 0.5, true, false);
+ Writes.write(array, j, v, 1, true, false);
}
}
}
diff --git a/src/templates/TimSorting.java b/src/templates/TimSorting.java
index 6c580de9..c68a98cf 100644
--- a/src/templates/TimSorting.java
+++ b/src/templates/TimSorting.java
@@ -1,5 +1,8 @@
package templates;
+import javax.swing.text.Highlighter.Highlight;
+
+import utils.Delays;
import utils.Highlights;
import utils.Reads;
import utils.Writes;
@@ -57,6 +60,7 @@
*/
final public class TimSorting {
+ private Delays Delays;
private Highlights Highlights;
private Reads Reads;
private Writes Writes;
@@ -133,10 +137,11 @@ public static int getMinRun() {
*
* @param a the array to be sorted
*/
- public TimSorting(int[] a, int currentLen, Highlights markOps, Reads readOps, Writes writeOps) {
+ public TimSorting(int[] a, int currentLen, Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps) {
this.a = a;
this.len = currentLen;
+ this.Delays = delayOps;
this.Highlights = markOps;
this.Reads = readOps;
this.Writes = writeOps;
@@ -309,12 +314,18 @@ private static int countRunAndMakeAscending(TimSorting ts, int[] a, int lo, int
// Find end of run, and reverse range if descending
if (ts.Reads.compare(a[runHi++], a[lo]) < 0) { // Descending
- while(runHi < hi && ts.Reads.compare(a[runHi], a[runHi - 1]) < 0)
+ while(runHi < hi && ts.Reads.compare(a[runHi], a[runHi - 1]) < 0) {
+ ts.Highlights.markArray(1, runHi);
+ ts.Delays.sleep(1);
runHi++;
+ }
reverseRange(ts, a, lo, runHi);
} else { // Ascending
- while (runHi < hi && ts.Reads.compare(a[runHi], a[runHi - 1]) >= 0)
+ while (runHi < hi && ts.Reads.compare(a[runHi], a[runHi - 1]) >= 0) {
+ ts.Highlights.markArray(1, runHi);
+ ts.Delays.sleep(1);
runHi++;
+ }
}
return runHi - lo;
}
@@ -420,6 +431,9 @@ private void mergeForceCollapse() {
* @param i stack index of the first of the two runs to merge
*/
private void mergeAt(int i) {
+ this.Highlights.clearMark(1);
+ this.Highlights.clearMark(2);
+
int base1 = this.runBase[i];
int len1 = this.runLen[i];
int base2 = this.runBase[i + 1];
@@ -460,6 +474,9 @@ private void mergeAt(int i) {
mergeLo(this, base1, len1, base2, len2);
else
mergeHi(this, base1, len1, base2, len2);
+
+ this.Highlights.clearMark(1);
+ this.Highlights.clearMark(2);
}
/**
@@ -484,14 +501,24 @@ private static int gallopLeft(TimSorting ts, int key, int[] a, int base, int len
int lastOfs = 0;
int ofs = 1;
+ ts.Highlights.markArray(3, base + hint);
+ ts.Delays.sleep(1);
+
if (ts.Reads.compare(key, a[base + hint]) > 0) {
// Gallop right until a[base+hint+lastOfs] < key <= a[base+hint+ofs]
int maxOfs = len - hint;
- while (ofs < maxOfs && ts.Reads.compare(key, a[base + hint + ofs]) > 0) {
+
+ ts.Highlights.markArray(3, base + hint + ofs);
+ ts.Delays.sleep(1);
+
+ while (ofs < maxOfs && ts.Reads.compare(key, a[base + hint + ofs]) > 0) {
lastOfs = ofs;
ofs = (ofs * 2) + 1;
if (ofs <= 0) // int overflow
ofs = maxOfs;
+
+ ts.Highlights.markArray(3, base + hint + ofs);
+ ts.Delays.sleep(1);
}
if (ofs > maxOfs)
ofs = maxOfs;
@@ -502,11 +529,18 @@ private static int gallopLeft(TimSorting ts, int key, int[] a, int base, int len
} else { // key <= a[base + hint]
// Gallop left until a[base+hint-ofs] < key <= a[base+hint-lastOfs]
final int maxOfs = hint + 1;
+
+ ts.Highlights.markArray(3, base + hint - ofs);
+ ts.Delays.sleep(1);
+
while (ofs < maxOfs && ts.Reads.compare(key, a[base + hint - ofs]) <= 0) {
lastOfs = ofs;
ofs = (ofs * 2) + 1;
if (ofs <= 0) // int overflow
ofs = maxOfs;
+
+ ts.Highlights.markArray(3, base + hint - ofs);
+ ts.Delays.sleep(1);
}
if (ofs > maxOfs)
ofs = maxOfs;
@@ -526,11 +560,15 @@ private static int gallopLeft(TimSorting ts, int key, int[] a, int base, int len
while (lastOfs < ofs) {
int m = lastOfs + ((ofs - lastOfs) >>> 1);
+ ts.Highlights.markArray(3, base + m);
+ ts.Delays.sleep(1);
+
if (ts.Reads.compare(key, a[base + m]) > 0)
lastOfs = m + 1; // a[base + m] < key
else
ofs = m; // key <= a[base + m]
}
+ ts.Highlights.clearMark(3);
return ofs;
}
/**
@@ -549,14 +587,25 @@ private static int gallopLeft(TimSorting ts, int key, int[] a, int base, int len
private static int gallopRight(TimSorting ts, int key, int[] a, int base, int len, int hint) {
int ofs = 1;
int lastOfs = 0;
+
+ ts.Highlights.markArray(3, base + hint);
+ ts.Delays.sleep(1);
+
if (ts.Reads.compare(key, a[base + hint]) < 0) {
// Gallop left until a[b+hint - ofs] <= key < a[b+hint - lastOfs]
int maxOfs = hint + 1;
+
+ ts.Highlights.markArray(3, base + hint - ofs);
+ ts.Delays.sleep(1);
+
while (ofs < maxOfs && ts.Reads.compare(key, a[base + hint - ofs]) < 0) {
lastOfs = ofs;
ofs = (ofs * 2) + 1;
if (ofs <= 0) // int overflow
ofs = maxOfs;
+
+ ts.Highlights.markArray(3, base + hint - ofs);
+ ts.Delays.sleep(1);
}
if (ofs > maxOfs)
ofs = maxOfs;
@@ -568,11 +617,18 @@ private static int gallopRight(TimSorting ts, int key, int[] a, int base, int le
} else { // a[b + hint] <= key
// Gallop right until a[b+hint + lastOfs] <= key < a[b+hint + ofs]
int maxOfs = len - hint;
+
+ ts.Highlights.markArray(3, base + hint + ofs);
+ ts.Delays.sleep(1);
+
while (ofs < maxOfs && ts.Reads.compare(key, a[base + hint + ofs]) >= 0) {
lastOfs = ofs;
ofs = (ofs * 2) + 1;
if (ofs <= 0) // int overflow
ofs = maxOfs;
+
+ ts.Highlights.markArray(3, base + hint + ofs);
+ ts.Delays.sleep(1);
}
if (ofs > maxOfs)
ofs = maxOfs;
@@ -591,11 +647,15 @@ private static int gallopRight(TimSorting ts, int key, int[] a, int base, int le
while (lastOfs < ofs) {
int m = lastOfs + ((ofs - lastOfs) >>> 1);
+ ts.Highlights.markArray(3, base + m);
+ ts.Delays.sleep(1);
+
if (ts.Reads.compare(key, a[base + m]) < 0)
ofs = m; // key < a[b + m]
else
lastOfs = m + 1; // a[b + m] <= key
}
+ ts.Highlights.clearMark(3);
return ofs;
}
/**
@@ -618,7 +678,7 @@ private void mergeLo(TimSorting ts, int base1, int len1, int base2, int len2) {
// Copy first run into temp array
int[] a = this.a; // For performance
int[] tmp = ensureCapacity(len1);
- ts.Writes.arraycopy(a, base1, tmp, 0, len1, 0.875, true, true);
+ ts.Writes.arraycopy(a, base1, tmp, 0, len1, 1, true, true);
int cursor1 = 0; // Indexes into tmp array
int cursor2 = base2; // Indexes int a
@@ -629,11 +689,11 @@ private void mergeLo(TimSorting ts, int base1, int len1, int base2, int len2) {
this.Highlights.markArray(1, dest);
this.Highlights.markArray(2, cursor2);
if (--len2 == 0) {
- ts.Writes.arraycopy(tmp, cursor1, a, dest, len1, 0.875, true, false);
+ ts.Writes.arraycopy(tmp, cursor1, a, dest, len1, 1, true, false);
return;
}
if (len1 == 1) {
- ts.Writes.arraycopy(a, cursor2, a, dest, len2, 0.875, true, false);
+ ts.Writes.arraycopy(a, cursor2, a, dest, len2, 1, true, false);
this.Writes.write(a, dest + len2, tmp[cursor1], 1, false, false); // Last elt of run 1 to end of merge
this.Highlights.markArray(1, dest + len2);
return;
@@ -675,7 +735,7 @@ private void mergeLo(TimSorting ts, int base1, int len1, int base2, int len2) {
do {
count1 = gallopRight(ts, a[cursor2], tmp, cursor1, len1, 0);
if (count1 != 0) {
- ts.Writes.arraycopy(tmp, cursor1, a, dest, count1, 0.875, true, false);
+ ts.Writes.arraycopy(tmp, cursor1, a, dest, count1, 1, true, false);
dest += count1;
cursor1 += count1;
len1 -= count1;
@@ -690,7 +750,7 @@ private void mergeLo(TimSorting ts, int base1, int len1, int base2, int len2) {
count2 = gallopLeft(ts, tmp[cursor1], a, cursor2, len2, 0);
if (count2 != 0) {
- ts.Writes.arraycopy(a, cursor2, a, dest, count2, 0.875, true, false);
+ ts.Writes.arraycopy(a, cursor2, a, dest, count2, 1, true, false);
dest += count2;
cursor2 += count2;
len2 -= count2;
@@ -710,16 +770,15 @@ private void mergeLo(TimSorting ts, int base1, int len1, int base2, int len2) {
this.minGallop = minGallop < 1 ? 1 : minGallop; // Write back to field
if (len1 == 1) {
- ts.Writes.arraycopy(a, cursor2, a, dest, len2, 0.875, true, false);
+ ts.Writes.arraycopy(a, cursor2, a, dest, len2, 1, true, false);
this.Writes.write(a, dest + len2, tmp[cursor1], 1, false, false); // Last elt of run 1 to end of merge
this.Highlights.markArray(1, dest + len2);
} else if (len1 == 0) {
throw new IllegalArgumentException(
"Comparison method violates its general contract!");
} else {
- ts.Writes.arraycopy(tmp, cursor1, a, dest, len1, 0.875, true, false);
+ ts.Writes.arraycopy(tmp, cursor1, a, dest, len1, 1, true, false);
}
- this.Highlights.clearMark(2);
}
/**
@@ -737,7 +796,7 @@ private void mergeHi(TimSorting ts, int base1, int len1, int base2, int len2) {
// Copy second run into temp array
int[] a = this.a; // For performance
int[] tmp = ensureCapacity(len2);
- ts.Writes.arraycopy(a, base2, tmp, 0, len2, 0.875, true, true);
+ ts.Writes.arraycopy(a, base2, tmp, 0, len2, 1, true, true);
int cursor1 = base1 + len1 - 1; // Indexes into a
int cursor2 = len2 - 1; // Indexes into tmp array
@@ -748,13 +807,13 @@ private void mergeHi(TimSorting ts, int base1, int len1, int base2, int len2) {
this.Highlights.markArray(1, dest);
this.Highlights.markArray(2, cursor1);
if (--len1 == 0) {
- ts.Writes.reversearraycopy(tmp, 0, a, dest - (len2 - 1), len2, 0.875, true, false);
+ ts.Writes.reversearraycopy(tmp, 0, a, dest - (len2 - 1), len2, 1, true, false);
return;
}
if (len2 == 1) {
dest -= len1;
cursor1 -= len1;
- ts.Writes.reversearraycopy(a, cursor1 + 1, a, dest + 1, len1, 0.875, true, false);
+ ts.Writes.reversearraycopy(a, cursor1 + 1, a, dest + 1, len1, 1, true, false);
this.Writes.write(a, dest, tmp[cursor2], 1, false, false);
this.Highlights.markArray(1, dest);
return;
@@ -800,7 +859,7 @@ private void mergeHi(TimSorting ts, int base1, int len1, int base2, int len2) {
dest -= count1;
cursor1 -= count1;
len1 -= count1;
- ts.Writes.reversearraycopy(a, cursor1 + 1, a, dest + 1, count1, 0.875, true, false);
+ ts.Writes.reversearraycopy(a, cursor1 + 1, a, dest + 1, count1, 1, true, false);
if (len1 == 0)
break outer;
}
@@ -814,7 +873,7 @@ private void mergeHi(TimSorting ts, int base1, int len1, int base2, int len2) {
dest -= count2;
cursor2 -= count2;
len2 -= count2;
- ts.Writes.reversearraycopy(tmp, cursor2 + 1, a, dest + 1, count2, 0.875, true, false);
+ ts.Writes.reversearraycopy(tmp, cursor2 + 1, a, dest + 1, count2, 1, true, false);
if (len2 <= 1) // len2 == 1 || len2 == 0
break outer;
}
@@ -834,17 +893,15 @@ private void mergeHi(TimSorting ts, int base1, int len1, int base2, int len2) {
if (len2 == 1) {
dest -= len1;
cursor1 -= len1;
- ts.Writes.reversearraycopy(a, cursor1 + 1, a, dest + 1, len1, 0.875, true, false);
+ ts.Writes.reversearraycopy(a, cursor1 + 1, a, dest + 1, len1, 1, true, false);
this.Writes.write(a, dest, tmp[cursor2], 1, false, false); // Move first elt of run2 to front of merge
this.Highlights.markArray(1, dest);
} else if (len2 == 0) {
throw new IllegalArgumentException(
"Comparison method violates its general contract!");
} else {
- ts.Writes.reversearraycopy(tmp, 0, a, dest - (len2 - 1), len2, 0.875, true, false);
+ ts.Writes.reversearraycopy(tmp, 0, a, dest - (len2 - 1), len2, 1, true, false);
}
-
- this.Highlights.clearMark(2);
}
/**
* Ensures that the external array tmp has at least the specified
diff --git a/src/templates/Visual.java b/src/templates/Visual.java
new file mode 100644
index 00000000..a8e35fd6
--- /dev/null
+++ b/src/templates/Visual.java
@@ -0,0 +1,128 @@
+package templates;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+
+import main.ArrayVisualizer;
+import utils.Highlights;
+import utils.Renderer;
+
+public abstract class Visual {
+ protected Graphics2D mainRender;
+ protected Graphics2D extraRender;
+
+ public Visual(ArrayVisualizer ArrayVisualizer) {
+ this.updateRender(ArrayVisualizer);
+ }
+
+ public void updateRender(ArrayVisualizer ArrayVisualizer) {
+ this.mainRender = ArrayVisualizer.getMainRender();
+ this.extraRender = ArrayVisualizer.getExtraRender();
+ }
+
+ public static Color getIntColor(int i, int length) {
+ return Color.getHSBColor(((float) i / length), 1.0F, 0.8F);
+ }
+
+ public static void markBar(Graphics2D bar, boolean color, boolean rainbow, boolean analysis) {
+ if(color || rainbow) {
+ /*
+ if(analysis) bar.setColor(Color.WHITE);
+ else bar.setColor(Color.BLACK);
+ */
+ if(analysis) bar.setColor(Color.LIGHT_GRAY);
+ else bar.setColor(Color.WHITE);
+ }
+ else if(analysis) bar.setColor(Color.BLUE);
+ else bar.setColor(Color.RED);
+ }
+ private static void markBarFancy(Graphics2D bar, boolean color, boolean rainbow) {
+ if(!color && !rainbow) bar.setColor(Color.RED);
+ else bar.setColor(Color.BLACK);
+ }
+
+ public static void lineMark(Graphics2D line, double width, boolean color, boolean analysis) {
+ line.setStroke(new BasicStroke((float) (9f * (width / 1280f))));
+ if(color) line.setColor(Color.BLACK);
+ else if(analysis) line.setColor(Color.BLUE);
+ else line.setColor(Color.RED);
+ }
+ //TODO: Change name to markLineFancy
+ public static void lineFancy(Graphics2D line, double width) {
+ line.setColor(Color.GREEN);
+ line.setStroke(new BasicStroke((float) (9f * (width / 1280f))));
+ }
+ //TODO: Change name to clearLine
+ public static void lineClear(Graphics2D line, boolean color, int[] array, int i, int length, double width) {
+ if(color) line.setColor(getIntColor(array[i], length));
+ else line.setColor(Color.WHITE);
+ line.setStroke(new BasicStroke((float) (3f * (width / 1280f))));
+ }
+
+ public static void setRectColor(Graphics2D rect, boolean color, boolean analysis) {
+ if(color) rect.setColor(Color.WHITE);
+ else if(analysis) rect.setColor(Color.BLUE);
+ else rect.setColor(Color.RED);
+ }
+
+ @SuppressWarnings("fallthrough")
+ //The longer the array length, the more bars marked. Makes the visual easier to see when bars are thinner.
+ public static void colorMarkedBars(int logOfLen, int index, Highlights Highlights, Graphics2D mainRender, boolean colorEnabled, boolean rainbowEnabled, boolean analysis) {
+ switch(logOfLen) {
+ case 14: if(Highlights.containsPosition(index - 10)
+ || Highlights.containsPosition(index - 9)
+ || Highlights.containsPosition(index - 8)) markBar(mainRender, colorEnabled, rainbowEnabled, analysis);
+ case 13: if(Highlights.containsPosition(index - 7)
+ || Highlights.containsPosition(index - 6)
+ || Highlights.containsPosition(index - 5)) markBar(mainRender, colorEnabled, rainbowEnabled, analysis);
+ case 12: if(Highlights.containsPosition(index - 4)
+ || Highlights.containsPosition(index - 3)) markBar(mainRender, colorEnabled, rainbowEnabled, analysis);
+ case 11: if(Highlights.containsPosition(index - 2)) markBar(mainRender, colorEnabled, rainbowEnabled, analysis);
+ case 10: if(Highlights.containsPosition(index - 1)) markBar(mainRender, colorEnabled, rainbowEnabled, analysis);
+ default: if(Highlights.containsPosition(index)) markBar(mainRender, colorEnabled, rainbowEnabled, analysis);
+ }
+ }
+
+ @SuppressWarnings("fallthrough")
+ public static void drawFancyFinish(int logOfLen, int index, int position, Graphics2D mainRender, boolean colorEnabled, boolean rainbowEnabled) {
+ switch(logOfLen) {
+ case 14: if(index == position - 13) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
+ case 13: if(index == position - 12) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
+ case 12: if(index == position - 11) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
+ case 11: if(index == position - 10) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
+ case 10: if(index == position - 9) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
+ case 9: if(index == position - 8) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
+ case 8: if(index == position - 7) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
+ case 7: if(index == position - 6) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
+ case 6: if(index == position - 5) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
+ case 5: if(index == position - 4) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
+ case 4: if(index == position - 3) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
+ case 3: if(index == position - 2) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
+ case 2: if(index == position - 1) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
+ default: if(index == position) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
+ }
+ }
+
+ @SuppressWarnings("fallthrough")
+ public static void drawFancyFinishLine(int logOfLen, int index, int position, Graphics2D mainRender, double width, boolean colorEnabled) {
+ switch(logOfLen) {
+ case 14: if(index == position - 13) lineMark(mainRender, width, colorEnabled, false);
+ case 13: if(index == position - 12) lineMark(mainRender, width, colorEnabled, false);
+ case 12: if(index == position - 11) lineMark(mainRender, width, colorEnabled, false);
+ case 11: if(index == position - 10) lineMark(mainRender, width, colorEnabled, false);
+ case 10: if(index == position - 9) lineMark(mainRender, width, colorEnabled, false);
+ case 9: if(index == position - 8) lineMark(mainRender, width, colorEnabled, false);
+ case 8: if(index == position - 7) lineMark(mainRender, width, colorEnabled, false);
+ case 7: if(index == position - 6) lineMark(mainRender, width, colorEnabled, false);
+ case 6: if(index == position - 5) lineMark(mainRender, width, colorEnabled, false);
+ case 5: if(index == position - 4) lineMark(mainRender, width, colorEnabled, false);
+ case 4: if(index == position - 3) lineMark(mainRender, width, colorEnabled, false);
+ case 3: if(index == position - 2) lineMark(mainRender, width, colorEnabled, false);
+ case 2: if(index == position - 1) lineMark(mainRender, width, colorEnabled, false);
+ default: if(index == position) lineMark(mainRender, width, colorEnabled, false);
+ }
+ }
+
+ public abstract void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights);
+}
\ No newline at end of file
diff --git a/src/templates/WikiSorting.java b/src/templates/WikiSorting.java
index 5fb9017a..3cedaf41 100644
--- a/src/templates/WikiSorting.java
+++ b/src/templates/WikiSorting.java
@@ -1,6 +1,7 @@
package templates;
import sorts.InsertionSort;
+import utils.Delays;
import utils.Highlights;
import utils.Reads;
import utils.Writes;
@@ -147,6 +148,8 @@ final public class WikiSorting {
// just keep in mind that making it too small ruins the point (nothing will fit into it),
// and making it too large also ruins the point (so much for "low memory"!)
private InsertionSort InsertSort;
+
+ private Delays Delays;
private Highlights Highlights;
private Reads Reads;
private Writes Writes;
@@ -167,8 +170,10 @@ final public class WikiSorting {
// 0 – if the system simply cannot allocate any extra memory whatsoever, no memory works just fine
- public WikiSorting(InsertionSort insertionSort, Highlights markOps, Reads readOps, Writes writeOps, int cacheChoice) {
+ public WikiSorting(InsertionSort insertionSort, Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps, int cacheChoice) {
this.InsertSort = insertionSort;
+
+ this.Delays = delayOps;
this.Highlights = markOps;
this.Reads = readOps;
this.Writes = writeOps;
@@ -261,7 +266,7 @@ int FindLastBackward(int[] array, int value, Range range, int unique) {
// n^2 sorting algorithm used to sort tiny chunks of the full array
void InsertionSort(int[] array, Range range) {
- InsertSort.customInsertSort(array, range.start, range.end, 0.25, false);
+ InsertSort.customInsertSort(array, range.start, range.end, 0.5, false);
}
// reverse a range of values within the array
@@ -368,6 +373,8 @@ void MergeExternal(int[] array, Range A, Range B) {
if (B.length() > 0 && A.length() > 0) {
while (true) {
+ Highlights.markArray(3, A_index);
+ Highlights.markArray(4, B_index);
if (Reads.compare(array[B_index], cache[A_index]) >= 0) {
Writes.write(array, insert_index, cache[A_index], 1, true, false);
A_index++;
@@ -381,7 +388,9 @@ void MergeExternal(int[] array, Range A, Range B) {
}
}
}
-
+ Highlights.clearMark(3);
+ Highlights.clearMark(4);
+
// copy the remainder of A into the final array
if (cache != null) {
Writes.arraycopy(cache, A_index, array, insert_index, A_last - A_index, 1, true, false);
@@ -397,19 +406,24 @@ void MergeInternal(int[] array, Range A, Range B, Range buffer) {
if (B.length() > 0 && A.length() > 0) {
while (true) {
if (Reads.compare(array[B.start + B_count], array[buffer.start + A_count]) >= 0) {
- Writes.swap(array, A.start + insert, buffer.start + A_count, 1, true, false);
+ Highlights.markArray(3, buffer.start + A_count);
+ Delays.sleep(1);
+ Writes.swap(array, A.start + insert, buffer.start + A_count, 0, true, false);
A_count++;
insert++;
if (A_count >= A.length()) break;
} else {
- Writes.swap(array, A.start + insert, B.start + B_count, 1, true, false);
+ Highlights.markArray(3, B.start + B_count);
+ Delays.sleep(1);
+ Writes.swap(array, A.start + insert, B.start + B_count, 0, true, false);
B_count++;
insert++;
if (B_count >= B.length()) break;
}
}
}
-
+ Highlights.clearMark(3);
+
// swap the remainder of A into the final array
BlockSwap(array, buffer.start + A_count, A.start + insert, A.length() - A_count);
}
diff --git a/src/test/Tester.java b/src/test/Tester.java
index 8ce05c90..4236e1e5 100644
--- a/src/test/Tester.java
+++ b/src/test/Tester.java
@@ -52,10 +52,10 @@ public static void main(String[] args) throws Exception {
ArrayVisualizer av = new ArrayVisualizer();
- Delays = new Delays();
+ Delays = new Delays(av);
Delays.setSleepRatio(Double.MAX_VALUE);
- Highlights = new Highlights(testArr.length);
+ Highlights = new Highlights(av, testArr.length);
Highlights.toggleFancyFinishes(false);
RealTimer = new Timer();
diff --git a/src/threads/RunAllSorts.java b/src/threads/RunAllSorts.java
index 06a0ed74..aeda83f0 100644
--- a/src/threads/RunAllSorts.java
+++ b/src/threads/RunAllSorts.java
@@ -1,5 +1,11 @@
package threads;
+import java.util.ArrayList;
+
+import main.ArrayVisualizer;
+import templates.JErrorPane;
+import templates.MultipleSortThread;
+
/*
*
MIT License
@@ -27,417 +33,41 @@ of this software and associated documentation files (the "Software"), to deal
*/
final public class RunAllSorts {
- public static void runAllSorts() {
- return;
+ private ArrayVisualizer ArrayVisualizer;
+ private ArrayList allSortThreads;
+
+ public RunAllSorts(ArrayVisualizer ArrayVisualizer) {
+ this.ArrayVisualizer = ArrayVisualizer;
+ this.allSortThreads = new ArrayList<>();
+ this.allSortThreads.add(new RunExchangeSorts(ArrayVisualizer));
+ this.allSortThreads.add(new RunSelectionSorts(ArrayVisualizer));
+ this.allSortThreads.add(new RunInsertionSorts(ArrayVisualizer));
+ this.allSortThreads.add(new RunMergeSorts(ArrayVisualizer));
+ this.allSortThreads.add(new RunDistributionSorts(ArrayVisualizer));
+ this.allSortThreads.add(new RunConcurrentSorts(ArrayVisualizer));
+ this.allSortThreads.add(new RunHybridSorts(ArrayVisualizer));
+ this.allSortThreads.add(new RunMiscellaneousSorts(ArrayVisualizer));
+ this.allSortThreads.add(new RunImpracticalSorts(ArrayVisualizer));
}
- /*
- category = "Merge Sorts";
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "Merge Sort";
- SLEEPRATIO = 1.75;
- startRealTimer();
- mergeSortOOP(array, currentLen, false);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "In-Place Merge Sort";
- SLEEPRATIO = 7;
- startRealTimer();
- mergeSort(array, 0, currentLen - 1);
-
- endSort();
- Thread.sleep(1000);
-
- category = "Distribution Sorts";
-
- SLEEPRATIO = 2.5;
-
- int radix = currentLen < 256 ? currentLen / 2 : 256;
- if(radix == 1) radix = 2;
-
- refresharray();
- heading = "American Flag Sort, " + radix + " Buckets";
- startRealTimer();
- flagSort(array, currentLen, radix);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "Bead (Gravity) Sort";
- SLEEPRATIO = Integer.MAX_VALUE;
- startRealTimer();
- gravitySort(array, currentLen);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "Counting Sort";
- SLEEPRATIO = 5;
- startRealTimer();
- countingSort(array, currentLen);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "Pigeonhole Sort";
- SLEEPRATIO = 5;
- startRealTimer();
- pigeonSort(array, currentLen);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- radix = currentLen == 2 ? 2 : 4;
-
- refresharray();
- heading = "Radix LSD Sort, Base " + radix;
- SLEEPRATIO = 2;
- startRealTimer();
- radixLSDsort(array, currentLen, radix);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
- SOUNDMUL = 0.01;
-
- radix = currentLen < 16 ? currentLen / 2 : 16;
- if(radix == 1) radix = 2;
-
- refresharray();
- heading = "In-Place Radix LSD Sort, Base " + radix;
- SLEEPRATIO = 2;
- startRealTimer();
- inPlaceRadixLSDSort(array, currentLen, radix);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
- SOUNDMUL = storeVol;
-
- radix = currentLen < 8 ? currentLen / 2 : 8;
- if(radix == 1) radix = 2;
-
- refresharray();
- heading = "Radix MSD Sort, Base " + radix;
- SLEEPRATIO = 1.75;
- startRealTimer();
- radixMSDSort(array, currentLen, radix);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "Flash Sort";
- SLEEPRATIO = 1.5;
- startRealTimer();
- flashSort(array, currentLen);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "Shatter Sort";
- SLEEPRATIO = 1;
- startRealTimer();
- shatterSort(array, currentLen, 64);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "Simple Shatter Sort";
- SLEEPRATIO = 1.5;
- startRealTimer();
- simpleShatterSort(array, currentLen, 256, 4);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "Time Sort (Mul 4)";
- SLEEPRATIO = 1.5;
- startRealTimer();
- timeSort(array, currentLen, 4);
-
- endSort();
- Thread.sleep(1000);
-
- category = "Concurrent Sorts";
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "Batcher's Bitonic Sort";
- SLEEPRATIO = 4.5;
- startRealTimer();
- bitonicSort(array, 0, currentLen, true);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "Batcher's Odd-Even Merge Sort";
- SLEEPRATIO = 3;
- startRealTimer();
- oddEvenMergeSort(array, 0, currentLen);
-
- endSort();
- Thread.sleep(1000);
-
- category = "Hybrid Sorts";
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "Hybrid Comb Sort (Comb/Insertion)";
- SLEEPRATIO = 3;
- startRealTimer();
- combSort(array, currentLen, true);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "Binary Merge Sort (Merge/Binary Insertion)";
- SLEEPRATIO = 1.25;
- startRealTimer();
- mergeSortOOP(array, currentLen, true);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "Weave Merge Sort (Merge/Insertion)";
- SLEEPRATIO = 2.5;
- startRealTimer();
- weaveMergeSort(array, 0, currentLen - 1);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "TimSort";
- SLEEPRATIO = 1.5;
- startRealTimer();
- timSort(array, currentLen);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "WikiSort (Block Merge Sort)";
- SLEEPRATIO = 2;
- startRealTimer();
- startWikiSort(array, currentLen);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "GrailSort (Block Merge Sort)";
- SLEEPRATIO = 2;
- startRealTimer();
- grailSortWithoutBuffer(array, currentLen);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "std::sort (Introsort)";
- SLEEPRATIO = 1.5;
- startRealTimer();
- introSort(array, currentLen, 32, 1, 0);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "Quick Shell Sort (Introsort with Shellsort)";
- SLEEPRATIO = 1.5;
- startRealTimer();
- introSort(array, currentLen, 48, 2, 12);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 2.5;
-
- refresharray();
- heading = "std::stable_sort (Insert/Bottom-up Merge)";
- SLEEPRATIO = 1.5;
- startRealTimer();
- stableSort(array, currentLen);
-
- endSort();
- Thread.sleep(1000);
-
- category = "Miscellaneous Sorts";
-
- int shortLen = (int) Math.ceil((256 * (currentLen / 2048d)));
- if(shortLen == 1) shortLen = 2;
- if(VISUALS == CIRCULAR && shortLen == 2) shortLen = 4;
- currentLen = currentLen >= 2048 ? 256 : shortLen;
-
- SLEEPRATIO = 1;
-
- refresharray();
- heading = "Pancake Sort";
- SLEEPRATIO = 1;
- startRealTimer();
- pancakeSort(array, currentLen);
-
- endSort();
- Thread.sleep(1000);
-
- category = "Impractical Sorts";
-
- refresharray();
- heading = "Stooge Sort";
- SLEEPRATIO = 2.5;
- startRealTimer();
- stoogeSort(array, 0, currentLen - 1);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 1;
-
- refresharray();
- heading = "Bad Sort";
- SLEEPRATIO = 1;
- startRealTimer();
- badSort(array, currentLen);
-
- endSort();
- Thread.sleep(1000);
-
- refresharray();
- heading = "Silly Sort";
- SLEEPRATIO = 1;
- startRealTimer();
- sillySort(array, 0, currentLen - 1);
-
- endSort();
- Thread.sleep(1000);
-
- refresharray();
- heading = "Slow Sort";
- SLEEPRATIO = 1;
- startRealTimer();
- slowSort(array, 0, currentLen - 1);
-
- endSort();
- Thread.sleep(1000);
-
- refresharray();
- heading = "Less Bogo Sort";
- SLEEPRATIO = 300;
- startRealTimer();
- lessBogoSort(array, currentLen);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 1;
-
- refresharray();
- heading = "Cocktail Bogo Sort";
- startRealTimer();
- SLEEPRATIO = 300;
- doubleBogoSort(array, currentLen);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 1;
-
- refresharray();
- heading = "Bubble Bogo Sort";
- startRealTimer();
- SLEEPRATIO = 1;
- bubbleBogoSort(array, currentLen);
-
- endSort();
- Thread.sleep(1000);
-
- SLEEPRATIO = 1;
-
- refresharray();
- heading = "Exchange Bogo Sort";
- startRealTimer();
- SLEEPRATIO = 0.35;
- exchangeBogoSort(array, currentLen);
-
- endSort();
- Thread.sleep(1000);
-
- currentLen = currentLen < 8 ? currentLen : 8;
- if(VISUALS == CIRCULAR && currentLen == 2) currentLen = 4;
-
- SLEEPRATIO = 0.01;
-
- refresharray();
- heading = "Bogo Sort";
- startRealTimer();
- SLEEPRATIO = 20;
- bogoSort(array, currentLen);
-
- endSort();
- Thread.sleep(1000);
-
- category = "Run All";
- heading = "Done";
- MUTABLE = true;
- }catch (Exception e){}
- SetSound(false);
+ public void reportAllSorts(int[] array) throws Exception {
+ int totalSortCount = 0;
+ for(MultipleSortThread category : this.allSortThreads) {
+ totalSortCount += category.getSortCount();
+ }
+
+ try {
+ int currentSort = 1;
+ for(MultipleSortThread thread : this.allSortThreads) {
+ thread.reportAllSorts(array, currentSort, totalSortCount);
+ this.ArrayVisualizer.getSortingThread().join();
+ currentSort += thread.getCategoryCount();
}
- };
- sortingThread.start();
+ } catch (Exception e) {
+ JErrorPane.invokeErrorMessage(e);
+ }
+
+ this.ArrayVisualizer.setCategory("Run All Sorts");
+ this.ArrayVisualizer.setHeading("Finished!!");
}
- */
}
\ No newline at end of file
diff --git a/src/threads/RunComparisonSort.java b/src/threads/RunComparisonSort.java
index 708b602d..9b5f0a83 100644
--- a/src/threads/RunComparisonSort.java
+++ b/src/threads/RunComparisonSort.java
@@ -6,6 +6,7 @@
import main.ArrayManager;
import main.ArrayVisualizer;
+import templates.JErrorPane;
import templates.Sort;
import utils.Delays;
import utils.Highlights;
@@ -123,13 +124,12 @@ public void run() {
else {
ArrayManager.initializeArray(array);
}
-
- ArrayVisualizer.endSort();
- ArrayManager.toggleMutableLength(true);
}
catch(Exception e) {
- e.printStackTrace();
+ JErrorPane.invokeErrorMessage(e);
}
+ ArrayVisualizer.endSort();
+ ArrayManager.toggleMutableLength(true);
Sounds.toggleSound(false);
}
});
diff --git a/src/threads/RunConcurrentSorts.java b/src/threads/RunConcurrentSorts.java
new file mode 100644
index 00000000..a70ac38d
--- /dev/null
+++ b/src/threads/RunConcurrentSorts.java
@@ -0,0 +1,112 @@
+package threads;
+
+import main.ArrayVisualizer;
+import sorts.IterativeBitonicSort;
+import sorts.IterativeOddEvenMergeSort;
+import sorts.IterativePairwiseSort;
+import sorts.RecursiveBitonicSort;
+import sorts.RecursiveOddEvenMergeSort;
+import sorts.RecursivePairwiseSort;
+import templates.JErrorPane;
+import templates.MultipleSortThread;
+import templates.Sort;
+
+/*
+ *
+MIT License
+
+Copyright (c) 2019 w0rthy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ *
+ */
+
+final public class RunConcurrentSorts extends MultipleSortThread {
+ private Sort RecursiveBitonicSort;
+ private Sort RecursiveOddEvenMergeSort;
+ private Sort RecursivePairwiseSort;
+ private Sort IterativeBitonicSort;
+ private Sort IterativeOddEvenMergeSort;
+ private Sort IterativePairwiseSort;
+
+ public RunConcurrentSorts(ArrayVisualizer ArrayVisualizer) {
+ super(ArrayVisualizer);
+ this.sortCount = 6;
+ this.categoryCount = this.sortCount;
+
+ RecursiveBitonicSort = new RecursiveBitonicSort(Delays, Highlights, Reads, Writes);
+ RecursiveOddEvenMergeSort = new RecursiveOddEvenMergeSort(Delays, Highlights, Reads, Writes);
+ RecursivePairwiseSort = new RecursivePairwiseSort(Delays, Highlights, Reads, Writes);
+ IterativeBitonicSort = new IterativeBitonicSort(Delays, Highlights, Reads, Writes);
+ IterativeOddEvenMergeSort = new IterativeOddEvenMergeSort(Delays, Highlights, Reads, Writes);
+ IterativePairwiseSort = new IterativePairwiseSort(Delays, Highlights, Reads, Writes);
+ }
+
+ @Override
+ protected synchronized void executeSortList(int[] array) throws Exception {
+ RunConcurrentSorts.this.runIndividualSort(RecursiveBitonicSort, 0, array, 1024, 0.6667);
+ RunConcurrentSorts.this.runIndividualSort(RecursiveOddEvenMergeSort, 0, array, 1024, 1);
+ RunConcurrentSorts.this.runIndividualSort(RecursivePairwiseSort, 0, array, 1024, 1);
+ RunConcurrentSorts.this.runIndividualSort(IterativeBitonicSort, 0, array, 1024, 0.3333);
+ RunConcurrentSorts.this.runIndividualSort(IterativeOddEvenMergeSort, 0, array, 1024, 1);
+ RunConcurrentSorts.this.runIndividualSort(IterativePairwiseSort, 0, array, 1024, 0.8);
+ }
+
+ @Override
+ protected synchronized void runThread(int[] array, int current, int total, boolean runAllActive) throws Exception {
+ if(ArrayVisualizer.getSortingThread() != null && ArrayVisualizer.getSortingThread().isAlive())
+ return;
+
+ Sounds.toggleSound(true);
+ ArrayVisualizer.setSortingThread(new Thread() {
+ @Override
+ public void run() {
+ try{
+ if(runAllActive) {
+ RunConcurrentSorts.this.sortNumber = current;
+ RunConcurrentSorts.this.sortCount = total;
+ }
+ else {
+ RunConcurrentSorts.this.sortNumber = 1;
+ }
+
+ ArrayManager.toggleMutableLength(false);
+
+ ArrayVisualizer.setCategory("Concurrent Sorts");
+
+ RunConcurrentSorts.this.executeSortList(array);
+
+ if(!runAllActive) {
+ ArrayVisualizer.setCategory("Run Concurrent Sorts");
+ ArrayVisualizer.setHeading("Done");
+ }
+
+ ArrayManager.toggleMutableLength(true);
+ }
+ catch (Exception e) {
+ JErrorPane.invokeErrorMessage(e);
+ }
+ Sounds.toggleSound(false);
+ ArrayVisualizer.setSortingThread(null);
+ }
+ });
+
+ ArrayVisualizer.runSortingThread();
+ }
+}
\ No newline at end of file
diff --git a/src/threads/RunDistributionSort.java b/src/threads/RunDistributionSort.java
index 97aa8fc9..93dd790c 100644
--- a/src/threads/RunDistributionSort.java
+++ b/src/threads/RunDistributionSort.java
@@ -1,20 +1,17 @@
package threads;
-import java.awt.HeadlessException;
import java.lang.reflect.Constructor;
-import javax.swing.JDialog;
import javax.swing.JOptionPane;
-import javax.swing.UIManager;
import main.ArrayManager;
import main.ArrayVisualizer;
-import sorts.FlashSort;
+import templates.JEnhancedOptionPane;
+import templates.JErrorPane;
import templates.Sort;
import utils.Delays;
import utils.Highlights;
import utils.Reads;
-import utils.Shuffles;
import utils.Sounds;
import utils.Timer;
import utils.Writes;
@@ -45,31 +42,6 @@ of this software and associated documentation files (the "Software"), to deal
*
*/
-// Many thanks to Freek de Bruijn on StackOverflow for providing a custom JOptionPane.
-// https://stackoverflow.com/questions/14407804/how-to-change-the-default-text-of-buttons-in-joptionpane-showinputdialog?noredirect=1&lq=1
-final class JEnhancedOptionPane extends JOptionPane {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- public static String showInputDialog(final Object message, final Object[] options) throws HeadlessException {
- final JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE,
- OK_CANCEL_OPTION, null,
- options, null);
- pane.setWantsInput(true);
- pane.setComponentOrientation((getRootFrame()).getComponentOrientation());
- pane.setMessageType(QUESTION_MESSAGE);
- pane.selectInitialValue();
- final String title = UIManager.getString("OptionPane.inputDialogTitle", null);
- final JDialog dialog = pane.createDialog(null, title);
- dialog.setVisible(true);
- dialog.dispose();
- final Object value = pane.getInputValue();
- return (value == UNINITIALIZED_VALUE) ? null : (String) value;
- }
-}
-
final public class RunDistributionSort {
private ArrayManager ArrayManager;
private ArrayVisualizer ArrayVisualizer;
@@ -183,20 +155,11 @@ public void run(){
}
}
else if(sort.getReportSortID().equals("Shatter Sort") || sort.getReportSortID().equals("Simple Shatter Sort")) {
- // Ugh. Not happy with this patch at all. For some reason, Shatter Sort does not work
- // for all distributions of data unless you only have two partitions/"shatters" **presumably**.
-
- // Specifically, an array that doesn't hold many unique values breaks Shatter Sort.
- if(ArrayManager.getShuffle().equals(Shuffles.SIMILAR)) {
- bucketCount = 2;
+ try {
+ bucketCount = Integer.parseInt(JEnhancedOptionPane.showInputDialog("Enter the size for each partition:", new Object[]{"Enter", "Use default"}));
}
- else {
- try {
- bucketCount = Integer.parseInt(JEnhancedOptionPane.showInputDialog("Enter the size for each partition:", new Object[]{"Enter", "Use default"}));
- }
- catch(Exception e) {
- bucketCount = ArrayVisualizer.getCurrentLength() / 16;
- }
+ catch(Exception e) {
+ bucketCount = ArrayVisualizer.getCurrentLength() / 16;
}
}
else {
@@ -263,11 +226,6 @@ else if(sort.getReportSortID().equals("Shatter Sort") || sort.getReportSortID().
goAhead = true;
}
- // Patch for Flashsort, fixes distribution for few unique numbers
- if(sort.getReportSortID().equals("Flashsort")) {
- ((FlashSort) sort).setCurrentShuffle(ArrayManager.getShuffle());
- }
-
if(sort.getReportSortID().equals("In-Place LSD Radix")) {
Sounds.changeVolume(0.01); // Here to protect your ears :)
}
@@ -281,13 +239,12 @@ else if(sort.getReportSortID().equals("Shatter Sort") || sort.getReportSortID().
else {
ArrayManager.initializeArray(array);
}
-
- ArrayVisualizer.endSort();
- ArrayManager.toggleMutableLength(true);
}
catch(Exception e) {
- e.printStackTrace();
+ JErrorPane.invokeErrorMessage(e);
}
+ ArrayVisualizer.endSort();
+ ArrayManager.toggleMutableLength(true);
Sounds.changeVolume(storeVol);
Sounds.toggleSound(false);
}
diff --git a/src/threads/RunDistributionSorts.java b/src/threads/RunDistributionSorts.java
new file mode 100644
index 00000000..c8279716
--- /dev/null
+++ b/src/threads/RunDistributionSorts.java
@@ -0,0 +1,141 @@
+package threads;
+
+import main.ArrayVisualizer;
+import sorts.AmericanFlagSort;
+import sorts.BinaryQuickSort;
+import sorts.CountingSort;
+import sorts.FlashSort;
+import sorts.GravitySort;
+import sorts.InPlaceLSDRadixSort;
+import sorts.LSDRadixSort;
+import sorts.MSDRadixSort;
+import sorts.PigeonholeSort;
+import sorts.RecursiveBinaryQuickSort;
+import sorts.ShatterSort;
+import sorts.SimpleShatterSort;
+import sorts.TimeSort;
+import templates.JErrorPane;
+import templates.MultipleSortThread;
+import templates.Sort;
+
+/*
+ *
+MIT License
+
+Copyright (c) 2019 w0rthy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ *
+ */
+
+final public class RunDistributionSorts extends MultipleSortThread {
+ private Sort CountingSort;
+ private Sort PigeonholeSort;
+ private Sort GravitySort;
+ private Sort AmericanFlagSort;
+ private Sort LSDRadixSort;
+ private Sort InPlaceLSDRadixSort;
+ private Sort MSDRadixSort;
+ private Sort FlashSort;
+ private Sort BinaryQuickSort;
+ private Sort RecursiveBinaryQuickSort;
+ private Sort ShatterSort;
+ private Sort SimpleShatterSort;
+ private Sort TimeSort;
+
+ public RunDistributionSorts(ArrayVisualizer ArrayVisualizer) {
+ super(ArrayVisualizer);
+ this.sortCount = 13;
+ this.categoryCount = this.sortCount;
+
+ CountingSort = new CountingSort(Delays, Highlights, Reads, Writes);
+ PigeonholeSort = new PigeonholeSort(Delays, Highlights, Reads, Writes);
+ GravitySort = new GravitySort(Delays, Highlights, Reads, Writes);
+ AmericanFlagSort = new AmericanFlagSort(Delays, Highlights, Reads, Writes);
+ LSDRadixSort = new LSDRadixSort(Delays, Highlights, Reads, Writes);
+ InPlaceLSDRadixSort = new InPlaceLSDRadixSort(Delays, Highlights, Reads, Writes);
+ MSDRadixSort = new MSDRadixSort(Delays, Highlights, Reads, Writes);
+ FlashSort = new FlashSort(Delays, Highlights, Reads, Writes);
+ BinaryQuickSort = new BinaryQuickSort(Delays, Highlights, Reads, Writes);
+ RecursiveBinaryQuickSort = new RecursiveBinaryQuickSort(Delays, Highlights, Reads, Writes);
+ ShatterSort = new ShatterSort(Delays, Highlights, Reads, Writes);
+ SimpleShatterSort = new SimpleShatterSort(Delays, Highlights, Reads, Writes);
+ TimeSort = new TimeSort(Delays, Highlights, Reads, Writes);
+ }
+
+ @Override
+ protected synchronized void executeSortList(int[] array) throws Exception {
+ RunDistributionSorts.this.runIndividualSort(CountingSort, 0, array, 2048, 1.5);
+ RunDistributionSorts.this.runIndividualSort(PigeonholeSort, 0, array, 2048, 1.5);
+ RunDistributionSorts.this.runIndividualSort(GravitySort, 0, array, 1024, 0.5);
+ RunDistributionSorts.this.runIndividualSort(AmericanFlagSort, 128, array, 2048, 0.75);
+ RunDistributionSorts.this.runIndividualSort(LSDRadixSort, 4, array, 2048, 1.5);
+ Sounds.toggleSofterSounds(true);
+ RunDistributionSorts.this.runIndividualSort(InPlaceLSDRadixSort, 10, array, 2048, 1);
+ Sounds.toggleSofterSounds(false);
+ RunDistributionSorts.this.runIndividualSort(MSDRadixSort, 4, array, 2048, 1.25);
+ RunDistributionSorts.this.runIndividualSort(FlashSort, 0, array, 2048, 1);
+ RunDistributionSorts.this.runIndividualSort(BinaryQuickSort, 0, array, 2048, 1);
+ RunDistributionSorts.this.runIndividualSort(RecursiveBinaryQuickSort, 0, array, 2048, 1);
+ RunDistributionSorts.this.runIndividualSort(ShatterSort, 128, array, 2048, 1);
+ RunDistributionSorts.this.runIndividualSort(SimpleShatterSort, 128, array, 2048, 1);
+ RunDistributionSorts.this.runIndividualSort(TimeSort, 10, array, 2048, 1);
+ }
+
+ @Override
+ protected synchronized void runThread(int[] array, int current, int total, boolean runAllActive) throws Exception {
+ if(ArrayVisualizer.getSortingThread() != null && ArrayVisualizer.getSortingThread().isAlive())
+ return;
+
+ Sounds.toggleSound(true);
+ ArrayVisualizer.setSortingThread(new Thread() {
+ @Override
+ public void run() {
+ try{
+ if(runAllActive) {
+ RunDistributionSorts.this.sortNumber = current;
+ RunDistributionSorts.this.sortCount = total;
+ }
+ else {
+ RunDistributionSorts.this.sortNumber = 1;
+ }
+
+ ArrayManager.toggleMutableLength(false);
+
+ ArrayVisualizer.setCategory("Distribution Sorts");
+
+ RunDistributionSorts.this.executeSortList(array);
+
+ if(!runAllActive) {
+ ArrayVisualizer.setCategory("Run Distribution Sorts");
+ ArrayVisualizer.setHeading("Done");
+ }
+
+ ArrayManager.toggleMutableLength(true);
+ }
+ catch (Exception e) {
+ JErrorPane.invokeErrorMessage(e);
+ }
+ Sounds.toggleSound(false);
+ ArrayVisualizer.setSortingThread(null);
+ }
+ });
+ ArrayVisualizer.runSortingThread();
+ }
+}
\ No newline at end of file
diff --git a/src/threads/RunExchangeSorts.java b/src/threads/RunExchangeSorts.java
index a86101d2..5926f30c 100644
--- a/src/threads/RunExchangeSorts.java
+++ b/src/threads/RunExchangeSorts.java
@@ -12,10 +12,13 @@
import sorts.LRQuickSort;
import sorts.OddEvenSort;
import sorts.SmartBubbleSort;
+import sorts.SmartCocktailSort;
import sorts.SmartGnomeSort;
import sorts.StableQuickSort;
+import templates.JErrorPane;
import templates.MultipleSortThread;
import templates.Sort;
+import utils.Shuffles;
/*
*
@@ -44,11 +47,62 @@ of this software and associated documentation files (the "Software"), to deal
*/
final public class RunExchangeSorts extends MultipleSortThread {
+ private Sort BubbleSort;
+ private Sort SmartBubbleSort;
+ private Sort CocktailShakerSort;
+ private Sort SmartCocktailSort;
+ private Sort OddEvenSort;
+ private Sort GnomeSort;
+ private Sort SmartGnomeSort;
+ private Sort BinaryGnomeSort;
+ private Sort CombSort;
+ private Sort CircleSort;
+ private Sort LLQuickSort;
+ private Sort LRQuickSort;
+ private Sort DualPivotQuickSort;
+ private Sort StableQuickSort;
+
public RunExchangeSorts(ArrayVisualizer ArrayVisualizer) {
super(ArrayVisualizer);
+ this.sortCount = 14;
+ this.categoryCount = this.sortCount;
+
+ BubbleSort = new BubbleSort(Delays, Highlights, Reads, Writes);
+ SmartBubbleSort = new SmartBubbleSort(Delays, Highlights, Reads, Writes);
+ CocktailShakerSort = new CocktailShakerSort(Delays, Highlights, Reads, Writes);
+ SmartCocktailSort = new SmartCocktailSort(Delays, Highlights, Reads, Writes);
+ OddEvenSort = new OddEvenSort(Delays, Highlights, Reads, Writes);
+ GnomeSort = new GnomeSort(Delays, Highlights, Reads, Writes);
+ SmartGnomeSort = new SmartGnomeSort(Delays, Highlights, Reads, Writes);
+ BinaryGnomeSort = new BinaryGnomeSort(Delays, Highlights, Reads, Writes);
+ CombSort = new CombSort(Delays, Highlights, Reads, Writes);
+ CircleSort = new CircleSort(Delays, Highlights, Reads, Writes);
+ LLQuickSort = new LLQuickSort(Delays, Highlights, Reads, Writes);
+ LRQuickSort = new LRQuickSort(Delays, Highlights, Reads, Writes);
+ DualPivotQuickSort = new DualPivotQuickSort(Delays, Highlights, Reads, Writes);
+ StableQuickSort = new StableQuickSort(Delays, Highlights, Reads, Writes);
}
- public synchronized void ReportExchangeSorts(int[] array) throws Exception {
+ @Override
+ protected synchronized void executeSortList(int[] array) throws Exception {
+ RunExchangeSorts.this.runIndividualSort(BubbleSort, 0, array, 512, 1.5);
+ RunExchangeSorts.this.runIndividualSort(SmartBubbleSort, 0, array, 512, 1.5);
+ RunExchangeSorts.this.runIndividualSort(CocktailShakerSort, 0, array, 512, 1.25);
+ RunExchangeSorts.this.runIndividualSort(SmartCocktailSort, 0, array, 512, 1.25);
+ RunExchangeSorts.this.runIndividualSort(OddEvenSort, 0, array, 512, 1);
+ RunExchangeSorts.this.runIndividualSort(GnomeSort, 0, array, 128, 0.025);
+ RunExchangeSorts.this.runIndividualSort(SmartGnomeSort, 0, array, 128, 0.025);
+ RunExchangeSorts.this.runIndividualSort(BinaryGnomeSort, 0, array, 128, 0.025);
+ RunExchangeSorts.this.runIndividualSort(CombSort, 0, array, 1024, 1);
+ RunExchangeSorts.this.runIndividualSort(CircleSort, 0, array, 1024, 1);
+ RunExchangeSorts.this.runIndividualSort(LLQuickSort, 0, array, 2048, ArrayManager.getShuffle() == Shuffles.RANDOM ? 1.5 : 65);
+ RunExchangeSorts.this.runIndividualSort(LRQuickSort, 0, array, 2048, 1);
+ RunExchangeSorts.this.runIndividualSort(DualPivotQuickSort, 0, array, 2048, ArrayManager.getShuffle() == Shuffles.RANDOM ? 1 : 50);
+ RunExchangeSorts.this.runIndividualSort(StableQuickSort, 0, array, 2048, ArrayManager.getShuffle() == Shuffles.RANDOM ? 1 : 50);
+ }
+
+ @Override
+ protected synchronized void runThread(int[] array, int current, int total, boolean runAllActive) throws Exception {
if(ArrayVisualizer.getSortingThread() != null && ArrayVisualizer.getSortingThread().isAlive())
return;
@@ -57,54 +111,34 @@ public synchronized void ReportExchangeSorts(int[] array) throws Exception {
@Override
public void run() {
try{
- Sort BubbleSort = new BubbleSort(Delays, Highlights, Reads, Writes);
- Sort SmartBubbleSort = new SmartBubbleSort(Delays, Highlights, Reads, Writes);
- Sort CocktailShakerSort = new CocktailShakerSort(Delays, Highlights, Reads, Writes);
- Sort OddEvenSort = new OddEvenSort(Delays, Highlights, Reads, Writes);
- Sort GnomeSort = new GnomeSort(Delays, Highlights, Reads, Writes);
- Sort SmartGnomeSort = new SmartGnomeSort(Delays, Highlights, Reads, Writes);
- Sort BinaryGnomeSort = new BinaryGnomeSort(Delays, Highlights, Reads, Writes);
- Sort CombSort = new CombSort(Delays, Highlights, Reads, Writes);
- Sort CircleSort = new CircleSort(Delays, Highlights, Reads, Writes);
- Sort LLQuickSort = new LLQuickSort(Delays, Highlights, Reads, Writes);
- Sort LRQuickSort = new LRQuickSort(Delays, Highlights, Reads, Writes);
- Sort DualPivotQuickSort = new DualPivotQuickSort(Delays, Highlights, Reads, Writes);
- Sort StableQuickSort = new StableQuickSort(Delays, Highlights, Reads, Writes);
-
- RunExchangeSorts.this.sortNumber = 1;
- RunExchangeSorts.this.sortCount = 13;
-
+ if(runAllActive) {
+ RunExchangeSorts.this.sortNumber = current;
+ RunExchangeSorts.this.sortCount = total;
+ }
+ else {
+ RunExchangeSorts.this.sortNumber = 1;
+ }
+
ArrayManager.toggleMutableLength(false);
ArrayVisualizer.setCategory("Exchange Sorts");
- RunExchangeSorts.this.RunIndividualSort(BubbleSort, 0, array, 25);
- RunExchangeSorts.this.RunIndividualSort(SmartBubbleSort, 0, array, 22);
- RunExchangeSorts.this.RunIndividualSort(CocktailShakerSort, 0, array, 22);
- RunExchangeSorts.this.RunIndividualSort(OddEvenSort, 0, array, 25);
- RunExchangeSorts.this.RunIndividualSort(GnomeSort, 0, array, 10);
- RunExchangeSorts.this.RunIndividualSort(SmartGnomeSort, 0, array, 10);
- RunExchangeSorts.this.RunIndividualSort(BinaryGnomeSort, 0, array, 10);
- RunExchangeSorts.this.RunIndividualSort(CombSort, 0, array, 2);
- RunExchangeSorts.this.RunIndividualSort(CircleSort, 0, array, 2.5);
- RunExchangeSorts.this.RunIndividualSort(LLQuickSort, 0, array, 1.25);
- RunExchangeSorts.this.RunIndividualSort(LRQuickSort, 0, array, 2);
- RunExchangeSorts.this.RunIndividualSort(DualPivotQuickSort, 0, array, 1.25);
- RunExchangeSorts.this.RunIndividualSort(StableQuickSort, 0, array, 1.5);
+ RunExchangeSorts.this.executeSortList(array);
- ArrayVisualizer.setCategory("Run Exchange Sorts");
- ArrayVisualizer.setHeading("Done");
+ if(!runAllActive) {
+ ArrayVisualizer.setCategory("Run Exchange Sorts");
+ ArrayVisualizer.setHeading("Done");
+ }
ArrayManager.toggleMutableLength(true);
}
catch (Exception e) {
- e.printStackTrace();
+ JErrorPane.invokeErrorMessage(e);
}
Sounds.toggleSound(false);
ArrayVisualizer.setSortingThread(null);
}
});
-
ArrayVisualizer.runSortingThread();
}
}
\ No newline at end of file
diff --git a/src/threads/RunHybridSorts.java b/src/threads/RunHybridSorts.java
new file mode 100644
index 00000000..3ca2a196
--- /dev/null
+++ b/src/threads/RunHybridSorts.java
@@ -0,0 +1,144 @@
+package threads;
+
+import main.ArrayVisualizer;
+import sorts.BinaryMergeSort;
+import sorts.BottomUpMergeSort;
+import sorts.BranchedPDQSort;
+import sorts.BranchlessPDQSort;
+import sorts.CocktailMergeSort;
+import sorts.GrailSort;
+import sorts.HybridCombSort;
+import sorts.IntroCircleSort;
+import sorts.IntroSort;
+import sorts.OptimizedDualPivotQuickSort;
+import sorts.SqrtSort;
+import sorts.TimSort;
+import sorts.WeaveMergeSort;
+import sorts.WikiSort;
+import templates.JErrorPane;
+import templates.MultipleSortThread;
+import templates.Sort;
+import utils.Shuffles;
+
+/*
+ *
+MIT License
+
+Copyright (c) 2019 w0rthy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ *
+ */
+
+final public class RunHybridSorts extends MultipleSortThread {
+ private Sort HybridCombSort;
+ private Sort IntroCircleSort;
+ private Sort BinaryMergeSort;
+ private Sort WeaveMergeSort;
+ private Sort TimSort;
+ private Sort CocktailMergeSort;
+ private Sort WikiSort;
+ private Sort GrailSort;
+ private Sort SqrtSort;
+ private Sort IntroSort;
+ private Sort BottomUpMergeSort;
+ private Sort OptimizedDualPivotQuickSort;
+ private Sort BranchedPDQSort;
+ private Sort BranchlessPDQSort;
+
+ public RunHybridSorts(ArrayVisualizer ArrayVisualizer) {
+ super(ArrayVisualizer);
+ this.sortCount = 14;
+ this.categoryCount = this.sortCount;
+
+ HybridCombSort = new HybridCombSort(Delays, Highlights, Reads, Writes);
+ IntroCircleSort = new IntroCircleSort(Delays, Highlights, Reads, Writes);
+ BinaryMergeSort = new BinaryMergeSort(Delays, Highlights, Reads, Writes);
+ WeaveMergeSort = new WeaveMergeSort(Delays, Highlights, Reads, Writes);
+ TimSort = new TimSort(Delays, Highlights, Reads, Writes);
+ CocktailMergeSort = new CocktailMergeSort(Delays, Highlights, Reads, Writes);
+ WikiSort = new WikiSort(Delays, Highlights, Reads, Writes);
+ GrailSort = new GrailSort(Delays, Highlights, Reads, Writes);
+ SqrtSort = new SqrtSort(Delays, Highlights, Reads, Writes);
+ IntroSort = new IntroSort(Delays, Highlights, Reads, Writes);
+ BottomUpMergeSort = new BottomUpMergeSort(Delays, Highlights, Reads, Writes);
+ OptimizedDualPivotQuickSort = new OptimizedDualPivotQuickSort(Delays, Highlights, Reads, Writes);
+ BranchedPDQSort = new BranchedPDQSort(Delays, Highlights, Reads, Writes);
+ BranchlessPDQSort = new BranchlessPDQSort(Delays, Highlights, Reads, Writes);
+ }
+
+ @Override
+ protected synchronized void executeSortList(int[] array) throws Exception {
+ RunHybridSorts.this.runIndividualSort(HybridCombSort, 0, array, 1024, 1);
+ RunHybridSorts.this.runIndividualSort(IntroCircleSort, 0, array, 1024, 1);
+ RunHybridSorts.this.runIndividualSort(BinaryMergeSort, 0, array, 2048, 1);
+ RunHybridSorts.this.runIndividualSort(WeaveMergeSort, 0, array, 2048, ArrayManager.getShuffle() == Shuffles.RANDOM ? 1.25 : 6);
+ RunHybridSorts.this.runIndividualSort(TimSort, 0, array, 2048, 1);
+ RunHybridSorts.this.runIndividualSort(CocktailMergeSort, 0, array, 2048, 1);
+ RunHybridSorts.this.runIndividualSort(WikiSort, 0, array, 2048, 1);
+ RunHybridSorts.this.runIndividualSort(GrailSort, 0, array, 2048, 1);
+ RunHybridSorts.this.runIndividualSort(SqrtSort, 0, array, 2048, 1);
+ RunHybridSorts.this.runIndividualSort(IntroSort, 0, array, 2048, 1);
+ RunHybridSorts.this.runIndividualSort(BottomUpMergeSort, 0, array, 2048, 1);
+ RunHybridSorts.this.runIndividualSort(OptimizedDualPivotQuickSort, 0, array, 2048, 0.75);
+ RunHybridSorts.this.runIndividualSort(BranchedPDQSort, 0, array, 2048, 0.75);
+ RunHybridSorts.this.runIndividualSort(BranchlessPDQSort, 0, array, 2048, 0.75);
+ }
+
+ @Override
+ protected synchronized void runThread(int[] array, int current, int total, boolean runAllActive) throws Exception {
+ if(ArrayVisualizer.getSortingThread() != null && ArrayVisualizer.getSortingThread().isAlive())
+ return;
+
+ Sounds.toggleSound(true);
+ ArrayVisualizer.setSortingThread(new Thread() {
+ @Override
+ public void run() {
+ try{
+ if(runAllActive) {
+ RunHybridSorts.this.sortNumber = current;
+ RunHybridSorts.this.sortCount = total;
+ }
+ else {
+ RunHybridSorts.this.sortNumber = 1;
+ }
+
+ ArrayManager.toggleMutableLength(false);
+
+ ArrayVisualizer.setCategory("Hybrid Sorts");
+
+ RunHybridSorts.this.executeSortList(array);
+
+ if(!runAllActive) {
+ ArrayVisualizer.setCategory("Run Hybrid Sorts");
+ ArrayVisualizer.setHeading("Done");
+ }
+
+ ArrayManager.toggleMutableLength(true);
+ }
+ catch (Exception e) {
+ JErrorPane.invokeErrorMessage(e);
+ }
+ Sounds.toggleSound(false);
+ ArrayVisualizer.setSortingThread(null);
+ }
+ });
+ ArrayVisualizer.runSortingThread();
+ }
+}
\ No newline at end of file
diff --git a/src/threads/RunImpracticalSorts.java b/src/threads/RunImpracticalSorts.java
new file mode 100644
index 00000000..69da1159
--- /dev/null
+++ b/src/threads/RunImpracticalSorts.java
@@ -0,0 +1,128 @@
+package threads;
+
+import main.ArrayVisualizer;
+import sorts.BadSort;
+import sorts.BogoSort;
+import sorts.BubbleBogoSort;
+import sorts.CocktailBogoSort;
+import sorts.ExchangeBogoSort;
+import sorts.LessBogoSort;
+import sorts.SillySort;
+import sorts.SlowSort;
+import sorts.StoogeSort;
+import templates.JErrorPane;
+import templates.MultipleSortThread;
+import templates.Sort;
+
+/*
+ *
+MIT License
+
+Copyright (c) 2019 w0rthy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ *
+ */
+
+final public class RunImpracticalSorts extends MultipleSortThread {
+ private Sort BadSort;
+ private Sort StoogeSort;
+ private Sort SillySort;
+ private Sort SlowSort;
+ private Sort ExchangeBogoSort;
+ private Sort BubbleBogoSort;
+ private Sort LessBogoSort;
+ private Sort CocktailBogoSort;
+ private Sort BogoSort;
+
+ public RunImpracticalSorts(ArrayVisualizer ArrayVisualizer) {
+ super(ArrayVisualizer);
+ this.sortCount = 9;
+ this.categoryCount = this.sortCount;
+
+ BadSort = new BadSort(Delays, Highlights, Reads, Writes);
+ StoogeSort = new StoogeSort(Delays, Highlights, Reads, Writes);
+ SillySort = new SillySort(Delays, Highlights, Reads, Writes);
+ SlowSort = new SlowSort(Delays, Highlights, Reads, Writes);
+ ExchangeBogoSort = new ExchangeBogoSort(Delays, Highlights, Reads, Writes);
+ BubbleBogoSort = new BubbleBogoSort(Delays, Highlights, Reads, Writes);
+ LessBogoSort = new LessBogoSort(Delays, Highlights, Reads, Writes);
+ CocktailBogoSort = new CocktailBogoSort(Delays, Highlights, Reads, Writes);
+ BogoSort = new BogoSort(Delays, Highlights, Reads, Writes);
+ }
+
+ @Override
+ protected synchronized void executeSortList(int[] array) throws Exception {
+ RunImpracticalSorts.this.runIndividualSort(BadSort, 0, array, 64, 0.0075);
+ RunImpracticalSorts.this.runIndividualSort(StoogeSort, 0, array, 64, 0.005);
+ RunImpracticalSorts.this.runIndividualSort(SillySort, 0, array, 64, 10);
+ RunImpracticalSorts.this.runIndividualSort(SlowSort, 0, array, 64, 10);
+ Sounds.toggleSofterSounds(true);
+ RunImpracticalSorts.this.runIndividualSort(ExchangeBogoSort, 0, array, 32, 0.01);
+ RunImpracticalSorts.this.runIndividualSort(BubbleBogoSort, 0, array, 32, 0.01);
+ RunImpracticalSorts.this.runIndividualSort(LessBogoSort, 0, array, 16, 0.0025);
+ RunImpracticalSorts.this.runIndividualSort(CocktailBogoSort, 0, array, 16, 0.0025);
+ RunImpracticalSorts.this.runIndividualSort(BogoSort, 0, array, 8, 1);
+ Sounds.toggleSofterSounds(false);
+ }
+
+ @Override
+ protected synchronized void runThread(int[] array, int current, int total, boolean runAllActive) throws Exception {
+ if(ArrayVisualizer.getSortingThread() != null && ArrayVisualizer.getSortingThread().isAlive())
+ return;
+
+ Sounds.toggleSound(true);
+ ArrayVisualizer.setSortingThread(new Thread() {
+ @Override
+ public void run() {
+ try{
+ if(runAllActive) {
+ RunImpracticalSorts.this.sortNumber = current;
+ RunImpracticalSorts.this.sortCount = total;
+ }
+ else {
+ RunImpracticalSorts.this.sortNumber = 1;
+ }
+
+ ArrayManager.toggleMutableLength(false);
+
+ ArrayVisualizer.setCategory("Impractical Sorts");
+
+ RunImpracticalSorts.this.executeSortList(array);
+
+ if(runAllActive) {
+ Thread.sleep(3000);
+ }
+ else {
+ ArrayVisualizer.setCategory("Run Impractical Sorts");
+ ArrayVisualizer.setHeading("Done");
+ }
+
+ ArrayManager.toggleMutableLength(true);
+ }
+ catch (Exception e) {
+ JErrorPane.invokeErrorMessage(e);
+ }
+ Sounds.toggleSound(false);
+ ArrayVisualizer.setSortingThread(null);
+ }
+ });
+ ArrayVisualizer.runSortingThread();
+ }
+}
\ No newline at end of file
diff --git a/src/threads/RunInsertionSorts.java b/src/threads/RunInsertionSorts.java
index fddbd186..0a850f5e 100644
--- a/src/threads/RunInsertionSorts.java
+++ b/src/threads/RunInsertionSorts.java
@@ -5,7 +5,7 @@
import sorts.InsertionSort;
import sorts.PatienceSort;
import sorts.ShellSort;
-import sorts.TreeSort;
+import templates.JErrorPane;
import templates.MultipleSortThread;
import templates.Sort;
@@ -36,11 +36,37 @@ of this software and associated documentation files (the "Software"), to deal
*/
final public class RunInsertionSorts extends MultipleSortThread {
+ private Sort InsertionSort;
+ private Sort BinaryInsertionSort;
+ private Sort ShellSort;
+ private Sort PatienceSort;
+ //private Sort TreeSort;
+
public RunInsertionSorts(ArrayVisualizer ArrayVisualizer) {
super(ArrayVisualizer);
+ this.sortCount = 4;
+ //5;
+ //TODO: Add Treesort back in when fixed
+ this.categoryCount = this.sortCount;
+
+ InsertionSort = new InsertionSort(Delays, Highlights, Reads, Writes);
+ BinaryInsertionSort = new BinaryInsertionSort(Delays, Highlights, Reads, Writes);
+ ShellSort = new ShellSort(Delays, Highlights, Reads, Writes);
+ PatienceSort = new PatienceSort(Delays, Highlights, Reads, Writes);
+ //Sort TreeSort = new TreeSort(Delays, Highlights, Reads, Writes);
}
- public synchronized void ReportInsertionSorts(int[] array) throws Exception {
+ @Override
+ protected synchronized void executeSortList(int[] array) throws Exception {
+ RunInsertionSorts.this.runIndividualSort(InsertionSort, 0, array, 128, 0.005);
+ RunInsertionSorts.this.runIndividualSort(BinaryInsertionSort, 0, array, 128, 0.025);
+ RunInsertionSorts.this.runIndividualSort(ShellSort, 0, array, 256, 0.1);
+ RunInsertionSorts.this.runIndividualSort(PatienceSort, 0, array, 2048, 1);
+ //RunInsertionSorts.this.RunIndividualSort(TreeSort, 0, array, 2048, 1);
+ }
+
+ @Override
+ protected synchronized void runThread(int[] array, int current, int total, boolean runAllActive) throws Exception {
if(ArrayVisualizer.getSortingThread() != null && ArrayVisualizer.getSortingThread().isAlive())
return;
@@ -49,38 +75,34 @@ public synchronized void ReportInsertionSorts(int[] array) throws Exception {
@Override
public void run() {
try{
- Sort InsertionSort = new InsertionSort(Delays, Highlights, Reads, Writes);
- Sort BinaryInsertionSort = new BinaryInsertionSort(Delays, Highlights, Reads, Writes);
- Sort ShellSort = new ShellSort(Delays, Highlights, Reads, Writes);
- Sort PatienceSort = new PatienceSort(Delays, Highlights, Reads, Writes);
- Sort TreeSort = new TreeSort(Delays, Highlights, Reads, Writes);
-
- RunInsertionSorts.this.sortNumber = 1;
- RunInsertionSorts.this.sortCount = 5;
-
+ if(runAllActive) {
+ RunInsertionSorts.this.sortNumber = current;
+ RunInsertionSorts.this.sortCount = total;
+ }
+ else {
+ RunInsertionSorts.this.sortNumber = 1;
+ }
+
ArrayManager.toggleMutableLength(false);
ArrayVisualizer.setCategory("Insertion Sorts");
- RunInsertionSorts.this.RunIndividualSort(InsertionSort, 0, array, 2);
- RunInsertionSorts.this.RunIndividualSort(BinaryInsertionSort, 0, array, 2);
- RunInsertionSorts.this.RunIndividualSort(ShellSort, 0, array, 3);
- RunInsertionSorts.this.RunIndividualSort(PatienceSort, 0, array, 2);
- RunInsertionSorts.this.RunIndividualSort(TreeSort, 0, array, 2);
+ RunInsertionSorts.this.executeSortList(array);
- ArrayVisualizer.setCategory("Run Insertion Sorts");
- ArrayVisualizer.setHeading("Done");
+ if(!runAllActive) {
+ ArrayVisualizer.setCategory("Run Insertion Sorts");
+ ArrayVisualizer.setHeading("Done");
+ }
ArrayManager.toggleMutableLength(true);
}
catch (Exception e) {
- e.printStackTrace();
+ JErrorPane.invokeErrorMessage(e);
}
Sounds.toggleSound(false);
ArrayVisualizer.setSortingThread(null);
}
});
-
ArrayVisualizer.runSortingThread();
}
}
\ No newline at end of file
diff --git a/src/threads/RunMergeSorts.java b/src/threads/RunMergeSorts.java
index d2725a8b..e52a26c9 100644
--- a/src/threads/RunMergeSorts.java
+++ b/src/threads/RunMergeSorts.java
@@ -5,6 +5,7 @@
import sorts.LazyStableSort;
import sorts.MergeSort;
import sorts.RotateMergeSort;
+import templates.JErrorPane;
import templates.MultipleSortThread;
import templates.Sort;
@@ -35,11 +36,32 @@ of this software and associated documentation files (the "Software"), to deal
*/
final public class RunMergeSorts extends MultipleSortThread {
+ private Sort MergeSort;
+ private Sort InPlaceMergeSort;
+ private Sort LazyStableSort;
+ private Sort RotateMergeSort;
+
public RunMergeSorts(ArrayVisualizer ArrayVisualizer) {
super(ArrayVisualizer);
+ this.sortCount = 4;
+ this.categoryCount = this.sortCount;
+
+ MergeSort = new MergeSort(Delays, Highlights, Reads, Writes);
+ InPlaceMergeSort = new InPlaceMergeSort(Delays, Highlights, Reads, Writes);
+ LazyStableSort = new LazyStableSort(Delays, Highlights, Reads, Writes);
+ RotateMergeSort = new RotateMergeSort(Delays, Highlights, Reads, Writes);
}
- public synchronized void ReportMergeSorts(int[] array) throws Exception {
+ @Override
+ protected synchronized void executeSortList(int[] array) throws Exception {
+ RunMergeSorts.this.runIndividualSort(MergeSort, 0, array, 2048, 1.5);
+ RunMergeSorts.this.runIndividualSort(InPlaceMergeSort, 0, array, 2048, 1.75);
+ RunMergeSorts.this.runIndividualSort(LazyStableSort, 0, array, 256, 0.2);
+ RunMergeSorts.this.runIndividualSort(RotateMergeSort, 0, array, 512, 0.2);
+ }
+
+ @Override
+ protected synchronized void runThread(int[] array, int current, int total, boolean runAllActive) throws Exception {
if(ArrayVisualizer.getSortingThread() != null && ArrayVisualizer.getSortingThread().isAlive())
return;
@@ -48,36 +70,34 @@ public synchronized void ReportMergeSorts(int[] array) throws Exception {
@Override
public void run() {
try{
- Sort MergeSort = new MergeSort(Delays, Highlights, Reads, Writes);
- Sort InPlaceMergeSort = new InPlaceMergeSort(Delays, Highlights, Reads, Writes);
- Sort LazyStableSort = new LazyStableSort(Delays, Highlights, Reads, Writes);
- Sort RotateMergeSort = new RotateMergeSort(Delays, Highlights, Reads, Writes);
+ if(runAllActive) {
+ RunMergeSorts.this.sortNumber = current;
+ RunMergeSorts.this.sortCount = total;
+ }
+ else {
+ RunMergeSorts.this.sortNumber = 1;
+ }
- RunMergeSorts.this.sortNumber = 1;
- RunMergeSorts.this.sortCount = 4;
-
ArrayManager.toggleMutableLength(false);
ArrayVisualizer.setCategory("Merge Sorts");
- RunMergeSorts.this.RunIndividualSort(MergeSort, 0, array, 1.75);
- RunMergeSorts.this.RunIndividualSort(InPlaceMergeSort, 0, array, 2);
- RunMergeSorts.this.RunIndividualSort(LazyStableSort, 0, array, 20);
- RunMergeSorts.this.RunIndividualSort(RotateMergeSort, 0, array, 1.5);
+ RunMergeSorts.this.executeSortList(array);
- ArrayVisualizer.setCategory("Merge Sorts");
- ArrayVisualizer.setHeading("Done");
+ if(!runAllActive) {
+ ArrayVisualizer.setCategory("Run Merge Sorts");
+ ArrayVisualizer.setHeading("Done");
+ }
ArrayManager.toggleMutableLength(true);
}
catch (Exception e) {
- e.printStackTrace();
+ JErrorPane.invokeErrorMessage(e);
}
Sounds.toggleSound(false);
ArrayVisualizer.setSortingThread(null);
}
});
-
ArrayVisualizer.runSortingThread();
}
}
\ No newline at end of file
diff --git a/src/threads/RunMiscellaneousSorts.java b/src/threads/RunMiscellaneousSorts.java
new file mode 100644
index 00000000..3f782a90
--- /dev/null
+++ b/src/threads/RunMiscellaneousSorts.java
@@ -0,0 +1,91 @@
+package threads;
+
+import main.ArrayVisualizer;
+import sorts.PancakeSort;
+import templates.JErrorPane;
+import templates.MultipleSortThread;
+import templates.Sort;
+
+/*
+ *
+MIT License
+
+Copyright (c) 2019 w0rthy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ *
+ */
+
+final public class RunMiscellaneousSorts extends MultipleSortThread {
+ private Sort PancakeSort;
+
+ public RunMiscellaneousSorts(ArrayVisualizer ArrayVisualizer) {
+ super(ArrayVisualizer);
+ this.sortCount = 1;
+ this.categoryCount = this.sortCount;
+
+ PancakeSort = new PancakeSort(Delays, Highlights, Reads, Writes);
+ }
+
+ @Override
+ protected synchronized void executeSortList(int[] array) throws Exception {
+ RunMiscellaneousSorts.this.runIndividualSort(PancakeSort, 0, array, 128, 0.015);
+ }
+
+ @Override
+ protected synchronized void runThread(int[] array, int current, int total, boolean runAllActive) throws Exception {
+ if(ArrayVisualizer.getSortingThread() != null && ArrayVisualizer.getSortingThread().isAlive())
+ return;
+
+ Sounds.toggleSound(true);
+ ArrayVisualizer.setSortingThread(new Thread() {
+ @Override
+ public void run() {
+ try{
+ if(runAllActive) {
+ RunMiscellaneousSorts.this.sortNumber = current;
+ RunMiscellaneousSorts.this.sortCount = total;
+ }
+ else {
+ RunMiscellaneousSorts.this.sortNumber = 1;
+ }
+
+ ArrayManager.toggleMutableLength(false);
+
+ ArrayVisualizer.setCategory("Miscellaneous Sorts");
+
+ RunMiscellaneousSorts.this.executeSortList(array);
+
+ if(!runAllActive) {
+ ArrayVisualizer.setCategory("Run Miscellaneous Sorts");
+ ArrayVisualizer.setHeading("Done");
+ }
+
+ ArrayManager.toggleMutableLength(true);
+ }
+ catch (Exception e) {
+ JErrorPane.invokeErrorMessage(e);
+ }
+ Sounds.toggleSound(false);
+ ArrayVisualizer.setSortingThread(null);
+ }
+ });
+ ArrayVisualizer.runSortingThread();
+ }
+}
\ No newline at end of file
diff --git a/src/threads/RunSelectionSorts.java b/src/threads/RunSelectionSorts.java
index 51567c23..16b76546 100644
--- a/src/threads/RunSelectionSorts.java
+++ b/src/threads/RunSelectionSorts.java
@@ -3,6 +3,7 @@
import main.ArrayVisualizer;
import sorts.CycleSort;
import sorts.DoubleSelectionSort;
+import sorts.FlippedMinHeapSort;
import sorts.MaxHeapSort;
import sorts.MinHeapSort;
import sorts.PoplarHeapSort;
@@ -11,6 +12,7 @@
import sorts.TernaryHeapSort;
import sorts.TournamentSort;
import sorts.WeakHeapSort;
+import templates.JErrorPane;
import templates.MultipleSortThread;
import templates.Sort;
@@ -41,11 +43,53 @@ of this software and associated documentation files (the "Software"), to deal
*/
final public class RunSelectionSorts extends MultipleSortThread {
+ private Sort SelectionSort;
+ private Sort DoubleSelectionSort;
+ private Sort CycleSort;
+ private Sort MaxHeapSort;
+ private Sort MinHeapSort;
+ private Sort FlippedMinHeapSort;
+ private Sort WeakHeapSort;
+ private Sort TernaryHeapSort;
+ private Sort SmoothSort;
+ private Sort PoplarHeapSort;
+ private Sort TournamentSort;
+
public RunSelectionSorts(ArrayVisualizer ArrayVisualizer) {
super(ArrayVisualizer);
+ this.sortCount = 11;
+ this.categoryCount = this.sortCount;
+
+ SelectionSort = new SelectionSort(Delays, Highlights, Reads, Writes);
+ DoubleSelectionSort = new DoubleSelectionSort(Delays, Highlights, Reads, Writes);
+ CycleSort = new CycleSort(Delays, Highlights, Reads, Writes);
+ MaxHeapSort = new MaxHeapSort(Delays, Highlights, Reads, Writes);
+ MinHeapSort = new MinHeapSort(Delays, Highlights, Reads, Writes);
+ FlippedMinHeapSort = new FlippedMinHeapSort(Delays, Highlights, Reads, Writes);
+ WeakHeapSort = new WeakHeapSort(Delays, Highlights, Reads, Writes);
+ TernaryHeapSort = new TernaryHeapSort(Delays, Highlights, Reads, Writes);
+ SmoothSort = new SmoothSort(Delays, Highlights, Reads, Writes);
+ PoplarHeapSort = new PoplarHeapSort(Delays, Highlights, Reads, Writes);
+ TournamentSort = new TournamentSort(Delays, Highlights, Reads, Writes);
}
- public synchronized void ReportSelectionSorts(int[] array) throws Exception {
+ @Override
+ protected synchronized void executeSortList(int[] array) throws Exception {
+ RunSelectionSorts.this.runIndividualSort(SelectionSort, 0, array, 128, 0.01);
+ RunSelectionSorts.this.runIndividualSort(DoubleSelectionSort, 0, array, 128, 0.01);
+ RunSelectionSorts.this.runIndividualSort(CycleSort, 0, array, 128, 0.01);
+ RunSelectionSorts.this.runIndividualSort(MaxHeapSort, 0, array, 2048, 1.5);
+ RunSelectionSorts.this.runIndividualSort(MinHeapSort, 0, array, 2048, 1.5);
+ RunSelectionSorts.this.runIndividualSort(FlippedMinHeapSort, 0, array, 2048, 1.5);
+ RunSelectionSorts.this.runIndividualSort(WeakHeapSort, 0, array, 2048, 1);
+ RunSelectionSorts.this.runIndividualSort(TernaryHeapSort, 0, array, 2048, 1);
+ RunSelectionSorts.this.runIndividualSort(SmoothSort, 0, array, 2048, 1.5);
+ RunSelectionSorts.this.runIndividualSort(PoplarHeapSort, 0, array, 2048, 1);
+ RunSelectionSorts.this.runIndividualSort(TournamentSort, 0, array, 2048, 1.5);
+ }
+
+ @Override
+ protected synchronized void runThread(int[] array, int current, int total, boolean runAllActive) throws Exception {
if(ArrayVisualizer.getSortingThread() != null && ArrayVisualizer.getSortingThread().isAlive())
return;
@@ -54,48 +98,34 @@ public synchronized void ReportSelectionSorts(int[] array) throws Exception {
@Override
public void run() {
try{
- Sort SelectionSort = new SelectionSort(Delays, Highlights, Reads, Writes);
- Sort DoubleSelectionSort = new DoubleSelectionSort(Delays, Highlights, Reads, Writes);
- Sort CycleSort = new CycleSort(Delays, Highlights, Reads, Writes);
- Sort MaxHeapSort = new MaxHeapSort(Delays, Highlights, Reads, Writes);
- Sort MinHeapSort = new MinHeapSort(Delays, Highlights, Reads, Writes);
- Sort WeakHeapSort = new WeakHeapSort(Delays, Highlights, Reads, Writes);
- Sort TernaryHeapSort = new TernaryHeapSort(Delays, Highlights, Reads, Writes);
- Sort SmoothSort = new SmoothSort(Delays, Highlights, Reads, Writes);
- Sort PoplarHeapSort = new PoplarHeapSort(Delays, Highlights, Reads, Writes);
- Sort TournamentSort = new TournamentSort(Delays, Highlights, Reads, Writes);
-
- RunSelectionSorts.this.sortNumber = 1;
- RunSelectionSorts.this.sortCount = 10;
-
+ if(runAllActive) {
+ RunSelectionSorts.this.sortNumber = current;
+ RunSelectionSorts.this.sortCount = total;
+ }
+ else {
+ RunSelectionSorts.this.sortNumber = 1;
+ }
+
ArrayManager.toggleMutableLength(false);
ArrayVisualizer.setCategory("Selection Sorts");
- RunSelectionSorts.this.RunIndividualSort(SelectionSort, 0, array, 5);
- RunSelectionSorts.this.RunIndividualSort(DoubleSelectionSort, 0, array, 5);
- RunSelectionSorts.this.RunIndividualSort(CycleSort, 0, array, 3);
- RunSelectionSorts.this.RunIndividualSort(MaxHeapSort, 0, array, 1.25);
- RunSelectionSorts.this.RunIndividualSort(MinHeapSort, 0, array, 1.25);
- RunSelectionSorts.this.RunIndividualSort(WeakHeapSort, 0, array, 1.25);
- RunSelectionSorts.this.RunIndividualSort(TernaryHeapSort, 0, array, 1.25);
- RunSelectionSorts.this.RunIndividualSort(SmoothSort, 0, array, 2);
- RunSelectionSorts.this.RunIndividualSort(PoplarHeapSort, 0, array, 1);
- RunSelectionSorts.this.RunIndividualSort(TournamentSort, 0, array, 1.5);
+ RunSelectionSorts.this.executeSortList(array);
- ArrayVisualizer.setCategory("Run Selection Sorts");
- ArrayVisualizer.setHeading("Done");
+ if(!runAllActive) {
+ ArrayVisualizer.setCategory("Run Selection Sorts");
+ ArrayVisualizer.setHeading("Done");
+ }
ArrayManager.toggleMutableLength(true);
}
catch (Exception e) {
- e.printStackTrace();
+ JErrorPane.invokeErrorMessage(e);
}
Sounds.toggleSound(false);
ArrayVisualizer.setSortingThread(null);
}
});
-
ArrayVisualizer.runSortingThread();
}
}
\ No newline at end of file
diff --git a/src/utils/Delays.java b/src/utils/Delays.java
index 3c5e7be2..1d224c37 100644
--- a/src/utils/Delays.java
+++ b/src/utils/Delays.java
@@ -1,9 +1,14 @@
package utils;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import main.ArrayVisualizer;
+import templates.JErrorPane;
/*
*
@@ -37,19 +42,60 @@ final public class Delays {
private double addamt;
private double delay;
+ private double nanos;
- public Delays() {
+ private volatile double currentDelay;
+
+ private DecimalFormat formatter;
+ private DecimalFormatSymbols symbols;
+
+ private Sounds Sounds;
+
+ public Delays(ArrayVisualizer ArrayVisualizer) {
this.SLEEPRATIO = 1.0;
this.SKIPPED = false;
- this.addamt = 0.0;
+ this.addamt = 0;
+
+ this.formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ this.symbols = this.formatter.getDecimalFormatSymbols();
+
+ this.symbols.setGroupingSeparator(',');
+ this.formatter.setDecimalFormatSymbols(this.symbols);
+
+ this.Sounds = ArrayVisualizer.getSounds();
}
+ public String displayCurrentDelay() {
+ String currDelay = "";
+
+ if(this.currentDelay == 0 || this.SKIPPED) {
+ currDelay = "0";
+ }
+ else if(this.currentDelay < 0.001) {
+ currDelay = "< 0.001";
+ }
+ else {
+ currDelay = formatter.format(this.currentDelay);
+ }
+
+ return currDelay;
+ }
public double getCurrentDelay() {
- return this.delay;
+ return this.currentDelay;
}
public void setCurrentDelay(double value) {
this.delay = value;
}
+ public void updateCurrentDelay(double oldRatio, double newRatio) {
+ this.delay = (this.delay * oldRatio) / newRatio;
+ this.currentDelay = this.delay;
+ this.Sounds.changeNoteDelayAndFilter((int) this.currentDelay);
+ this.addamt = 0;
+
+ if(this.currentDelay < 0) {
+ this.delay = this.currentDelay = 0;
+ }
+ }
public double getSleepRatio() {
return this.SLEEPRATIO;
@@ -63,6 +109,7 @@ public boolean skipped() {
}
public void changeSkipped(boolean Bool) {
this.SKIPPED = Bool;
+ if(this.SKIPPED) this.Sounds.changeNoteDelayAndFilter(1);
}
public void sleep(double millis){
@@ -70,22 +117,26 @@ public void sleep(double millis){
return;
}
- this.delay = (millis * (1 / this.SLEEPRATIO));
- this.addamt += this.delay;
+ this.delay += (millis * (1 / this.SLEEPRATIO));
+ this.currentDelay = (millis * (1 / this.SLEEPRATIO));
- long amt = (long) this.delay;
- if(this.addamt >= 1){
- amt += (int) this.addamt;
- this.addamt -= (int) this.addamt;
- }
+ this.Sounds.changeNoteDelayAndFilter((int) this.currentDelay);
try {
// With this for loop, you can change the speed of sorts without waiting for the current delay to finish.
- for(int i = 0; i < amt / this.SLEEPRATIO; i++) {
- Thread.sleep(1);
+ if(!this.SKIPPED) {
+ while(this.delay >= 1) {
+ Thread.sleep(1);
+ this.delay--;
+ }
+ }
+ else {
+ this.delay = 0;
}
} catch(Exception ex) {
- Logger.getLogger(ArrayVisualizer.class.getName()).log(Level.SEVERE, null, ex);
+ JErrorPane.invokeErrorMessage(ex);
}
+
+ this.currentDelay = 0;
}
}
\ No newline at end of file
diff --git a/src/utils/Highlights.java b/src/utils/Highlights.java
index bd49cf86..0b16c65c 100644
--- a/src/utils/Highlights.java
+++ b/src/utils/Highlights.java
@@ -2,6 +2,8 @@
import java.util.Arrays;
+import main.ArrayVisualizer;
+
/*
*
MIT License
@@ -53,7 +55,11 @@ final public class Highlights {
private volatile boolean fancyFinish;
private volatile int trackFinish;
- public Highlights(int maximumLength) {
+ private ArrayVisualizer ArrayVisualizer;
+
+ public Highlights(ArrayVisualizer ArrayVisualizer, int maximumLength) {
+ this.ArrayVisualizer = ArrayVisualizer;
+
this.Highlights = new int[maximumLength];
this.FANCYFINISH = true;
this.maxIndexMarked = 0;
@@ -86,6 +92,11 @@ public void resetFancyFinish() {
this.trackFinish = -1; // Magic number that clears the green sweep animation
}
+ //TODO: Move Analysis to Highlights
+ public void toggleAnalysis(boolean Bool) {
+ this.ArrayVisualizer.toggleAnalysis(Bool);
+ }
+
public int getMaxIndex() {
return this.maxIndexMarked;
}
diff --git a/src/utils/Reads.java b/src/utils/Reads.java
index 2998f270..a2fa1c13 100644
--- a/src/utils/Reads.java
+++ b/src/utils/Reads.java
@@ -69,7 +69,7 @@ public void addComparison() {
this.comparisons++;
}
- public String getComparisons() {
+ public String displayComparisons() {
if(this.comparisons < 0) {
this.comparisons = Long.MIN_VALUE;
return "Over " + this.formatter.format(Long.MAX_VALUE);
@@ -80,18 +80,26 @@ public String getComparisons() {
}
}
+ public long getComparisons() {
+ return this.comparisons;
+ }
+
+ public void setComparisons(long value) {
+ this.comparisons = value;
+ }
+
public int compare(int left, int right) {
this.comparisons++;
int cmpVal = 0;
- if(Timer.timerEnabled()) Timer.startLap();
+ Timer.startLap();
if(left > right) cmpVal = 1;
else if(left < right) cmpVal = -1;
else cmpVal = 0;
- if(Timer.timerEnabled()) Timer.stopLap();
+ Timer.stopLap();
return cmpVal;
}
@@ -102,11 +110,11 @@ public int analyzeMax(int[] array, int length, double sleep, boolean mark) {
int max = 0;
for(int i = 0; i < length; i++) {
- if(Timer.timerEnabled()) Timer.startLap();
+ Timer.startLap();
if(array[i] > max) max = array[i];
- if(Timer.timerEnabled()) Timer.stopLap();
+ Timer.stopLap();
if(mark) {
Highlights.markArray(1, i);
@@ -125,12 +133,13 @@ public int analyzeMaxLog(int[] array, int length, int base, double sleep, boolea
int max = 0;
for(int i = 0; i < length; i++) {
- if(Timer.timerEnabled()) Timer.startLap();
-
int log = (int) (Math.log(array[i]) / Math.log(base));
+
+ Timer.startLap();
+
if(log > max) max = log;
- if(Timer.timerEnabled()) Timer.stopLap();
+ Timer.stopLap();
if(mark) {
Highlights.markArray(1, i);
@@ -150,20 +159,20 @@ public int analyzeBit(int[] array, int length) {
int max = 0;
for(int i = 0; i < length; i++) {
- if(Timer.timerEnabled()) Timer.startLap();
+ Timer.startLap();
max = Math.max(max, array[i]);
- if(Timer.timerEnabled()) Timer.stopLap();
+ Timer.stopLap();
Highlights.markArray(1, i);
Delays.sleep(0.75);
}
- if(Timer.timerEnabled()) Timer.startLap();
+ Timer.startLap();
int analysis = 31 - Integer.numberOfLeadingZeros(max);
- if(Timer.timerEnabled()) Timer.stopLap();
+ Timer.stopLap();
ArrayVisualizer.toggleAnalysis(false);
return analysis;
diff --git a/src/utils/Renderer.java b/src/utils/Renderer.java
index b0d33926..a46fa377 100644
--- a/src/utils/Renderer.java
+++ b/src/utils/Renderer.java
@@ -1,15 +1,8 @@
package utils;
import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics2D;
import main.ArrayVisualizer;
-import visuals.Bars;
-import visuals.Circular;
-import visuals.Hoops;
-import visuals.Mesh;
-import visuals.Pixels;
import visuals.VisualStyles;
/*
@@ -38,6 +31,8 @@ of this software and associated documentation files (the "Software"), to deal
*
*/
+// TODO: Many of these methods should exist solely in visual classes
+
final class WindowState {
private boolean windowUpdated;
private boolean windowResized;
@@ -57,12 +52,6 @@ public boolean resized() {
}
final public class Renderer {
- private Bars Bars;
- private Circular Circular;
- private Hoops Hoops;
- private Mesh Mesh;
- private Pixels Pixels;
-
private volatile double xscl; //TODO: Change to xScale/yScale
private volatile double yscl;
@@ -71,8 +60,6 @@ final public class Renderer {
private int linkedpixdrawx; //TODO: Change names
private int linkedpixdrawy;
- private int frames;
-
private int doth; //TODO: Change names
private int dotw;
private int dots; //TODO: Change name to dotDims/dotDimensions
@@ -118,27 +105,24 @@ public void setLineY(int y) {
this.linkedpixdrawy = y;
}
- public void updateGraphics(ArrayVisualizer ArrayVisualizer) {
+ public static void createRenders(ArrayVisualizer ArrayVisualizer) {
ArrayVisualizer.createVolatileImage();
ArrayVisualizer.setMainRender();
ArrayVisualizer.setExtraRender();
}
- public void initializeVisuals(ArrayVisualizer ArrayVisualizer, VisualStyles VisualStyles) {
- this.Bars = new Bars();
- this.Circular = new Circular();
- this.Hoops = new Hoops();
- this.Mesh = new Mesh();
- this.Pixels = new Pixels();
-
- this.frames = 0;
- this.updateGraphics(ArrayVisualizer);
+ public static void initializeVisuals(ArrayVisualizer ArrayVisualizer) {
+ Renderer.createRenders(ArrayVisualizer);
ArrayVisualizer.updateFontSize();
ArrayVisualizer.repositionFrames();
}
+ public static void updateGraphics(ArrayVisualizer ArrayVisualizer) {
+ Renderer.createRenders(ArrayVisualizer);
+ ArrayVisualizer.updateVisuals();
+ }
- private WindowState checkWindowResizeAndReposition(ArrayVisualizer ArrayVisualizer) {
+ private static WindowState checkWindowResizeAndReposition(ArrayVisualizer ArrayVisualizer) {
boolean windowUpdate = false;
boolean windowResize = false;
@@ -174,7 +158,7 @@ public void updateVisuals(ArrayVisualizer ArrayVisualizer) {
if(WindowState.resized()) {
ArrayVisualizer.updateDimensions();
- this.updateGraphics(ArrayVisualizer);
+ updateGraphics(ArrayVisualizer);
}
ArrayVisualizer.updateFontSize();
@@ -193,8 +177,6 @@ public void updateVisuals(ArrayVisualizer ArrayVisualizer) {
this.linkedpixdrawx = 0;
this.linkedpixdrawy = 0;
- this.frames++;
-
this.dotw = (int) (2 * (ArrayVisualizer.currentWidth() / 640.0));
this.doth = (int) (2 * (ArrayVisualizer.currentHeight() / 480.0));
this.dots = (this.dotw + this.doth) / 2; //TODO: Does multiply/divide by 2 like this cancel out??
@@ -202,177 +184,7 @@ public void updateVisuals(ArrayVisualizer ArrayVisualizer) {
ArrayVisualizer.resetMainStroke();
}
- public Color getIntColor(int i, int length) {
- return Color.getHSBColor(((float) i / length), 1.0F, 0.8F);
- }
-
- public void markBar(Graphics2D bar, boolean color, boolean rainbow, boolean analysis) {
- if(color || rainbow) {
- if(analysis) bar.setColor(Color.WHITE);
- else bar.setColor(Color.BLACK);
- }
- else if(analysis) bar.setColor(Color.BLUE);
- else bar.setColor(Color.RED);
- }
- private void markBarFancy(Graphics2D bar, boolean color, boolean rainbow) {
- if(!color && !rainbow) bar.setColor(Color.RED);
- else bar.setColor(Color.BLACK);
- }
-
- public void lineMark(Graphics2D line, double width, boolean color, boolean analysis) {
- line.setStroke(new BasicStroke((float) (9f * (width / 1280f))));
- if(color) line.setColor(Color.BLACK);
- else if(analysis) line.setColor(Color.BLUE);
- else line.setColor(Color.RED);
- }
- //TODO: Change name to markLineFancy
- public void lineFancy(Graphics2D line, double width) {
- line.setColor(Color.GREEN);
- line.setStroke(new BasicStroke((float) (9f * (width / 1280f))));
- }
- //TODO: Change name to clearLine
- public void lineClear(Graphics2D line, boolean color, int[] array, int i, int length, double width) {
- if(color) line.setColor(getIntColor(array[i], length));
- else line.setColor(Color.WHITE);
- line.setStroke(new BasicStroke((float) (3f * (width / 1280f))));
- }
-
- public void setRectColor(Graphics2D rect, boolean color, boolean analysis) {
- if(color) rect.setColor(Color.WHITE);
- else if(analysis) rect.setColor(Color.BLUE);
- else rect.setColor(Color.RED);
- }
-
- @SuppressWarnings("fallthrough")
- //The longer the array length, the more bars marked. Makes the visual easier to see when bars are thinner.
- public void colorMarkedBars(int logOfLen, int index, Highlights Highlights, Graphics2D mainRender, boolean colorEnabled, boolean rainbowEnabled, boolean analysis) {
- switch(logOfLen) {
- case 12: if(Highlights.containsPosition(index - 3)) markBar(mainRender, colorEnabled, rainbowEnabled, analysis);
- case 11: if(Highlights.containsPosition(index - 2)) markBar(mainRender, colorEnabled, rainbowEnabled, analysis);
- case 10: if(Highlights.containsPosition(index - 1)) markBar(mainRender, colorEnabled, rainbowEnabled, analysis);
- default: if(Highlights.containsPosition(index)) markBar(mainRender, colorEnabled, rainbowEnabled, analysis);
- }
- }
-
- @SuppressWarnings("fallthrough")
- public void markHoops(int logOfLen, int index, Highlights Highlights, Graphics2D mainRender) {
- switch(logOfLen) {
- case 12: if(Highlights.containsPosition(index - 11)) mainRender.setColor(Color.BLACK);
- case 11: if(Highlights.containsPosition(index - 10)) mainRender.setColor(Color.BLACK);
- case 10: if(Highlights.containsPosition(index - 9)) mainRender.setColor(Color.BLACK);
- case 9: if(Highlights.containsPosition(index - 8)) mainRender.setColor(Color.BLACK);
- case 8: if(Highlights.containsPosition(index - 7)) mainRender.setColor(Color.BLACK);
- case 7: if(Highlights.containsPosition(index - 6)) mainRender.setColor(Color.BLACK);
- case 6: if(Highlights.containsPosition(index - 5)) mainRender.setColor(Color.BLACK);
- case 5: if(Highlights.containsPosition(index - 4)) mainRender.setColor(Color.BLACK);
- case 4: if(Highlights.containsPosition(index - 3)) mainRender.setColor(Color.BLACK);
- case 3: if(Highlights.containsPosition(index - 2)) mainRender.setColor(Color.BLACK);
- case 2: if(Highlights.containsPosition(index - 1)) mainRender.setColor(Color.BLACK);
- default: if(Highlights.containsPosition(index)) mainRender.setColor(Color.BLACK);
- }
- }
-
- @SuppressWarnings("fallthrough")
- public void drawFancyFinish(int logOfLen, int index, int position, Graphics2D mainRender, boolean colorEnabled, boolean rainbowEnabled) {
- switch(logOfLen) {
- case 12: if(index == position - 11) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
- case 11: if(index == position - 10) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
- case 10: if(index == position - 9) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
- case 9: if(index == position - 8) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
- case 8: if(index == position - 7) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
- case 7: if(index == position - 6) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
- case 6: if(index == position - 5) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
- case 5: if(index == position - 4) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
- case 4: if(index == position - 3) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
- case 3: if(index == position - 2) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
- case 2: if(index == position - 1) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
- default: if(index == position) markBarFancy(mainRender, colorEnabled, rainbowEnabled);
- }
- }
-
- @SuppressWarnings("fallthrough")
- public void drawFancyFinishLine(int logOfLen, int index, int position, Graphics2D mainRender, double width, boolean colorEnabled) {
- switch(logOfLen) {
- case 12: if(index == position - 11) lineMark(mainRender, width, colorEnabled, false);
- case 11: if(index == position - 10) lineMark(mainRender, width, colorEnabled, false);
- case 10: if(index == position - 9) lineMark(mainRender, width, colorEnabled, false);
- case 9: if(index == position - 8) lineMark(mainRender, width, colorEnabled, false);
- case 8: if(index == position - 7) lineMark(mainRender, width, colorEnabled, false);
- case 7: if(index == position - 6) lineMark(mainRender, width, colorEnabled, false);
- case 6: if(index == position - 5) lineMark(mainRender, width, colorEnabled, false);
- case 5: if(index == position - 4) lineMark(mainRender, width, colorEnabled, false);
- case 4: if(index == position - 3) lineMark(mainRender, width, colorEnabled, false);
- case 3: if(index == position - 2) lineMark(mainRender, width, colorEnabled, false);
- case 2: if(index == position - 1) lineMark(mainRender, width, colorEnabled, false);
- default: if(index == position) lineMark(mainRender, width, colorEnabled, false);
- }
- }
-
- @SuppressWarnings("fallthrough")
- public void drawFancyFinishHoops(int logOfLen, int index, int position, Graphics2D mainRender) {
- switch(logOfLen) {
- case 12: if(index == position - 11) mainRender.setColor(Color.BLACK);
- case 11: if(index == position - 10) mainRender.setColor(Color.BLACK);
- case 10: if(index == position - 9) mainRender.setColor(Color.BLACK);
- case 9: if(index == position - 8) mainRender.setColor(Color.BLACK);
- case 8: if(index == position - 7) mainRender.setColor(Color.BLACK);
- case 7: if(index == position - 6) mainRender.setColor(Color.BLACK);
- case 6: if(index == position - 5) mainRender.setColor(Color.BLACK);
- case 5: if(index == position - 4) mainRender.setColor(Color.BLACK);
- case 4: if(index == position - 3) mainRender.setColor(Color.BLACK);
- case 3: if(index == position - 2) mainRender.setColor(Color.BLACK);
- case 2: if(index == position - 1) mainRender.setColor(Color.BLACK);
- default: if(index == position) mainRender.setColor(Color.BLACK);
- }
- }
-
- public int getTriangleHeight(int length, double height) {
- switch(length) {
- case 2: height *= 20; break;
- case 4: height *= 13; break;
- case 8: height *= 8; break;
- case 16:
- case 32: height *= 4.4; break;
- case 64: height *= 2.3; break;
- case 128: height *= 2.35; break;
- case 256: height *= 1.22; break;
- default: height *= 1;
- }
-
- return (int) height;
- }
-
- public int getTrianglesPerRow(int length, int trianglesPerColumn) {
- int trianglesPerRow;
-
- switch(length) {
- case 32:
- case 64: trianglesPerRow = 4; break;
- case 128:
- case 256: trianglesPerRow = 8; break;
- default: trianglesPerRow = Math.max(length / trianglesPerColumn, 2);
- }
-
- return trianglesPerRow;
- }
-
- public void drawCircle(int[] array, ArrayVisualizer ArrayVisualizer, Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights) {
- Circular.drawVisual(array, ArrayVisualizer, this, mainRender, extraRender, Highlights);
- }
- public void drawHoops(int[] array, ArrayVisualizer ArrayVisualizer, Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights) {
- Hoops.drawVisual(array, ArrayVisualizer, this, mainRender, extraRender, Highlights);
- }
- public void drawMesh(int[] array, ArrayVisualizer ArrayVisualizer, Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights) {
- Mesh.drawVisual(array, ArrayVisualizer, this, mainRender, extraRender, Highlights);
- }
- public void drawBars(int[] array, ArrayVisualizer ArrayVisualizer, Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights) {
- Bars.drawVisual(array, ArrayVisualizer, this, mainRender, extraRender, Highlights);
- }
- public void drawPixels(int[] array, ArrayVisualizer ArrayVisualizer, Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights) {
- Pixels.drawVisual(array, ArrayVisualizer, this, mainRender, extraRender, Highlights);
- }
-
- public void drawVisual(VisualStyles VisualStyles, int[] array, ArrayVisualizer ArrayVisualizer, Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights) {
- VisualStyles.drawVisual(array, ArrayVisualizer, this, mainRender, extraRender, Highlights);
+ public void drawVisual(VisualStyles VisualStyles, int[] array, ArrayVisualizer ArrayVisualizer, Highlights Highlights) {
+ VisualStyles.drawVisual(array, ArrayVisualizer, this, Highlights);
}
}
\ No newline at end of file
diff --git a/src/utils/Shuffles.java b/src/utils/Shuffles.java
index c81f9d08..1e3e6e9e 100644
--- a/src/utils/Shuffles.java
+++ b/src/utils/Shuffles.java
@@ -30,12 +30,18 @@ of this software and associated documentation files (the "Software"), to deal
public enum Shuffles {
RANDOM {
+ // If you want to learn why the random shuffle was changed,
+ // I highly encourage you read this. It's quite fascinating:
+ // http://datagenetics.com/blog/november42014/index.html
+
@Override
public void shuffleArray(int[] array, ArrayVisualizer ArrayVisualizer, Delays Delays, Highlights Highlights, Writes Writes) {
int currentLen = ArrayVisualizer.getCurrentLength();
+ //TODO: Consider separate method
for(int i = 0; i < currentLen; i++){
- Writes.swap(array, i, (int)(Math.random()*currentLen), 0, true, false);
+ int randomIndex = (int) (Math.random() * (currentLen - i)) + i;
+ Writes.swap(array, i, randomIndex, 0, true, false);
if(ArrayVisualizer.shuffleEnabled()) Delays.sleep(1);
}
@@ -70,7 +76,8 @@ public void shuffleArray(int[] array, ArrayVisualizer ArrayVisualizer, Delays De
if(ArrayVisualizer.shuffleEnabled()) Delays.sleep(1);
}
for(int i = 0; i < currentLen; i++){
- Writes.swap(array, i, (int)(Math.random()*currentLen), 0, true, false);
+ int randomIndex = (int) (Math.random() * (currentLen - i)) + i;
+ Writes.swap(array, i, randomIndex, 0, true, false);
if(ArrayVisualizer.shuffleEnabled()) Delays.sleep(1);
}
@@ -83,9 +90,22 @@ public void shuffleArray(int[] array, ArrayVisualizer ArrayVisualizer, Delays De
for(int i = 0; i < Math.max(currentLen / 20, 1); i++){
Writes.swap(array, (int)(Math.random()*currentLen), (int)(Math.random()*currentLen), 0, true, false);
-
if(ArrayVisualizer.shuffleEnabled()) Delays.sleep(2);
}
+
+ /*
+ int step = (int) Math.sqrt(currentLen);
+
+ //TODO: *Strongly* consider randomSwap method
+ for(int i = 0; i < currentLen; i += step){
+ int randomIndex = (int) (Math.random() * step);
+ randomIndex = Math.max(randomIndex, 1);
+ randomIndex = Math.min(randomIndex, currentLen - i - 1);
+ Writes.swap(array, i, i + randomIndex, 0, true, false);
+
+ if(ArrayVisualizer.shuffleEnabled()) Delays.sleep(2);
+ }
+ */
}
},
ALREADY {
diff --git a/src/utils/Sounds.java b/src/utils/Sounds.java
index fcc76164..3f5c27a0 100644
--- a/src/utils/Sounds.java
+++ b/src/utils/Sounds.java
@@ -1,9 +1,7 @@
package utils;
-import java.io.File;
-import java.io.IOException;
+import java.io.InputStream;
-import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
@@ -11,6 +9,9 @@
import javax.swing.JOptionPane;
import main.ArrayVisualizer;
+import soundfont.SFXFetcher;
+import soundfont.SFXFetcher;
+import templates.JErrorPane;
/*
*
@@ -50,12 +51,15 @@ final public class Sounds {
private Synthesizer synth;
private MidiChannel[] channels;
+ private volatile int noteDelay;
+
private volatile boolean SOUND;
private boolean MIDI;
private int NUMCHANNELS; //Number of Audio Channels
private double PITCHMIN; //Minimum Pitch
private double PITCHMAX; //Maximum Pitch
private double SOUNDMUL;
+ private boolean SOFTERSOUNDS;
final private int REVERB = 91;
@@ -71,24 +75,35 @@ public Sounds(int[] array, ArrayVisualizer arrayVisualizer) {
this.PITCHMAX = 105d;
this.SOUNDMUL = 1d;
+ this.noteDelay = 1;
+
try {
MidiSystem.getSequencer(false);
this.synth = MidiSystem.getSynthesizer();
this.synth.open();
} catch (MidiUnavailableException e) {
- JOptionPane.showMessageDialog(null, "The MIDI device is unavailable, possibly because it is already being used by another application. Sound is disabled.");
- e.printStackTrace();
+ JOptionPane.showMessageDialog(null, e.getMessage() + ": The MIDI device is unavailable, possibly because it is already being used by another application. Sound is disabled.");
}
+ SFXFetcher sfxFetcher = new SFXFetcher();
+ InputStream stream = sfxFetcher.getSFXFile();
try {
- this.synth.loadAllInstruments(MidiSystem.getSoundbank(new File("soundfont/sfx.dls")));
- } catch (InvalidMidiDataException | IOException e1) {
- e1.printStackTrace();
+ this.synth.loadAllInstruments(MidiSystem.getSoundbank(stream));
+ } catch (Exception e) {
+ JErrorPane.invokeErrorMessage(e);
+ }
+ finally {
+ try {
+ stream.close();
+ } catch (Exception e) {
+ JErrorPane.invokeErrorMessage(e);
+ }
}
this.channels = new MidiChannel[this.NUMCHANNELS];
for(int i = 0; i < this.NUMCHANNELS; i++) {
this.channels[i] = this.synth.getChannels()[i];
+ //this.channels[i].programChange(this.synth.getLoadedInstruments()[197].getPatch().getProgram());
this.channels[i].programChange(this.synth.getLoadedInstruments()[16].getPatch().getProgram()); // MIDI Instrument 16 is a Rock Organ.
this.channels[i].setChannelPressure(1);
}
@@ -103,7 +118,7 @@ public void run() {
for(MidiChannel channel : channels) {
channel.allNotesOff();
}
- if(SOUND == false || MIDI == false) {
+ if(SOUND == false || MIDI == false || JErrorPane.errorMessageActive) {
continue;
}
@@ -129,19 +144,21 @@ public void run() {
channels[voice].noteOn(pitchmajor, vel);
channels[voice].setPitchBend(pitchminor);
channels[voice].controlChange(REVERB, 10);
-
+
if((++voice % Math.max(noteCount, 1)) == 0)
break;
}
}
catch (Exception e) {
- e.printStackTrace();
+ JErrorPane.invokeErrorMessage(e);
}
}
try {
- sleep(1);
+ for(int i = 0; i < Sounds.this.noteDelay; i++) {
+ sleep(1);
+ }
} catch(Exception e) {
- e.printStackTrace();
+ JErrorPane.invokeErrorMessage(e);
}
}
}
@@ -156,6 +173,14 @@ public synchronized void toggleSound(boolean val) {
this.MIDI = val;
}
+ //Double check logic
+ public void toggleSofterSounds(boolean val) {
+ this.SOFTERSOUNDS = val;
+
+ if(this.SOFTERSOUNDS) this.SOUNDMUL = 0.01;
+ else this.SOUNDMUL = 1;
+ }
+
public double getVolume() {
return this.SOUNDMUL;
}
@@ -163,6 +188,22 @@ public void changeVolume(double val) {
this.SOUNDMUL = val;
}
+ public void changeNoteDelayAndFilter(int noteFactor) {
+ if(noteFactor != this.noteDelay) {
+ if(noteFactor > 1) {
+ this.noteDelay = noteFactor;
+ this.SOUNDMUL = 1d / noteFactor;
+ }
+ //Double check logic
+ else {
+ this.noteDelay = 1;
+
+ if(this.SOFTERSOUNDS) this.SOUNDMUL = 0.01;
+ else this.SOUNDMUL = 1;
+ }
+ }
+ }
+
public void startAudioThread() {
AudioThread.start();
}
diff --git a/src/utils/Timer.java b/src/utils/Timer.java
index 05e795f5..d3882007 100644
--- a/src/utils/Timer.java
+++ b/src/utils/Timer.java
@@ -82,10 +82,10 @@ else if(this.realTimer == 0) {
if(this.timerEnabled) return "0.000ms";
else return "---ms";
}
- else if(this.realTimer < 0.001) return "<0.001ms";
- else if(this.realTimer >= 60000.000) return this.formatter.format((int) (this.realTimer / 60000)) + "m" + (int) ((this.realTimer % 60000) / 1000) + "s";
- else if(this.realTimer >= 1000.000) return this.formatter.format(this.realTimer / 1000) + "s";
- else return this.formatter.format(this.realTimer) + "ms";
+ else if(this.realTimer < 0.001) return "< 0.001ms";
+ else if(this.realTimer >= 60000.000) return "~" + this.formatter.format((int) (this.realTimer / 60000)) + "m" + (int) ((this.realTimer % 60000) / 1000) + "s";
+ else if(this.realTimer >= 1000.000) return "~" + this.formatter.format(this.realTimer / 1000) + "s";
+ else return "~" + this.formatter.format(this.realTimer) + "ms";
}
public void toggleRealTimer(boolean Bool) {
@@ -107,12 +107,12 @@ public boolean timerEnabled() {
}
public void startLap() {
- this.timeStart = System.nanoTime();
+ if(this.timerEnabled) this.timeStart = System.nanoTime();
}
public void stopLap() {
this.timeStop = System.nanoTime();
- this.realTimer += (timeStop - timeStart) / 1e+6;
+ if(this.timerEnabled) this.realTimer += (timeStop - timeStart) * 1e-6d;
}
void manualAddTime(long milliseconds) {
diff --git a/src/utils/Writes.java b/src/utils/Writes.java
index 5032cefe..09bf7712 100644
--- a/src/utils/Writes.java
+++ b/src/utils/Writes.java
@@ -104,8 +104,8 @@ public String getTempWrites() {
return "Over " + this.formatter.format(Long.MAX_VALUE);
}
else {
- if(this.tempWrites == 1) return this.tempWrites + " Write to Auxillary Array(s)";
- else return this.formatter.format(this.tempWrites) + " Writes to Auxillary Array(s)";
+ if(this.tempWrites == 1) return this.tempWrites + " Write to Auxiliary Array(s)";
+ else return this.formatter.format(this.tempWrites) + " Writes to Auxiliary Array(s)";
}
}
@@ -142,13 +142,13 @@ private void markSwap(int a, int b) {
public void swap(int[] array, int a, int b, double pause, boolean mark, boolean auxwrite) {
if(mark) this.markSwap(a, b);
- if(Timer.timerEnabled()) Timer.startLap();
+ Timer.startLap();
int temp = array[a];
array[a] = array[b];
array[b] = temp;
- if(Timer.timerEnabled()) Timer.stopLap();
+ Timer.stopLap();
this.updateSwap(auxwrite);
Delays.sleep(pause);
@@ -183,11 +183,11 @@ public void write(int[] array, int at, int equals, double pause, boolean mark, b
if(auxwrite) tempWrites++;
else writes++;
- if(Timer.timerEnabled()) Timer.startLap();
+ Timer.startLap();
array[at] = equals;
- if(Timer.timerEnabled()) Timer.stopLap();
+ Timer.stopLap();
Delays.sleep(pause);
}
@@ -198,11 +198,11 @@ public void multiDimWrite(int[][] array, int x, int y, int equals, double pause,
if(auxwrite) tempWrites++;
else writes++;
- if(Timer.timerEnabled()) Timer.startLap();
+ Timer.startLap();
array[x][y] = equals;
- if(Timer.timerEnabled()) Timer.stopLap();
+ Timer.stopLap();
Delays.sleep(pause);
}
@@ -213,11 +213,11 @@ public void mockWrite(int length, int pos, int val, double pause) {
this.tempWrites++;
- if(Timer.timerEnabled()) Timer.startLap();
+ Timer.startLap();
mockArray[pos] = val;
- if(Timer.timerEnabled()) Timer.stopLap();
+ Timer.stopLap();
Delays.sleep(pause);
}
@@ -234,7 +234,7 @@ public void transcribe(int[] array, ArrayList[] registers, int start, b
}
}
- public void transcribeMSD(int[] array, ArrayList[] registers, int start, int min, boolean mark, boolean auxwrite) {
+ public void transcribeMSD(int[] array, ArrayList[] registers, int start, int min, double sleep, boolean mark, boolean auxwrite) {
int total = start;
int temp = 0;
@@ -245,12 +245,12 @@ public void transcribeMSD(int[] array, ArrayList[] registers, int start
for(int index = registers.length - 1; index >= 0; index--) {
for(int i = registers[index].size() - 1; i >= 0; i--) {
this.write(array, total + min - temp++ - 1, registers[index].get(i), 0, mark, auxwrite);
- if(mark) Delays.sleep(1 + (2 / registers[index].size()));
+ if(mark) Delays.sleep(sleep);
}
}
}
- public void fancyTranscribe(int[] array, int length, ArrayList[] registers) {
+ public void fancyTranscribe(int[] array, int length, ArrayList[] registers, double sleep) {
int[] tempArray = new int[length];
boolean[] tempWrite = new boolean[length];
int radix = registers.length;
@@ -260,7 +260,7 @@ public void fancyTranscribe(int[] array, int length, ArrayList[] regist
for(int i = 0; i < length; i++) {
int register = i % radix;
- int pos = (int) ((register * (length / radix)) + (i / radix));
+ int pos = (register * (length / radix)) + (i / radix);
if(!tempWrite[pos]) {
this.write(array, pos, tempArray[pos], 0, false, false);
@@ -268,7 +268,7 @@ public void fancyTranscribe(int[] array, int length, ArrayList[] regist
}
Highlights.markArray(register, pos);
- if(register == 0) Delays.sleep(radix);
+ if(register == 0) Delays.sleep(sleep);
}
for(int i = 0; i < length; i++) {
if(!tempWrite[i]){
@@ -282,23 +282,24 @@ public void fancyTranscribe(int[] array, int length, ArrayList[] regist
//Methods mocking System.arraycopy (reversearraycopy is for TimSort's MergeHi and BinaryInsert, and WikiSort's Rotate)
public void arraycopy(int[] src, int srcPos, int[] dest, int destPos, int length, double sleep, boolean mark, boolean temp) {
for(int i = 0; i < length; i++) {
- this.write(dest, destPos + i, src[srcPos + i], sleep, false, temp);
-
if(mark) {
if(temp) Highlights.markArray(1, srcPos + i);
else Highlights.markArray(1, destPos + i);
}
+
+ //TODO: Handle order of Delays in write method better
+ this.write(dest, destPos + i, src[srcPos + i], sleep, false, temp);
}
}
public void reversearraycopy(int[] src, int srcPos, int[] dest, int destPos, int length, double sleep, boolean mark, boolean temp) {
for(int i = length - 1; i >= 0; i--) {
- this.write(dest, destPos + i, src[srcPos + i], sleep, false, temp);
-
if(mark) {
if(temp) Highlights.markArray(1, srcPos + i);
else Highlights.markArray(1, destPos + i);
}
+
+ this.write(dest, destPos + i, src[srcPos + i], sleep, false, temp);
}
}
diff --git a/src/visuals/Bars.java b/src/visuals/Bars.java
index bae63e73..eb4a9ee2 100644
--- a/src/visuals/Bars.java
+++ b/src/visuals/Bars.java
@@ -1,9 +1,9 @@
package visuals;
import java.awt.Color;
-import java.awt.Graphics2D;
import main.ArrayVisualizer;
+import templates.Visual;
import utils.Highlights;
import utils.Renderer;
@@ -33,47 +33,83 @@ of this software and associated documentation files (the "Software"), to deal
*
*/
-final public class Bars {
- public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights) {
+final public class Bars extends Visual {
+ public Bars(ArrayVisualizer ArrayVisualizer) {
+ super(ArrayVisualizer);
+ }
+
+ @Override
+ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) {
for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++){
if(Highlights.fancyFinishActive()) {
if(i < Highlights.getFancyFinishPosition()) {
- mainRender.setColor(Color.GREEN);
+ this.mainRender.setColor(Color.GREEN);
}
else if(ArrayVisualizer.rainbowEnabled() || ArrayVisualizer.colorEnabled()) {
- mainRender.setColor(Renderer.getIntColor(array[i], ArrayVisualizer.getCurrentLength()));
+ this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength()));
}
- else mainRender.setColor(Color.WHITE);
+ else this.mainRender.setColor(Color.WHITE);
- Renderer.drawFancyFinish(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), mainRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.rainbowEnabled());
+ drawFancyFinish(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.rainbowEnabled());
}
else {
if(ArrayVisualizer.rainbowEnabled() || ArrayVisualizer.colorEnabled()) {
- mainRender.setColor(Renderer.getIntColor(array[i], ArrayVisualizer.getCurrentLength()));
+ this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength()));
}
- else mainRender.setColor(Color.WHITE);
+ else this.mainRender.setColor(Color.WHITE);
if(ArrayVisualizer.getCurrentLength() != 2) {
- Renderer.colorMarkedBars(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights, mainRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.analysisEnabled());
+ colorMarkedBars(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights, this.mainRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.analysisEnabled());
}
}
-
+ /*
+ int markHeight = 0;
+ Color currentColor = mainRender.getColor();
+ if(currentColor == Color.BLACK || currentColor == Color.RED || currentColor == Color.BLUE) {
+ markHeight = 5;
+ }
+ */
+
int y = 0;
int width = (int) (Renderer.getXScale() * (i + 1)) - Renderer.getOffset();
if(ArrayVisualizer.rainbowEnabled()) {
if(width > 0) {
- mainRender.fillRect(Renderer.getOffset() + 20, 0, width, ArrayVisualizer.windowHeight());
+ this.mainRender.fillRect(Renderer.getOffset() + 20, 0, width, ArrayVisualizer.windowHeight());
}
Renderer.setOffset(Renderer.getOffset() + width);
}
+ else if(ArrayVisualizer.waveEnabled()) {
+ if(width > 0) {
+ y = (int) ((ArrayVisualizer.windowHeight() / 4) * Math.sin((2 * Math.PI * ((double) array[i] / ArrayVisualizer.getCurrentLength()))) + ArrayVisualizer.windowHalfHeight());
+ this.mainRender.fillRect(Renderer.getOffset() + 20, y, width, 20);
+ }
+ Renderer.setOffset(Renderer.getOffset() + width);
+ }
else {
if(width > 0) {
- y = (int) (((ArrayVisualizer.windowHeight() - 20)) - array[i] * Renderer.getYScale());
- mainRender.fillRect(Renderer.getOffset() + 20, y, width, (int) Math.max(array[i] * Renderer.getYScale(), 1));
+ /*
+ int gap = 0;
+ if(width > 5) {
+ gap = 5;
+ }
+ */
+
+ y = (int) (((ArrayVisualizer.windowHeight() - 20)) - (array[i] + 1) * Renderer.getYScale());
+ mainRender.fillRect(Renderer.getOffset() + 20, y, width, (int) ((array[i] + 1) * Renderer.getYScale()));
+
+ //mainRender.fillRect(Renderer.getOffset() + 20, y /*- markHeight*/, width /*- gap*/, (int) ((array[i] + 1) * Renderer.getYScale()) /*+ markHeight*/);
+
+ /*
+ double thickness = 1;
+ Stroke oldStroke = mainRender.getStroke();
+ mainRender.setStroke(new BasicStroke((float) thickness));
+ mainRender.setColor(Color.BLACK);
+ mainRender.drawLine(Renderer.getOffset() + 20, y, Renderer.getOffset() + 20, (int) Math.max(array[i] * Renderer.getYScale()-1, 1) + y);
+ mainRender.setStroke(oldStroke);
+ */
}
-
Renderer.setOffset(Renderer.getOffset() + width);
}
}
diff --git a/src/visuals/Circular.java b/src/visuals/Circular.java
index 49eb5050..753a4d96 100644
--- a/src/visuals/Circular.java
+++ b/src/visuals/Circular.java
@@ -2,10 +2,10 @@
import java.awt.BasicStroke;
import java.awt.Color;
-import java.awt.Graphics2D;
import java.awt.Polygon;
import main.ArrayVisualizer;
+import templates.Visual;
import utils.Highlights;
import utils.Renderer;
@@ -35,11 +35,13 @@ of this software and associated documentation files (the "Software"), to deal
*
*/
-final public class Circular {
- final private double CIRC_HEIGHT_RATIO = (9/6.0843731432) * (16/9d);
- final private double CIRC_WIDTH_RATIO = (16/6.0843731432) * (16/9d);
+final public class Circular extends Visual {
+ final private static double CIRC_HEIGHT_RATIO = (9/6.0843731432) * (16/9d);
+ final private static double CIRC_WIDTH_RATIO = (16/6.0843731432) * (16/9d);
- private boolean drawRect;
+ public Circular(ArrayVisualizer ArrayVisualizer) {
+ super(ArrayVisualizer);
+ }
// The reason we use cosine with height (expressed in terms of y) and sine with width (expressed in terms of x) is because our circles are rotated 90 degrees.
// After that rotation, sine is on the x-axis and cosine is on the y-axis.
@@ -55,27 +57,29 @@ private static double getCosOfDegrees(double d, int halfCirc) {
return Math.cos((d * Math.PI) / halfCirc);
}
- public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights) {
+ @Override
+ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) {
for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++){
if(i < Highlights.getFancyFinishPosition()) {
- mainRender.setColor(Color.getHSBColor((1f/3f), 1f, 0.8f));
+ this.mainRender.setColor(Color.getHSBColor((1f/3f), 1f, 0.8f));
}
else if(!ArrayVisualizer.colorEnabled() && (ArrayVisualizer.spiralEnabled() || ArrayVisualizer.distanceEnabled() || ArrayVisualizer.pixelsEnabled())) {
- mainRender.setColor(Color.WHITE);
+ this.mainRender.setColor(Color.WHITE);
}
- else mainRender.setColor(Renderer.getIntColor(array[i], ArrayVisualizer.getCurrentLength()));
+ else this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength()));
if(Highlights.fancyFinishActive()) {
- Renderer.drawFancyFinish(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), mainRender, ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.colorEnabled());
+ drawFancyFinish(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.colorEnabled());
}
else {
+ /*
if(ArrayVisualizer.pointerActive()) {
if(Highlights.containsPosition(i)) {
if(ArrayVisualizer.analysisEnabled()) {
- extraRender.setColor(Color.GRAY);
+ this.extraRender.setColor(Color.GRAY);
}
else {
- extraRender.setColor(Color.WHITE);
+ this.extraRender.setColor(Color.WHITE);
}
//Create new Polygon for the pointer
@@ -114,14 +118,14 @@ else if(!ArrayVisualizer.colorEnabled() && (ArrayVisualizer.spiralEnabled() || A
pointer.addPoint(pointerXValues[j], pointerYValues[j]);
}
- extraRender.fillPolygon(pointer);
+ this.extraRender.fillPolygon(pointer);
}
}
- else if(ArrayVisualizer.getCurrentLength() != 2){
- Renderer.colorMarkedBars(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights, mainRender, ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled());
+ else */ if(ArrayVisualizer.getCurrentLength() != 2){
+ colorMarkedBars(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights, this.mainRender, ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled());
}
}
-
+
if(ArrayVisualizer.distanceEnabled()) {
//TODO: Rewrite this abomination
double len = ((ArrayVisualizer.getCurrentLength() / 2d) - Math.min(Math.min(Math.abs(i - array[i]), Math.abs(i - array[i] + ArrayVisualizer.getCurrentLength())), Math.abs(i - array[i] - ArrayVisualizer.getCurrentLength()))) / (ArrayVisualizer.getCurrentLength() / 2d);
@@ -134,43 +138,43 @@ else if(ArrayVisualizer.getCurrentLength() != 2){
if(i > 0) {
if(Highlights.fancyFinishActive()) {
if(i < Highlights.getFancyFinishPosition()) {
- Renderer.lineFancy(mainRender, ArrayVisualizer.currentWidth());
+ lineFancy(this.mainRender, ArrayVisualizer.currentWidth());
}
else {
- Renderer.lineClear(mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth());
+ lineClear(this.mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth());
}
- Renderer.drawFancyFinishLine(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled());
+ drawFancyFinishLine(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled());
}
else {
if(Highlights.containsPosition(i)) {
- Renderer.lineMark(mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled());
+ lineMark(this.mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled());
}
- else Renderer.lineClear(mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth());
+ else lineClear(this.mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth());
}
- mainRender.drawLine(linkedpixX, linkedpixY, Renderer.getLineX(), Renderer.getLineY());
+ this.mainRender.drawLine(linkedpixX, linkedpixY, Renderer.getLineX(), Renderer.getLineY());
}
Renderer.setLineX(linkedpixX);
Renderer.setLineY(linkedpixY);
}
else {
+ boolean drawRect = false;
if(Highlights.containsPosition(i)) {
- Renderer.setRectColor(extraRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled());
+ setRectColor(this.extraRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled());
drawRect = true;
}
- else drawRect = false;
if(drawRect) {
- extraRender.setStroke(ArrayVisualizer.getThickStroke());
+ this.extraRender.setStroke(ArrayVisualizer.getThickStroke());
if(Highlights.fancyFinishActive()) {
- extraRender.fillRect((linkedpixX - Renderer.getDotWidth() / 2) - 10, (linkedpixY - Renderer.getDotHeight() / 2) - 10, Renderer.getDotWidth() + 20, Renderer.getDotHeight() + 20);
+ this.extraRender.fillRect((linkedpixX - Renderer.getDotWidth() / 2) - 10, (linkedpixY - Renderer.getDotHeight() / 2) - 10, Renderer.getDotWidth() + 20, Renderer.getDotHeight() + 20);
}
else {
- extraRender.drawRect((linkedpixX - Renderer.getDotWidth() / 2) - 10, (linkedpixY - Renderer.getDotHeight() / 2) - 10, Renderer.getDotWidth() + 20, Renderer.getDotHeight() + 20);
+ this.extraRender.drawRect((linkedpixX - Renderer.getDotWidth() / 2) - 10, (linkedpixY - Renderer.getDotHeight() / 2) - 10, Renderer.getDotWidth() + 20, Renderer.getDotHeight() + 20);
}
- extraRender.setStroke(new BasicStroke(3f * (ArrayVisualizer.currentWidth() / 1280f)));
+ this.extraRender.setStroke(new BasicStroke(3f * (ArrayVisualizer.currentWidth() / 1280f)));
}
- mainRender.fillRect(linkedpixX - Renderer.getDotWidth() / 2, linkedpixY - Renderer.getDotHeight() / 2, Renderer.getDotWidth(), Renderer.getDotHeight());
+ this.mainRender.fillRect(linkedpixX - Renderer.getDotWidth() / 2, linkedpixY - Renderer.getDotHeight() / 2, Renderer.getDotWidth(), Renderer.getDotHeight());
}
}
else {
@@ -185,7 +189,7 @@ else if(ArrayVisualizer.getCurrentLength() != 2){
p.addPoint(ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(i + 1, ArrayVisualizer.halfCircle()) * (((ArrayVisualizer.currentWidth() - 64) / CIRC_WIDTH_RATIO) * len)),
ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(i + 1, ArrayVisualizer.halfCircle()) * (((ArrayVisualizer.currentHeight() - 96) / CIRC_HEIGHT_RATIO) * len)));
- mainRender.fillPolygon(p);
+ this.mainRender.fillPolygon(p);
}
}
else if(ArrayVisualizer.spiralEnabled()) {
@@ -194,19 +198,19 @@ else if(ArrayVisualizer.spiralEnabled()) {
if(i > 0) {
if(Highlights.fancyFinishActive()) {
if(i < Highlights.getFancyFinishPosition()) {
- Renderer.lineFancy(mainRender, ArrayVisualizer.currentWidth());
+ lineFancy(this.mainRender, ArrayVisualizer.currentWidth());
}
- else Renderer.lineClear(mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth());
+ else lineClear(this.mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth());
- Renderer.drawFancyFinishLine(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled());
+ drawFancyFinishLine(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled());
}
else {
if(Highlights.containsPosition(i)) {
- Renderer.lineMark(mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled());
+ lineMark(this.mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled());
}
- else Renderer.lineClear(mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth());
+ else lineClear(this.mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth());
}
- mainRender.drawLine(ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(i, ArrayVisualizer.halfCircle()) * ((((ArrayVisualizer.windowWidth() - 64) / 3.0) * array[i]) / ArrayVisualizer.getCurrentLength())),
+ this.mainRender.drawLine(ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(i, ArrayVisualizer.halfCircle()) * ((((ArrayVisualizer.windowWidth() - 64) / 3.0) * array[i]) / ArrayVisualizer.getCurrentLength())),
ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(i, ArrayVisualizer.halfCircle()) * ((((ArrayVisualizer.windowHeight() - 96) / 2.0) * array[i]) / ArrayVisualizer.getCurrentLength())),
Renderer.getLineX(),
Renderer.getLineY());
@@ -215,32 +219,32 @@ else if(ArrayVisualizer.spiralEnabled()) {
Renderer.setLineY(ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(i, ArrayVisualizer.halfCircle()) * ((((ArrayVisualizer.windowHeight() - 96) / 2.0) * array[i]) / ArrayVisualizer.getCurrentLength())));
}
else {
+ boolean drawRect = false;
if(Highlights.containsPosition(i)) {
- Renderer.setRectColor(extraRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled());
+ setRectColor(this.extraRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled());
drawRect = true;
}
- else drawRect = false;
int rectx = ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(i, ArrayVisualizer.halfCircle()) * (((((ArrayVisualizer.windowWidth() - 64) / 3.0) * array[i]) / ArrayVisualizer.getCurrentLength())));
int recty = ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(i, ArrayVisualizer.halfCircle()) * (((((ArrayVisualizer.windowHeight() - 96) / 2.0) * array[i]) / ArrayVisualizer.getCurrentLength())));
- mainRender.fillRect(rectx, recty, Renderer.getDotWidth(), Renderer.getDotHeight());
+ this.mainRender.fillRect(rectx, recty, Renderer.getDotWidth(), Renderer.getDotHeight());
if(drawRect) {
- extraRender.setStroke(ArrayVisualizer.getThickStroke());
+ this.extraRender.setStroke(ArrayVisualizer.getThickStroke());
if(Highlights.fancyFinishActive()) {
- extraRender.fillRect(rectx - 10, recty - 10, Renderer.getDotWidth() + 20, Renderer.getDotHeight() + 20);
+ this.extraRender.fillRect(rectx - 10, recty - 10, Renderer.getDotWidth() + 20, Renderer.getDotHeight() + 20);
}
else {
- extraRender.drawRect(rectx - 10, recty - 10, Renderer.getDotWidth() + 20, Renderer.getDotHeight() + 20);
+ this.extraRender.drawRect(rectx - 10, recty - 10, Renderer.getDotWidth() + 20, Renderer.getDotHeight() + 20);
}
- extraRender.setStroke(new BasicStroke(3f * (ArrayVisualizer.currentWidth() / 1280f)));
+ this.extraRender.setStroke(new BasicStroke(3f * (ArrayVisualizer.currentWidth() / 1280f)));
}
}
}
else {
if(Highlights.containsPosition(i)) {
- Renderer.markBar(mainRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.analysisEnabled());
+ markBar(this.mainRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.analysisEnabled());
}
Polygon p = new Polygon();
@@ -254,7 +258,7 @@ else if(ArrayVisualizer.spiralEnabled()) {
p.addPoint(ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(i + 1, ArrayVisualizer.halfCircle()) * ((((ArrayVisualizer.windowWidth() - 64) / 3.0) * array[Math.min(i + 1, ArrayVisualizer.getCurrentLength() - 1)]) / ArrayVisualizer.getCurrentLength())),
ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(i + 1, ArrayVisualizer.halfCircle()) * ((((ArrayVisualizer.windowHeight() - 96) / 2.0) * array[Math.min(i + 1, ArrayVisualizer.getCurrentLength() - 1)]) / ArrayVisualizer.getCurrentLength())));
- mainRender.fillPolygon(p);
+ this.mainRender.fillPolygon(p);
}
}
else {
@@ -269,7 +273,7 @@ else if(ArrayVisualizer.spiralEnabled()) {
p.addPoint(ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(i + 1, ArrayVisualizer.halfCircle()) * ((ArrayVisualizer.windowWidth() - 64) / CIRC_WIDTH_RATIO)),
ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(i + 1, ArrayVisualizer.halfCircle()) * ((ArrayVisualizer.windowHeight() - 96) / CIRC_HEIGHT_RATIO)));
- mainRender.fillPolygon(p);
+ this.mainRender.fillPolygon(p);
}
}
}
diff --git a/src/visuals/Hoops.java b/src/visuals/Hoops.java
index c4e8f7f7..9041e6e2 100644
--- a/src/visuals/Hoops.java
+++ b/src/visuals/Hoops.java
@@ -5,6 +5,7 @@
import java.awt.Graphics2D;
import main.ArrayVisualizer;
+import templates.Visual;
import utils.Highlights;
import utils.Renderer;
@@ -34,11 +35,56 @@ of this software and associated documentation files (the "Software"), to deal
*
*/
-final public class Hoops {
+final public class Hoops extends Visual {
+ public Hoops(ArrayVisualizer ArrayVisualizer) {
+ super(ArrayVisualizer);
+ }
+
+ @SuppressWarnings("fallthrough")
+ public static void markHoops(int logOfLen, int index, Highlights Highlights, Graphics2D mainRender) {
+ switch(logOfLen) {
+ case 14: if(Highlights.containsPosition(index - 13)) mainRender.setColor(Color.BLACK);
+ case 13: if(Highlights.containsPosition(index - 12)) mainRender.setColor(Color.BLACK);
+ case 12: if(Highlights.containsPosition(index - 11)) mainRender.setColor(Color.BLACK);
+ case 11: if(Highlights.containsPosition(index - 10)) mainRender.setColor(Color.BLACK);
+ case 10: if(Highlights.containsPosition(index - 9)) mainRender.setColor(Color.BLACK);
+ case 9: if(Highlights.containsPosition(index - 8)) mainRender.setColor(Color.BLACK);
+ case 8: if(Highlights.containsPosition(index - 7)) mainRender.setColor(Color.BLACK);
+ case 7: if(Highlights.containsPosition(index - 6)) mainRender.setColor(Color.BLACK);
+ case 6: if(Highlights.containsPosition(index - 5)) mainRender.setColor(Color.BLACK);
+ case 5: if(Highlights.containsPosition(index - 4)) mainRender.setColor(Color.BLACK);
+ case 4: if(Highlights.containsPosition(index - 3)) mainRender.setColor(Color.BLACK);
+ case 3: if(Highlights.containsPosition(index - 2)) mainRender.setColor(Color.BLACK);
+ case 2: if(Highlights.containsPosition(index - 1)) mainRender.setColor(Color.BLACK);
+ default: if(Highlights.containsPosition(index)) mainRender.setColor(Color.BLACK);
+ }
+ }
+
+ @SuppressWarnings("fallthrough")
+ public static void drawFancyFinishHoops(int logOfLen, int index, int position, Graphics2D mainRender) {
+ switch(logOfLen) {
+ case 14: if(index == position - 13) mainRender.setColor(Color.BLACK);
+ case 13: if(index == position - 12) mainRender.setColor(Color.BLACK);
+ case 12: if(index == position - 11) mainRender.setColor(Color.BLACK);
+ case 11: if(index == position - 10) mainRender.setColor(Color.BLACK);
+ case 10: if(index == position - 9) mainRender.setColor(Color.BLACK);
+ case 9: if(index == position - 8) mainRender.setColor(Color.BLACK);
+ case 8: if(index == position - 7) mainRender.setColor(Color.BLACK);
+ case 7: if(index == position - 6) mainRender.setColor(Color.BLACK);
+ case 6: if(index == position - 5) mainRender.setColor(Color.BLACK);
+ case 5: if(index == position - 4) mainRender.setColor(Color.BLACK);
+ case 4: if(index == position - 3) mainRender.setColor(Color.BLACK);
+ case 3: if(index == position - 2) mainRender.setColor(Color.BLACK);
+ case 2: if(index == position - 1) mainRender.setColor(Color.BLACK);
+ default: if(index == position) mainRender.setColor(Color.BLACK);
+ }
+ }
+
//TODO: Fix scaling to ensure Hoops close at the center
//TODO: Too many rings highlighted at once!!
- public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights) {
- mainRender.setStroke(new BasicStroke(1.0f)); //thin strokes significantly increased performance
+ @Override
+ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) {
+ this.mainRender.setStroke(new BasicStroke(1.0f)); //thin strokes significantly increased performance
//This StackOverflow thread may be related: https://stackoverflow.com/questions/47102734/performances-issue-when-drawing-dashed-line-in-java
@@ -48,23 +94,23 @@ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Re
for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++) {
if(Highlights.fancyFinishActive()) {
if(i < Highlights.getFancyFinishPosition()) {
- mainRender.setColor(Color.GREEN);
+ this.mainRender.setColor(Color.GREEN);
}
- else mainRender.setColor(Renderer.getIntColor(array[i], ArrayVisualizer.getCurrentLength()));
+ else this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength()));
- Renderer.drawFancyFinishHoops(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), mainRender);
+ drawFancyFinishHoops(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender);
}
else {
- mainRender.setColor(Renderer.getIntColor(array[i], ArrayVisualizer.getCurrentLength()));
+ this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength()));
}
if(ArrayVisualizer.getCurrentLength() != 2) {
- Renderer.markHoops(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights, mainRender);
+ markHoops(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights, this.mainRender);
}
int radius = (int) (diameter / 2.0);
- mainRender.drawOval(ArrayVisualizer.windowHalfWidth() - radius,
+ this.mainRender.drawOval(ArrayVisualizer.windowHalfWidth() - radius,
ArrayVisualizer.windowHalfHeight() - radius + 12,
(int) diameter,
(int) diameter);
diff --git a/src/visuals/Mesh.java b/src/visuals/Mesh.java
index 69ef1100..03bbf650 100644
--- a/src/visuals/Mesh.java
+++ b/src/visuals/Mesh.java
@@ -1,9 +1,9 @@
package visuals;
import java.awt.Color;
-import java.awt.Graphics2D;
import main.ArrayVisualizer;
+import templates.Visual;
import utils.Highlights;
import utils.Renderer;
@@ -33,12 +33,48 @@ of this software and associated documentation files (the "Software"), to deal
*
*/
-final public class Mesh {
- public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights) {
- int trih = Renderer.getTriangleHeight(ArrayVisualizer.getCurrentLength(), ArrayVisualizer.windowHeight() / 20); //Height of triangles to use, Width will be scaled accordingly
+final public class Mesh extends Visual {
+ public Mesh(ArrayVisualizer ArrayVisualizer) {
+ super(ArrayVisualizer);
+ }
+
+ //TODO: Change these to be more consistent between array lengths. These heights and counts are a bit random.
+ public static int getTriangleHeight(int length, double height) {
+ switch(length) {
+ case 2: height *= 20; break;
+ case 4: height *= 13; break;
+ case 8: height *= 8; break;
+ case 16:
+ case 32: height *= 4.4; break;
+ case 64: height *= 2.3; break;
+ case 128: height *= 2.35; break;
+ case 256: height *= 1.22; break;
+ default: height *= 1;
+ }
+
+ return (int) height;
+ }
+
+ public static int getTrianglesPerRow(int length, int trianglesPerColumn) {
+ int trianglesPerRow;
+
+ switch(length) {
+ case 32:
+ case 64: trianglesPerRow = 4; break;
+ case 128:
+ case 256: trianglesPerRow = 8; break;
+ default: trianglesPerRow = Math.max(length / trianglesPerColumn, 2);
+ }
+
+ return trianglesPerRow;
+ }
+
+ @Override
+ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) {
+ int trih = getTriangleHeight(ArrayVisualizer.getCurrentLength(), ArrayVisualizer.windowHeight() / 20); //Height of triangles to use, Width will be scaled accordingly
int tripercol = (ArrayVisualizer.windowHeight() / trih) * 2; //Triangles per column
- int triperrow = Renderer.getTrianglesPerRow(ArrayVisualizer.getCurrentLength(), tripercol); //Triangles per row
+ int triperrow = getTrianglesPerRow(ArrayVisualizer.getCurrentLength(), tripercol); //Triangles per row
double triw = (double) ArrayVisualizer.windowWidth() / triperrow; //Width of triangles to use
@@ -50,15 +86,15 @@ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Re
for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++){
if(Highlights.containsPosition(i) && ArrayVisualizer.getCurrentLength() != 2) {
- if(ArrayVisualizer.analysisEnabled()) mainRender.setColor(Color.WHITE);
- else mainRender.setColor(Color.BLACK);
+ if(ArrayVisualizer.analysisEnabled()) this.mainRender.setColor(Color.WHITE);
+ else this.mainRender.setColor(Color.BLACK);
}
else {
//TODO: Clean up this visual trick
if(Highlights.fancyFinishActive() && (i < Highlights.getFancyFinishPosition() && i > Highlights.getFancyFinishPosition() - ArrayVisualizer.getLogBaseTwoOfLength())) {
- mainRender.setColor(Color.GREEN);
+ this.mainRender.setColor(Color.GREEN);
}
- else mainRender.setColor(Renderer.getIntColor(array[i], ArrayVisualizer.getCurrentLength()));
+ else this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength()));
}
//If i/triperrow is even, then triangle points right, else left
boolean direction = false;
@@ -89,7 +125,7 @@ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Re
}
//Draw it
- mainRender.fillPolygon(triptsx, triptsy, triptsx.length);
+ this.mainRender.fillPolygon(triptsx, triptsy, triptsx.length);
//If at the end of a row, reset curx
//(i != 0 || i != currentLen - 1)
diff --git a/src/visuals/Pixels.java b/src/visuals/Pixels.java
index 92d306ed..a1fad716 100644
--- a/src/visuals/Pixels.java
+++ b/src/visuals/Pixels.java
@@ -2,9 +2,9 @@
import java.awt.BasicStroke;
import java.awt.Color;
-import java.awt.Graphics2D;
import main.ArrayVisualizer;
+import templates.Visual;
import utils.Highlights;
import utils.Renderer;
@@ -34,34 +34,52 @@ of this software and associated documentation files (the "Software"), to deal
*
*/
-final public class Pixels {
- private boolean drawRect;
-
- public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights) {
- //TODO: Fix zeroth line approaching infinity
+final public class Pixels extends Visual {
+ public Pixels(ArrayVisualizer ArrayVisualizer) {
+ super(ArrayVisualizer);
+ }
+
+ @Override
+ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) {
if(ArrayVisualizer.linesEnabled()) {
+ //TODO: Wave visual needs to be *heavily* refactored
+ if(ArrayVisualizer.waveEnabled()) {
+ Renderer.setLineY((int) ((ArrayVisualizer.windowHeight() / 4) * Math.sin((2 * Math.PI * ((double) array[1] / ArrayVisualizer.getCurrentLength()))) + ArrayVisualizer.windowHalfHeight()));
+ }
+ else {
+ Renderer.setLineY((int) ((ArrayVisualizer.windowHeight() - 20) - array[0] * Renderer.getYScale()));
+ }
for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++) {
- int y = 0;
+ int y;
+ if(ArrayVisualizer.waveEnabled()) {
+ y = (int) ((ArrayVisualizer.windowHeight() / 4) * Math.sin((2 * Math.PI * ((double) array[i] / ArrayVisualizer.getCurrentLength()))) + ArrayVisualizer.windowHalfHeight());
+ }
+ else {
+ y = (int) ((ArrayVisualizer.windowHeight() - 20) - (Math.max(array[i], 1) * Renderer.getYScale()));
+
+ // Quick patch to fix the first line being horizontal for some reason
+ if(i == 0) y += ((ArrayVisualizer.windowHeight() - 20) - array[1] * Renderer.getYScale())
+ - ((ArrayVisualizer.windowHeight() - 20) - array[2] * Renderer.getYScale());
+ }
+
int width = (int) (Renderer.getXScale() * (i + 1)) - Renderer.getOffset();
if(width > 0) {
- y = (int) ((ArrayVisualizer.windowHeight() - 20) - (Math.max(array[i], 1) * Renderer.getYScale()));
-
if(i > 0) {
if(Highlights.fancyFinishActive()) {
if(i < Highlights.getFancyFinishPosition()) {
- Renderer.lineFancy(mainRender, ArrayVisualizer.currentWidth());
+ lineFancy(this.mainRender, ArrayVisualizer.currentWidth());
}
- else Renderer.lineClear(mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth());
+ else lineClear(this.mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth());
- Renderer.drawFancyFinishLine(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled());
+ drawFancyFinishLine(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled());
}
else if(Highlights.containsPosition(i) && ArrayVisualizer.getCurrentLength() != 2) {
- Renderer.lineMark(mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled());
+ lineMark(this.mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled());
}
- else Renderer.lineClear(mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth());
-
- mainRender.drawLine(Renderer.getOffset() + 20, y, Renderer.getLineX() + 20, Renderer.getLineY());
+ else lineClear(this.mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth());
+
+ this.mainRender.drawLine(Renderer.getOffset() + 20, y, Renderer.getLineX() + 20, Renderer.getLineY());
}
Renderer.setLineX(Renderer.getOffset());
Renderer.setLineY(y);
@@ -72,43 +90,48 @@ else if(Highlights.containsPosition(i) && ArrayVisualizer.getCurrentLength() !=
else {
for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++) {
if(i < Highlights.getFancyFinishPosition()) {
- mainRender.setColor(Color.GREEN);
+ this.mainRender.setColor(Color.GREEN);
}
else if(i == Highlights.getFancyFinishPosition() && Highlights.fancyFinishActive()) {
if(ArrayVisualizer.colorEnabled()) {
- mainRender.setColor(Color.WHITE);
+ this.mainRender.setColor(Color.WHITE);
}
- else mainRender.setColor(Color.RED);
+ else this.mainRender.setColor(Color.RED);
}
else if(ArrayVisualizer.colorEnabled()) {
- mainRender.setColor(Renderer.getIntColor(array[i], ArrayVisualizer.getCurrentLength()));
+ this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength()));
}
- else mainRender.setColor(Color.WHITE);
+ else this.mainRender.setColor(Color.WHITE);
int y = 0;
int width = (int) (Renderer.getXScale() * (i + 1)) - Renderer.getOffset();
+ boolean drawRect = false;
if(Highlights.containsPosition(i) && ArrayVisualizer.getCurrentLength() != 2) {
- Renderer.setRectColor(extraRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled());
+ setRectColor(this.extraRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled());
drawRect = true;
}
- else drawRect = false;
if(width > 0) {
- y = (int) ((ArrayVisualizer.windowHeight() - 20) - (array[i] * Renderer.getYScale()));
- mainRender.fillRect(Renderer.getOffset() + 20, y, Renderer.getDotDimensions(), Renderer.getDotDimensions());
+ if(ArrayVisualizer.waveEnabled()) {
+ y = (int) ((ArrayVisualizer.windowHeight() / 4) * Math.sin((2 * Math.PI * ((double) array[i] / ArrayVisualizer.getCurrentLength()))) + ArrayVisualizer.windowHalfHeight());
+ }
+ else {
+ y = (int) ((ArrayVisualizer.windowHeight() - 20) - (array[i] * Renderer.getYScale()));
+ }
+ this.mainRender.fillRect(Renderer.getOffset() + 20, y, Renderer.getDotDimensions(), Renderer.getDotDimensions());
if(drawRect) {
- extraRender.setStroke(ArrayVisualizer.getThickStroke());
+ this.extraRender.setStroke(ArrayVisualizer.getThickStroke());
if(Highlights.fancyFinishActive()) {
- extraRender.fillRect(Renderer.getOffset() + 10, y - 10, Renderer.getDotDimensions() + 20, Renderer.getDotDimensions() + 20);
+ this.extraRender.fillRect(Renderer.getOffset() + 10, y - 10, Renderer.getDotDimensions() + 20, Renderer.getDotDimensions() + 20);
}
else {
- extraRender.drawRect(Renderer.getOffset() + 10, y - 10, Renderer.getDotDimensions() + 20, Renderer.getDotDimensions() + 20);
+ this.extraRender.drawRect(Renderer.getOffset() + 10, y - 10, Renderer.getDotDimensions() + 20, Renderer.getDotDimensions() + 20);
}
- extraRender.setStroke(new BasicStroke(3f * (ArrayVisualizer.currentWidth() / 1280f))); //TODO: This BasicStroke should have a getDefaultStroke() method
+ this.extraRender.setStroke(new BasicStroke(3f * (ArrayVisualizer.currentWidth() / 1280f))); //TODO: This BasicStroke should have a getDefaultStroke() method
}
}
Renderer.setOffset(Renderer.getOffset() + width);
diff --git a/src/visuals/VisualStyles.java b/src/visuals/VisualStyles.java
index 46b7c600..d7b8f683 100644
--- a/src/visuals/VisualStyles.java
+++ b/src/visuals/VisualStyles.java
@@ -1,7 +1,5 @@
package visuals;
-import java.awt.Graphics2D;
-
import main.ArrayVisualizer;
import utils.Highlights;
import utils.Renderer;
@@ -33,45 +31,40 @@ of this software and associated documentation files (the "Software"), to deal
*/
public enum VisualStyles {
- CIRCULAR {
+ BARS {
@Override
- public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer,
- Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights) {
- Renderer.drawCircle(array, ArrayVisualizer, mainRender, extraRender, Highlights);
+ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) {
+ ArrayVisualizer.getVisuals()[0].drawVisual(array, ArrayVisualizer, Renderer, Highlights);
}
},
- HOOPS {
+ CIRCULAR {
@Override
- public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer,
- Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights) {
- Renderer.drawHoops(array, ArrayVisualizer, mainRender, extraRender, Highlights);
+ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) {
+ ArrayVisualizer.getVisuals()[1].drawVisual(array, ArrayVisualizer, Renderer, Highlights);
}
},
- MESH {
+ HOOPS {
@Override
- public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer,
- Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights) {
- Renderer.drawMesh(array, ArrayVisualizer, mainRender, extraRender, Highlights);
+ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) {
+ ArrayVisualizer.getVisuals()[2].drawVisual(array, ArrayVisualizer, Renderer, Highlights);
}
},
- BARS {
+ MESH {
@Override
- public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer,
- Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights) {
- Renderer.drawBars(array, ArrayVisualizer, mainRender, extraRender, Highlights);
+ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) {
+ ArrayVisualizer.getVisuals()[3].drawVisual(array, ArrayVisualizer, Renderer, Highlights);
}
},
PIXELS {
@Override
- public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer,
- Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights) {
- Renderer.drawPixels(array, ArrayVisualizer, mainRender, extraRender, Highlights);
+ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) {
+ ArrayVisualizer.getVisuals()[4].drawVisual(array, ArrayVisualizer, Renderer, Highlights);
}
};
- public VisualStyles getVisual() {
+ public VisualStyles getCurrentVisual() {
return this;
}
- public abstract void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Graphics2D mainRender, Graphics2D extraRender, Highlights Highlights);
+ public abstract void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights);
}
\ No newline at end of file