Introduction
Algorithm is simply a set of step by step procedures for solving a complex problem by splitting its large chunk into several smaller bits and solving them procedurally, which can then be tackled individually in steps to solve the original problem
Algorithms can be implemented practically with the use of one or more programming langauges. This documentation in an insight to a few algorithms problems and my approach to solving them by enumerating step by step, the procedures I took to arive at my solution. These steps might not be the shortest possible path or most consise pattern, but is aimed at exposing the process step by step in the most plain way possible.
Before proceeding I will want to point out some of the types of algorithms that probably might have been used, and give a brief definition on each.
Types of Algorithms
Some types of algorithms include, but are not restricted to the following
- Backtracking algorithms – This algorithm pattern involves dividing the problem into subproblems, each which can be attempted to be solved, but however, if the desired solution is not reached, steps are retraced backwards in the problem until a path is found that moves it forward.
- Randomized algorithms – This kind of algorithm makes use a random number at least once during the computation to find a solution to the problem.
- Divide and conquer algorithms – This type of algorithm involves the division of the problem into smaller subproblems of the same type, solving these smaller problems, and then cummulating their solutions to solve the original problem.
- Recursive algorithms – This type of algorithm solves the lowest and simplest version of a problem to then solve increasingly larger versions of the problem until the solution to the original problem is found.
- Brute force algorithms – This type of algorithm tries all possible solutions to a problem until a satisfactory solution is found.
- Dynamic programming algorithms – This type of algorithm involves the breaking of a complex problem into a collection of simpler subproblems, then solve each of those subproblems only once, and storing their solution for future use instead of re-computing their solutions.
- Greedy algorithms – This kind of algorithm involves finding an optimal solution at the local level with the intent of finding an optimal solution for the whole problem.
It is important to learn the use and applicaton of Algorithms for some the folowing reasons
- Enables the easy breaking down of complex problems into smaller bits
- Improves the efficiency of solving a problem
- It enables the propert utilization of resources avaliable to solve a problem
- It provides clarity of the problem statement
- Saves time and improves precison
Below are some algorithm problems I solved using plain JavaScript, with some commented details, and my thought process on how I went about my solution.
ROT13 Caeser Cipher Decoder
This is a program that accepts an encoded ROT13 text and converts it back to its original text.
The ROT13 is a simple letter substitution cipher that replaces a letter with the 13th letter after it in the alphabet.
function rot13(str) {
/** Defining a regex pattern rule */
const regex = /[A-Z]/ig
/** Splitting the input string argument into an array of characters */
const splString = str.split('')
/** Defining an empty array to hold the character codes of each character */
let charCodeArr = []
/** Iterating through each of the characters, , */
for(let i = 0; i < splString.length; i++){
/** Testing each character against the regular expression defined */
if(splString[i].match(regex)){
/** Adding 13 to each character code withing the range of A - M and inserting its result into the empty array */
if(splString[i].charCodeAt() >= 65 && splString[i].charCodeAt() <= 77){
charCodeArr.push(`${splString[i].charCodeAt()+13}`)
}
/** Subtracting 13 from each character code within the range of N - Z and inserting its result into the empty array */
else{
charCodeArr.push(`${splString[i].charCodeAt()-13}`)
}
}
/** Inserting any non alphanumeric character without any form of modification */
else{
charCodeArr.push(splString[i])
}
}
/** Initializing a variable to hold the final result */
let rot13String = ''
/** Populating the final result with the converted character codes together with non-alphanumeric characters at appropriate positions */
for(let i = 0; i < charCodeArr.length; i++){
if(splString[i].match(regex)){
rot13String += String.fromCharCode(Number(charCodeArr[i]))
}else{
rot13String += charCodeArr[i]
}
}
/** Returning the final result of the operations */
return rot13String;
}
/** Testing the Function with a ROT13 encoded text. Output is "FREE PIZZA!" */
rot13("SERR CVMMN!");
My Thought Process
- I defined a regular expression rule to match only uppercase and lowercase aphabets, rejecting all other characters
- I then splitted the string iput argument into an array of characters.
- I created an empty array.
- Iterating though each entity in the array, each element is tested in a "if" statement, against the regex rule specified.
- If an entity fails, the entity itself is appended to the empty array created.
- If the entity passes, it is again tested if the character code equivalent of the enetity is within the range of the characters "A" to "N" (character code 65 to 77).
- If the entity is within the range of characters "A" to "N", the number 13 is added (+13) to its character code value, if not the number 13 is subtracted (-13) instead from its character code value to reverse the sequence and the values of both cases are also inserted (pushed) into the empty array for each entity satisfying their condition.
- I then created an empty string.
- Iterating through each entity in the previously empty array (now filled with values from the previous iteration), each eneity is tested in a "if" statement against the regex rule specified again.
- If the element passes, it is converted from a number string value into a Number integer, and the value of this integer is now converted back to a character and added to the empty string previously created, at any point the entity being tested is "truthy".
- If the element fails the regex rule test (Meaning that is is not an alphanumeric character) it is appended as it is at any point which the eneity being tested is "falsy".
Sum In Range
This program makes use of algorithm to get the sum of two numbers together with the sum of all numbers in-between them
function sumAll(arr) {br
/** Summing the two numbers in the given array */
const sumArr = arr[0] + arr[1];
/** Sorting the array to ensure that the lowest number comes first */
const sortedArr = arr.sort((a, b)=> a - b );
/** Obtaining an array containing all the numbers between the two gven numbers */
let arrRange = [];
let sortedMinArrPlusOne = sortedArr[0] + 1
for(let i = sortedArr[0]; i < sortedArr[1] - 1; i++){
arrRange.push(sortedMinArrPlusOne++);
}
/** Adding all the numbers between the two given numbers */
let summedArrRange = 0;
for(let i = 0; i < arrRange.length; i++){
summedArrRange += arrRange[i];
}
/** Summing the sum of the two numbers and the range of numbers between them */
const totalSum = sumArr + summedArrRange;
console.log(totalSum) // Printing the final answer
return totalSum;
}
/** Calling the Function with input arguments */
sumAll([4, 9]);
My Thought Process
- I created a variable and store the value of the sum of the two numbers.
- I arranged the two numbers so that the smaller one always comes first.
- Using iteration I generated all the numbers between the two given numbers and stored them in an array.
- All numbers between the two given numbers are then added and stored in a variable using iteration.
- The sum of the two given numbers and the sum of all the numbers in-between them are then added together and then Returned.
Average Altitude To Orbital Period
This is a program that accepts an array or objects containing an entity and its average height, and returns a new object for the entity and its orbital period
function orbitalPeriod(arr) {
/** Initialization of an array to hold the values of the objects to be created. */
const newArr = []
/** The actual Function that takes the average altitude and converts it to orbital period */
function getOrbitalPeriod(avgAlt){
const GM = 398600.4418;
const earthRadius = 6367.4447;
const orbitalRadius = earthRadius + avgAlt
/** Formula for calculation */
return Math.round(
2 * Math.PI * Math.sqrt(((orbitalRadius * orbitalRadius) * orbitalRadius) / GM)
)
}
/** Iterating through the given array to obtain their values of average height, calculate their orbital height, and store the values in the newly created object */
for(let i = 0; i < arr.length; i++){
let tempVal = {
name: arr[i]['name'],
orbitalPeriod: getOrbitalPeriod(arr[i]['avgAlt'])
}
/** Inserting the newly created objects into the declared empty array above. */
newArr.push(tempVal)
}
)
/** Returning the new object array */
return newArr;
}
/** Testing the Function with an array with a single object, containing its name and average height value. */
orbitalPeriod([{name : "manjaro", avgAlt : 35873.5553}]);
/** result is [ { name: 'manjaro', orbitalPeriod: 86400 } ] */
My Thought Process
- I defined an empty array to store the new object to be created.
- I initialized a function that takes the average atlitude value and returns the value of the orbital period using the mathematical relation contained in the function.
- I iterated through each object in the input array, and for each object, create a new object whoose name key and value is same with its name, and the value of its orbitalPeriod property is the result of the "getOrbitalPeriod()" function
- For each object in the input array, a new object is inserted into the new array, and then the new array is returned.
Find The Missing Letter
This program spots out a missing character from amongst a string of characters, and returns the missing character, by comparing their ASCII unicode
function findTheMissingLetter(str) {
for(let i = 0; i < str.length; i++){
if(str.charCodeAt(i) !== (str.charCodeAt(0) + i)){
return String.fromCharCode(str.charCodeAt(i)-1)
}
}
return undefined;
}
/** The character "d" is Returned */
findTheMissingLetter("abce");
My Thought Process
- Each character in the input string is looped through
- If the character code of each letter in the string at every point is not same with the sum of the first character code and the iterator, that character is spotted as the missing one, and then Returned
- If no character is found to be missing from the input string, "undefined" is returned;
Palindrome Checker
A palindrome is simply a word whoose character arrangement is the same when spelt normally (forward) and backwards. The function below, takes a string as input arguent strips it of all non alphanumeric characters, removes all spaces flips it backward and compares the processed string with itself spelt backwards, and returns true or false if it is a palindrome or not
/** Removing all non alphanumeric characters and spaces */
function removeNonAlphaNumericAndJoin(arg){
const regex = /[^\W]/ig
return arg.match(regex).join("")
}
/** The palindrome checker function */
function palindrome(str){
/** Variable to hold the reversed version of the input argument */
let strReversed = ''
/** Reversing the input argument */
for(let i = str.length - 1; i >= 0; i--){
strReversed += str[i]
}
/** Performing the check between the processed input string, and the processed reversed string */
return removeNonAlphaNumericAndJoin(strReversed).toLowerCase() === removeNonAlphaNumericAndJoin(str).toLowerCase()
}
/** Testing a few inputs */
console.log(palindrome("never odd or even")) /** Returns true */
console.log(palindrome('once a rat now a cat')) /** Returns false */
My Thought Process
- I filtered out all alphanumeric characters from the input string and return the output.
- From the output above, I emoved all spaces between characters and return the output.
- From the output above, I reversed the string, and stored in a variable.
- Both the input string and the reversed string are then converted to lower case and compared.
- The result of the comparism is then returned.
Search And Replace
This is a program that takes a string (first argument), and replaces a word in the string (second argument), with another word (third argument) without using the String "replace()" method.
function myReplacer(str, before, after) {
/** Split the input string into an array of words */
const strArray = str.split(" ")
/** Initializing a regular expression */
const regex = /[A-Z]/g
/** Carrying out a set of operations if the first letter of the word to be replaced in upper case */
if(regex.test(before[0]) === true){
/** Finding the index of the word to be replaced */
const replaceIndex = strArray.indexOf(before)
/** Spreading the replacing word into an array of characters */
let afterSpread = [...after]
/** Converting the first letter of the replacing word to uppercase */
afterSpread[0] = afterSpread[0].toUpperCase();
/** Joining back the array of characters into a word */
const joinedAfter = afterSpread.join("");
/** Replacing the word to be replaced with the replacing word */
strArray.splice(replaceIndex, 1, joinedAfter);
/** Assembling the array of words back into a string */
const joinedStr = strArray.join(" ");
/** Returning the result */
return joinedStr;
}
/** Carrying out a set of operations if the first letter of the word to be replaced in lower case */
/** Finding the index of the word to be replaced */
const replaceIndex = strArray.indexOf(before)
/** Spreading the replacing word into an array of characters */
let afterSpread = [...after]
/** Converting the first letter of the replacing word to uppercase */
afterSpread[0] = afterSpread[0].toLowerCase()
/** Joining back the array of characters into a word */
const joinedAfter = afterSpread.join("")
/** Replacing the word to be replaced with the replacing word */
strArray.splice(replaceIndex, 1, joinedAfter)
/** Assembling the array of words back into a string */
const joinedStr = strArray.join(" ")
/** Returning the result */
return joinedStr;
}
/** Calling the function with different string arguments */
myReplacer("A quick brown fox jumped over the lazy dog", "jumped", "leaped");
myReplacer("He is Sleeping on the couch", "Sleeping", "sitting")
My Thought Process
- I split the input string into an array or words
- A regular expression is initialized to match all uppercase letters
- I set up a condition block if the first letter of the word to be replaced is uppercase
- The index number of the word to be replaced is obtained and store it in a variable
- The first letter of the replacing word is then changed to uppercase
- The word to be replaced is then replaced with the replacing word targeting the word to be replaced with its index number, and return the resulting string
- After that a condition block is set up if the first letter of the word to be replaced is lower case
- The index number of the word to be replaced is found and store it in a variable
- The first letter of the replacing word is then changed to uppercase
- The word to be replaced is then swapped with the replacing word targeting the word to be replaced with its index number, and return the resulting string
Roman Numeral Converter
This is a simple program that converts an Arabic numeral within the range of 1 to 3999, to a Roman Numeral
function convertToRoman(num) {
if(num >= 4000){
return 'Input Above Range!'
}
let holder = '';
let numVar = num;
while(numVar >= 1000){
holder += 'M';
numVar -= 1000;
}
while(numVar >= 900){
holder += 'CM';
numVar -= 900;
}
while(numVar >= 500){
holder += 'D';
numVar -= 500;
}
while(numVar >= 400){
holder += 'CD';
numVar -= 400;
}
while(numVar >= 100){
holder += 'C';
numVar -= 100;
}
while(numVar >= 90){
holder += 'XC';
numVar -= 90;
}
while(numVar >= 50){
holder += 'L';
numVar -= 50;
}
while(numVar >= 40){
holder += 'XL';
numVar -= 40;
}
while(numVar >= 10){
holder += 'X';
numVar -= 10;
}
while(numVar == 9){
holder += 'IX';
numVar -= 9
}
while(numVar >= 5){
holder += 'V';
numVar -= 5;
}
while(numVar == 4){
holder += "IV";
numVar -= 4;
}
console.log(numVar)
while(numVar >= 1){
holder += "I";
numVar -= 1;
}
console.log(holder)
return holder;
}
convertToRoman(36);
convertToRoman(214);
My Thought Process
- This function encolses sets of recursive blocks that appends each key Roman character to a variable whilst subtracting the actual value of the number from the input, and running through all recursive blocks, till the value of the input is exhausted.