Category: Uncategorized
Quicksort Algorithm

JavaScript
/*** GLOBALS ***/
var morphArray;
var numberRange = 500;
var prints = 21;
var waitTime = 100;
/*** FUNCTIONS ***/
/*create the actual array to be sorted*/
function createArray() {
morphArray = [];
for (i = 0; i < prints; i++) {
var number = Math.floor((Math.random() * numberRange));
morphArray.push(number);
}
var uniqueArray = Array.from(new Set(morphArray));
//test that every number in array is unique
if (JSON.stringify(uniqueArray) === JSON.stringify(morphArray)) {
return morphArray
} else {
//recreate the array if each number is not unique
return createArray();
}
}
/*create the visual representation of the array - a set of boxes*/
function createBoxes() {
morphArray = createArray();
for (i = 0; i < prints; i++) {
var randomNumber = morphArray[i];
//append each box to the container; wrapper is necessary to assign different transition durations for float effect (class "wrap") and rotate effect (class "box") transforms
$('.box-container').append('<div class="wrap float"><div class="box invisible unsorted"><div class="number-text">' + randomNumber + '</div></div></div>');
//assign unique data attribute to each box
$('.wrap:eq(' + i + ')>.box').attr('data-num', randomNumber);
/*
ADD CLASS "VISIBLE" TO EACH BOX TRIGGERING ENTRANCE ANIMATION
-IIFE is used to create execution context so the current iteration's context is remembered when time comes to add "visible" class. This enables the setTimeout to work before the execution context expires and the loop is completed.
-The outer IIFE provides delay b/t creation of each box and addition of animation class, so element exists long enough for animation to kick in successfully. This only seemed necessary for the first box.
-The inner IIFE does the work of adding the class to each box after the delay period
*/
(function buyTime(i) {
setTimeout(function () {
(function triggerAnimation(i) {
setTimeout(function () {
var currentBox = '.wrap:eq(' + i + ')>.box';
$(currentBox).toggleClass('visible invisible');
}, waitTime * i);
})(i);
}, waitTime);
})(i);
}
}
/*quicksort function*/
//add method quicksort to Array.prototype that exists in browser
Array.prototype.quicksort = function () {
//"this" is equal to the array on which the quicksort function is executed
var r = this;
// base case - return the array when it is one digit, and thus doesn't need more sorting
if (r.length <= 1) {
return r;
}
//create pivot of 1 digit that is just past mid-point of the array, removing it from the array
var pivot = r.splice(Math.floor(r.length / 2), 1);
//initialize sub-arrays for each side of the pivot
var less = [];
var greater = [];
//run number of times there are items left in the array after pivot is removed
for (i = r.length - 1; i >= 0; i--) {
if (r[i] < pivot) {
less.push(r[i]);
} else {
greater.push(r[i]);
}
}
var c = [];
//recursive cases - sort each sub array
return c.concat(less.quicksort(), pivot, greater.quicksort());
}
/***EVENTS***/
/* click event for "Create Array" button */
$('.create-array-btn').click(function () {
var allVisible = true;
//turn allVisible false if any .box is missing .visible (entrance animation) class
$('.wrap').each(function () {
if ($(this).children().hasClass('visible') === false) {
allVisible = false;
};
});
//create boxes if there are none
if ($('.wrap').length === 0) {
createBoxes();
} else if ($('.wrap').length === prints && allVisible === true) {
$('.wrap').remove();
createBoxes();
} //or remove and recreate boxes only if a prior array with its boxes has finished displaying
});
/* click event for "Quick Sort" button */
$('.sort-btn').click(function () {
var readyToSort = false;
//if the full number of prints exist, we are provisionally ready to sort
if ($('.box-container').get(0).childElementCount === prints) {
readyToSort = true;
}
//but don't sort if all the boxes are not finished animating onto the screen, or if they're already sorted
$('.box').each(function () {
if ($(this).hasClass('invisible') || $(this).hasClass('sorted')) {
readyToSort = false;
}
});
if (readyToSort === true) {
morphArray = morphArray.quicksort();
/*move first box into position of the sorted morphArray*/
var sortedDataAttr = morphArray[0];
//data attribute must be absolutely unique for fetching it based on that to work
var sortedElement = '*[data-num="' + sortedDataAttr + '"]';
$('.box-container').prepend($(sortedElement).parent());
$(sortedElement).toggleClass('sorted unsorted');
/*move remaining boxes into their postion in the sorted morphArray*/
for (i = 1; i < prints; i++) {
(function (i) {
setTimeout(function () {
var sortedDataAttr = morphArray[i];
var sortedElement = '*[data-num="' + sortedDataAttr + '"]';
//place box after the last instance of .sorted
$('.sorted:last').parent().after($(sortedElement).parent());
$(sortedElement).toggleClass('sorted unsorted');
}, waitTime * i);
})(i);
}
}
});
HTML
<div class="button-container">
<button class="create-array-btn wpforms-submit">Create Array</button>
<button class="sort-btn wpforms-submit ">Quick Sort</button>
</div>
<div class="box-container"></div>
CSS
.button-container {
display: flex;
justify-content: center;
margin-bottom: 18px;
}
@media(max-width:500px) {
.button-container {
flex-direction: column;
align-items: center;
}
.sort-btn {
margin-top: 7px;
}
}
@media(min-width:501px) {
.sort-btn {
margin-left: 7px;
}
}
.box-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.box {
margin: 15px;
justify-content: center;
align-items: center;
width: 130px;
height: 130px;
font-family: Montserrat, sans-serif;
font-size: 30px;
display: flex;
transition: opacity .5s, transform .5s;
}
.invisible {
opacity: 0;
transform: rotate(-90deg);
}
.visible {
opacity: 1;
transform: rotate(0deg);
}
.unsorted {
background: #4d4d4d;
}
.sorted {
background: black;
}
.number-text {
font-size: 24px;
color: white;
}
/*float effect on hover*/
.float {
transition-duration: .3s;
transition-property: transform;
transition-timing-function: cubic-bezier(0.09, 0.51, 0.83, 0.96);
}
.float:active,
.float:focus,
.float:hover {
transform: translateY(-8px)
}
Roman Numeral Converter

