Skip to content

add in alternate color mode; add adtl sorting algorithms #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ Without the work of these excellent folks, the algorithms you see visualized wou
- [Learn JS With Me](http://learnjswith.me/quick-sort-in-javascript/)
- [NCZOnline](https://www.nczonline.net/blog/2009/09/08/computer-science-in-javascript-selection-sort/)

Additionally, I'd like to credit the work of [reddit user morolin](https://www.reddit.com/r/woahdude/comments/78fzi7/sorting_algorithms_visualized_gifv/?st=jaj5goe1&sh=e80fb95c) for the initial inspiration

[algorithm-playground]: https://algorithm-playground.com
2 changes: 1 addition & 1 deletion src/algorithms/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fs from 'fs';
import path from 'path';
import camelCase from 'lodash.camelcase';

const EXCLUDE = [/^__/, /^\./, /index\.js/];
const EXCLUDE = [/^__/, /^\./, /index\.js/, /bogo/];

const base = path.join(__dirname, '..');
const files = fs
Expand Down
35 changes: 35 additions & 0 deletions src/algorithms/bitonic-merge-sort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* CODE: https://en.wikipedia.org/wiki/Bitonic_sorter
*
* Bitonic mergesort is a parallel algorithm for sorting. It is also used as a
construction method for building a sorting network. The algorithm was devised
by Ken Batcher.
*
* MORE INFO: https://en.wikipedia.org/wiki/Bitonic_sorter
*/
function kernel(arr, p, q) {
let d = 1 << (p - q);

for (let i = 0; i < arr.length; i++) {
let up = ((i >> p) & 2) === 0;

if ((i & d) === 0 && arr[i] > arr[i | d] === up) {
let temp = arr[i];
arr[i] = arr[i | d];
arr[i | d] = temp;
}
}
}

function bitonicSort(n, arr) {
for (let i = 0; i < n; i++) {
for (let j = 0; j <= i; j++) {
kernel(arr, i, j);
}
}
return arr;
}

export function bitonicMergeSort(arr, n = 25) {
return bitonicSort(n, arr);
}
43 changes: 43 additions & 0 deletions src/algorithms/bogo-sort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* CODE: https://www.w3resource.com/javascript-exercises/searching-and-sorting-algorithm/searching-and-sorting-algorithm-exercise-14.php
*
* Bogo sort is a highly ineffective sorting function based on the generate
and test paradigm. The function successively generates permutations of its
input until it finds one that is sorted. It is not useful for sorting, but
may be used for educational purposes, to contrast it with more efficient
algorithms.
*
* MORE INFO: https://en.wikipedia.org/wiki/Bogosort
*/
function isSorted(arr) {
return arr.every((num, index) => index === 0 || arr[index - 1] <= num);
}

function shuffle(arr) {
let count = arr.length;
let temp;
let index;

while (count > 0) {
index = Math.floor(Math.random() * count);
count--;

temp = arr[count];
arr[count] = arr[index];
arr[index] = temp;
}

return arr;
}

export function bogoSort(arr, attempts = 10) {
let sorted = false;
for (let i = 0; i < attempts; i++) {
arr = shuffle(arr);
sorted = isSorted(arr);
if (sorted) {
break;
}
}
return arr;
}
43 changes: 43 additions & 0 deletions src/algorithms/bucket-sort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
*
*/
function insertionSort(arr) {
for (let i = 1; i < arr.length; i++) {
let value = arr[i];
let j = i - 1;
while (j >= 0 && arr[j] > value) {
arr[j + 1] = arr[j];
j -= 1;
}
arr[j + 1] = value;
}
return arr;
}

export function bucketSort(list, bucketCount = 200) {
// only for numbers
var min = Math.min.apply(Math, list), // get the min
buckets = [];

// build the bucket and distribute the elements in the list
for (var i = 0; i < list.length; i++) {
// this is a simple hash function that will make sure the basic rule of bucket sort
var newIndex = Math.floor((list[i] - min) / bucketCount);

buckets[newIndex] = buckets[newIndex] || [];
buckets[newIndex].push(list[i]);
}
// refill the elements into the list
var idx = 0;
for (i = 0; i < buckets.length; i++) {
if (typeof buckets[i] !== 'undefined') {
// select those non-empty buckets
insertionSort(buckets[i]); // use any sorting algorithm would be fine
// sort the elements in the bucket
for (var j = 0; j < buckets[i].length; j++) {
list[idx++] = buckets[i][j];
}
}
}
return list;
}
39 changes: 39 additions & 0 deletions src/algorithms/comb-sort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* CODE: https://www.w3resource.com/javascript-exercises/searching-and-sorting-algorithm/searching-and-sorting-algorithm-exercise-9.php
*
* Comb sort is a relatively simple sorting algorithm originally designed by
Włodzimierz Dobosiewicz in 1980. Later it was rediscovered by Stephen Lacey
and Richard Box in 1991. Comb sort improves on bubble sort.
*
* MORE INFO: https://en.wikipedia.org/wiki/Comb_sort
*/
function isSorted(arr) {
return arr.every((num, index) => index === 0 || arr[index - 1] <= num);
}

export function combSort(arr) {
let iteration_count = 0;
let gap = arr.length - 2;
let decrease_factor = 1.25;

while (!isSorted(arr)) {
if (iteration_count > 0) {
gap = gap === 1 ? gap : Math.floor(gap / decrease_factor);
}

let front = 0;
let back = gap;
while (back <= arr.length - 1) {
if (arr[front] > arr[back]) {
let temp = arr[front];
arr[front] = arr[back];
arr[back] = temp;
}

front += 1;
back += 1;
}
iteration_count += 1;
}
return arr;
}
51 changes: 51 additions & 0 deletions src/algorithms/merge-sort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* CODE: http://www.stoimen.com/blog/2010/07/02/friday-algorithms-javascript-merge-sort/
*
*
* MORE INFO:
*/

function merge(arr, left, right) {
let result = [];
while (left.length && right.length) {
if (left[0] <= right[0]) {
result.push(left.shift());
} else {
result.push(right.shift());
}
}

while (left.length) {
result.push(left.shift());
}

while (right.length) {
result.push(right.shift());
}

return result;
}

/*
* Note: augment would normally not be needed
* but is needed for the visualization to appear correctly
*/
function augment(arr, result) {
for (let i = 0; i < result.length; i++) {
arr[i] = result[i];
}
}

export function mergeSort(arr) {
if (arr.length < 2) {
return arr;
}

const len = arr.length;

let middle = parseInt(len / 2);
let left = arr.slice(0, middle);
let right = arr.slice(middle, len);

return merge(arr, mergeSort(left), mergeSort(right));
}
42 changes: 42 additions & 0 deletions src/algorithms/radix-sort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* CODE: http://taoalpha.github.io/blog/2016/01/19/tech-javascript-sorting-algorithm-radix-sort/
*
*
* MORE INFO:
*/
function getDigit(num, nth) {
// get last nth digit of a number
let ret = 0;
while (nth--) {
ret = num % 10;
num = Math.floor((num - ret) / 10);
}
return ret;
}

export function radixSort(arr) {
let max = Math.floor(Math.log10(Math.max.apply(Math, arr))),
digitBuckets = [],
idx = 0;

for (let i = 0; i < max + 1; i++) {
digitBuckets = [];
let j = 0;
for (; j < arr.length; j++) {
let digit = getDigit(arr[j], i + 1);

digitBuckets[digit] = digitBuckets[digit] || [];
digitBuckets[digit].push(arr[j]);
}

idx = 0;
for (let t = 0; t < digitBuckets.length; t++) {
if (digitBuckets[t] && digitBuckets[t].length > 0) {
for (j = 0; j < digitBuckets[t].length; j++) {
arr[idx++] = digitBuckets[t][j];
}
}
}
}
return arr;
}
25 changes: 19 additions & 6 deletions src/components/AlgorithmPreview/components/Canvas/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,15 @@ class CanvasComponent extends Component {
window.removeEventListener('resize', this.handleResize);
}

componentWillReceiveProps({ localChanges, sortFunction }) {
componentWillReceiveProps({ localChanges, sortFunction, theme }) {
if (this.props.localChanges !== localChanges) {
this.handleResize();
} else if (
!this.props.sortFunction ||
(this.props.sortFunction !== sortFunction && this.state.sortComplete)
(this.props.sortFunction !== sortFunction && this.state.sortComplete) ||
this.props.theme !== theme
) {
this.resetGrid({ inProgress: false });
this.resetGrid({ inProgress: false }, theme);
}
}

Expand Down Expand Up @@ -171,12 +172,13 @@ class CanvasComponent extends Component {
});
}

resetGrid(additionalUpdate) {
resetGrid(additionalUpdate, theme = this.props.theme) {
this.setState({
inProgress: false,
grid: createGrid(this.state.context)({
height: this.state.height,
width: this.state.width
width: this.state.width,
...this.getMaxAndStart(theme)
}),
sortComplete: false,
sorted: false,
Expand All @@ -194,12 +196,23 @@ class CanvasComponent extends Component {
...(reset && {
grid: createGrid(this.state.context)({
height: this.state.height,
width: this.state.width
width: this.state.width,
...this.getMaxAndStart(this.props.theme)
})
}: {})
});
}

getMaxAndStart(theme) {
if (theme === 'dark') {
return {};
}
return {
max: 250,
min: 50
};
}

render() {
const {
height,
Expand Down
Loading