JavaScript
function convertToRoman(num) {
var roman = [];
var numString = num.toString();
//split number into an array containing only any digits entered
var numArr = numString.match(/\d/g);
//store value of the number without any special characters, such as commas
var bareNumber = numArr.join('');
var thousands = bareNumber / 1000;
//initialize variables for each index in the array that contains the last 3 digits
var hundreds = 0;
var tens = 1;
var ones = 2;
//if the number has digits for the thousands, push an "M" into the array for each thousand
if (thousands >= 1) {
thousands = Math.floor(thousands);
console.log(thousands);
for (i = 0; i < thousands; i++) {
roman.push("M");
}
var thousandsString = thousands.toString();
//remove each digit for thousands from the beginning of the array
for (i = 0; i < thousandsString.length; i++) {
numArr.shift();
}
}
//function to convert last 3 array digits to their Roman numerals
function parseNumbers(first, second, third, position) {
//hundreds, tens, or ones: 1-2
if (numArr[position] >= 1 && numArr[position] <= 3) {
for (i = 0; i < numArr[position]; i++) {
roman.push(first);
}
}
//4
if (numArr[position] == 4) {
roman.push(first + second);
}
//5
if (numArr[position] == 5) {
roman.push(second);
}
//6-8
if (numArr[position] >= 6 && numArr[position] <= 8) {
roman.push(second);
for (i = 5; i < numArr[position]; i++) {
roman.push(first);
}
}
//9
if (numArr[position] == 9) {
roman.push(first + third);
}
}
//if there is a hundreds digit, do the conversion for this digit
console.log(numArr.length);
if (numArr.length === 3) {
//hundreds
parseNumbers("C", "D", "M", hundreds);
}
//if there is a tens digit, do the conversion for this digit
if (numArr.length >= 2) {
if (numArr.length === 2) {
//if the number starts with tens, shift the array position fed to the parser to the correct digit
tens = 0;
ones = 1;
}
//tens
parseNumbers("X", "L", "C", tens);
}
//if there is a ones digit, do the conversion for this digit
if (numArr.length >= 1) {
//if the number starts with ones, shift the array position fed to the parser to the correct digit
if (numArr.length === 1) {
ones = 0;
}
//ones
parseNumbers("I", "V", "X", ones);
}
num = roman.toString();
num = num.replace(/,/g, '');
console.log(num);
return num;
}
Rotate 13 Algorithm

JavaScript
function rot13(str) {
// 1- Convert every character to the number portion (charCode) of the that character's HTML entity ---
//helpful map of HTML entities: https://unicode-table.com/en/
//create an array containing all characters
var indivChars = str.split("");
//create an array of only every character that is not a capital letter
var nonLetterRE = /[^A-Z]/g;
var nonLetters = str.match(nonLetterRE);
//create an empty array that will contain all the numerical values for the characters
var numEntityArr = [];
//cycle through array containing all characters & convert the capital letters to their character code
//if a character does not belong to A-Z, assign it a value of 0
for (let i = 0; i < indivChars.length; i++) {
var numberEntity = indivChars[i].charCodeAt(0);
if (numberEntity >= 65 && numberEntity <= 90) {
numEntityArr.push(numberEntity);
} else {
numEntityArr.push(0);
}
}
// 2 - shift each character code 13 positions numerically ---
var shiftedArray = [];
var counter = 0;
for (let i = 0; i < numEntityArr.length; i++) {
//if the character code represents a letter within A-M, add 13 to the character code
if (numEntityArr[i] >= 65 && numEntityArr[i] <= 77) {
numEntityArr[i] = numEntityArr[i] + 13;
//push this new number into an array, along with prefix and suffix that make the character code an HTML entity
shiftedArray.push("&#" + numEntityArr[i] + ";");
//if the character code represents a letter within N-Z, subtract 13 from the character code
} else if (numEntityArr[i] >= 78 && numEntityArr[i] <= 90) {
numEntityArr[i] = numEntityArr[i] - 13;
shiftedArray.push("&#" + numEntityArr[i] + ";");
//if the character code is not A-Z or 0, simply add prefix and suffix to make it an HTML entity & push it into the array
} else if (numEntityArr[i] !== 0) {
shiftedArray.push("&#" + numEntityArr[i] + ";");
//if the character code is 0, replace it with the corresponding index of the nonLetter array created above
} else if (numEntityArr[i] === 0) {
shiftedArray.push(nonLetters[counter]);
counter += 1;
}
}
// 3 - return correct letters ---
//join in a string the html entities and non A-Z characters pushed into shiftedArray
var entityString = shiftedArray.join("");
//convert the HTML entities into characters, while passing all other non-entity characters through
//credit: http://stackoverflow.com/questions/7394748/whats-the-right-way-to-decode-a-string-that-has-special-html-entities-in-it
function decodeHTML(html) {
var txt = document.createElement("textarea");
txt.innerHTML = html;
return txt.value;
}
var decodedHTML = decodeHTML(entityString);
return decodedHTML;
}
Flexbox Demo

CSS
.flex-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
max-width: 1000px;
margin: 0 auto;
padding: 1%;
}
.flex-item {
width: 30%;
max-width: 275px;
min-width: 200px;
margin-left: 1%;
margin-right: 1%;
}
.image {
width: 100%;
height: auto;
}
HTML
<div class="flex-container">
<a class="flex-item" href="http://example-url.org">
<img class="image" src="http://example-image.jpg">
<h3 class="pic-title">Spirograph Nebula</h3>
</a>
<!--Each of the nine flex items follow the format above-->
</div>