[JavaScript] Algorithms and Data Structures Projects

These are my notes while doing the course JavaScript Algorithms and Data Structures on https://www.freecodecamp.org. I highly recommend it if you prefer to try things directly rather than watching videos.


1. Palindrome Checker

function palindrome(str) {

  // clear string
  str = str.toLowerCase().replace(/[^a-z0-9]/g, "");

  // reverse string
  let strBack = str.split("").reverse().join("");

  // palindrome?
  return (str === strBack) ? true : false;

}

palindrome("_eye");
palindrome("five|\_/|four");
palindrome("1 eye for of 1 eye.");

2. Roman Numeral Converter

function convertToRoman(num) {

  const lookup = {M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1};
  let roman = '';

  for ( let i in lookup ) {
    while ( num >= lookup[i] ) {
      roman += i;
      num -= lookup[i];
    }
  }
  return roman;
}

convertToRoman(6);

3. Caesars Cipher

function rot13(str) {

  const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  const length = alphabet.length;
  let decode = "";

  const getROT13 = index => {
    return (index+13 >= length) ? alphabet[13-(length-index)] : alphabet[index+13];
  }

  for (let i=0; i<str.length; i++) {

    let index = alphabet.indexOf(str[i]);

    decode += (index<0) ? str[i] : getROT13(index); 

  }

  return decode;
}

rot13("SERR PBQR PNZC")
rot13("SERR CVMMN!")

4. Telephone Number Validator

function telephoneCheck(str) {

  let regexCheck = /^(1.*){0,1}(\d{3}|[(]\d{3}[)])[\s|-]*\d{3}.*\d{4}$/g; 

  let result = regexCheck.test(str);

  if (result) {
    let length = str.match(/\d/g).length;
    result = (length == 7 || length == 10 || (length == 11 && str[0] == 1)) ? true : false;
  }

  console.log(str.match(regexCheck));
  console.log(result);

  return result;

}


telephoneCheck("555-555-5555");
telephoneCheck("1 555-555-5555");
telephoneCheck("1 (555) 555-5555");
telephoneCheck("5555555555");
telephoneCheck("555-555-5555")
telephoneCheck("(555)555-5555")
telephoneCheck("1(555)555-5555")
telephoneCheck("1 555)555-5555") //false
telephoneCheck("(6054756961)")  //false
telephoneCheck("2 (757) 622-7382") //false
telephoneCheck("10 (757) 622-7382") //false

5. Cash Register

function checkCashRegister(price, cash, cid) {

  let changeArr = [];

  const currency = { "ONE HUNDRED": 100, "TWENTY": 20, "TEN": 10, "FIVE": 5, "ONE": 1, "QUARTER": 0.25, "DIME": 0.1, "NICKEL": 0.05, "PENNY": 0.01 }

  const substract = (a, b) => parseFloat(a - b).toPrecision(4);

  const calcAmount = (change, curr) => {
                let rest = change % curr;
                let div = substract(change, rest) / curr;    
                return div * curr;
  }

  let change = substract(cash, price);

  //check if cid equals to change
  //or if cid is already not enough
  let sum = 0;
  for (let k=0; k<cid.length;k++) {
    sum += cid[k][1]
  }
  if (sum == change) {
    return {status: "CLOSED", change: cid};
  } else if (sum < change) {
    return {status: "INSUFFICIENT_FUNDS", change: []};
  }

  //calculate change
  for (let i in currency) {
    if (change > currency[i]) {    
      for (let j=0; j<cid.length;j++) {
        if (i == cid[j][0]) {
          let amount = cid[j][1];
          if (substract(change, amount) < 0)  {
            amount = calcAmount(change, currency[i]);
          }
          change = substract(change, amount);
          changeArr.push([i, amount]);
        }
      }
    } 
  }

  if (change != 0) {
    //not able to give the correct change
    return {status: "INSUFFICIENT_FUNDS", change: []};
  }
  return {status: "OPEN", change: changeArr};
}

checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]);

checkCashRegister(3.26, 100, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]])

checkCashRegister(19.5, 20, [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])

checkCashRegister(19.5, 20, [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 1], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])

checkCashRegister(19.5, 20, [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])

[JavaScript] Intermediate Algorithm Scripting

These are my notes while doing the course JavaScript Algorithms and Data Structures on https://www.freecodecamp.org. I highly recommend it if you prefer to try things directly rather than watching videos.


1. Sum All Numbers in a Range

function sumAll(arr) {

  let num1 = Math.min(arr[0], arr[1]);
  let num2 = Math.max(arr[0], arr[1]);
  let result = 0;

  while (num1 < num2) {
      result += num1;
      num1++;
  }
  return result += num2;
}

sumAll([1, 4]);

2. Diff Two Arrays

function diffArray(arr1, arr2) {

  var newArr = [];

  for (let i = 0; i < arr1.length; i++) {
    if (arr2.indexOf(arr1[i]) == -1) {
      newArr.push(arr1[i]);
    }
  }

  for (let i = 0; i < arr2.length; i++) {
    if (arr1.indexOf(arr2[i]) == -1) {
      newArr.push(arr2[i]);
    }
  }

  return newArr;
}

diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);

3. Seek and Destroy

function destroyer(...arr) {

  let newArr = arr.shift();

  for (let i = 0; i < arr.length; i++) {
    while (newArr.indexOf(arr[i]) > -1) {
      newArr.splice(newArr.indexOf(arr[i]), 1);
    };
  }

  return newArr;
}

destroyer([1, 2, 3, 1, 2, 3], 2, 3);

4. Wherefore art thou

function whatIsInAName(collection, source) {

  var arr = [];

  var srcKeys = Object.keys(source);

  for (let i = 0; i < collection.length; i++) {
    let obj = collection[i];
    let bool = true;

    for (let j = 0; j < srcKeys.length; j++) {
      let key = srcKeys[j];
      if (!obj.hasOwnProperty(key) || (obj[key] != source[key])) {
        bool = false;
      }
    }

    if (bool) {
      arr.push(obj);
    }
  }

  return arr;
}

whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", //last: "Capulet" }], { last: "Capulet" });

whatIsInAName([{ "apple": 1, "bat": 2 }, { "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "bat": 2 });

5. Spinal Tap Case

function spinalCase(str) {

  let myRegex = /[A-Z][a-z]+|[a-z]+/g;
  let arr = str.match(myRegex);

  return arr.join("-").toLowerCase();
}

spinalCase('This Is Spinal Tap');
spinalCase("thisIsSpinalTap");
spinalCase("The_Andy_Griffith_Show");
spinalCase("Teletubbies say Eh-oh");
spinalCase("AllThe-small Things");

6. Pig Latin

function translatePigLatin(str) {

  let regexAY = /(^[^aeiou]+)/g;
  let regexWAY = /(^[aeiou]+)/g; 
  
  if (regexAY.test(str)) {
    let cutStr = str.match(regexAY);
    let newStr = str.substr(cutStr[0].length);
    return newStr + cutStr[0] + "ay";

  } else if (regexWAY.test(str)) {
    return str + "way";
  }

}

translatePigLatin("consonant");
translatePigLatin("paragraphs");
translatePigLatin("glove");
translatePigLatin("algorithm");
translatePigLatin("eight");
translatePigLatin("rhythm");

7. Search and Replace

function myReplace(str, before, after) {

  if (/^[A-Z]/.test(before)) {
    after = after.charAt(0).toUpperCase() + after.slice(1);
  } else {
    after = after.charAt(0).toLowerCase() + after.slice(1);
  }

  return str.replace(before, after);

}

myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped");
myReplace("Let us go to the store", "store", "mall");
myReplace("He is Sleeping on the couch", "Sleeping", "sitting");

8. DNA Pairing

function pairElement(str) {

  let arr = [];

  for (let i = 0; i < str.length; i++) {

    let tmp = [];
    tmp.push(str[i]);
    
    switch(str[i]) {
      case "A":
        tmp.push("T");
        break;
      case "T":
        tmp.push("A");
        break;
      case "C":
        tmp.push("G");
        break;
      case "G":
        tmp.push("C");
    }
  
    arr.push(tmp);
  }
  
  return arr;
}

pairElement("GCG");

9. Missing letters

function fearNotLetter(str) {

  const alphabet = "abcdefghijklmnopqrstuvwxyz";

  let startIndex = alphabet.indexOf(str[0]);

  const compareStr = alphabet.slice(startIndex, startIndex + str.length);

  for (let i = 0; i < compareStr.length; i++) {
    if (compareStr[i] !== str[i]) {
        return compareStr[i];
    }
  }

  return undefined;
}

fearNotLetter("abce");
fearNotLetter("bcdf");
fearNotLetter("stvwx");

10. Sorted Union

function uniteUnique(...arr) {

  const uniteArray = [].concat(...arr);

  let uniteUniqueArray = [];

  for (let i = 0; i < uniteArray.length; i++) {
    if (uniteUniqueArray.indexOf(uniteArray[i]) == -1) uniteUniqueArray.push(uniteArray[i]);
  }

  return uniteUniqueArray;
}

uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);

11. Convert HTML Entities

function convertHTML(str) {

  return str
  .replace(/&/g, "&")
  .replace(/</g, "<")
  .replace(/>/g, ">")
  .replace(/"/g, """)
  .replace(/'/g, "'")
  .replace(/<>/g, "<>");

}

convertHTML("Dolce & Gabbana");
convertHTML("Hamburgers < Pizza < Tacos");
convertHTML("Sixty > twelve");
convertHTML('Stuff in "quotation marks"');
convertHTML("Schindler's List");
convertHTML("<>");
convertHTML("abc");

12. Sum All Odd Fibonacci Numbers

function sumFibs(num) {

  let fibo = [1, 1];

  const nextNum = fibu => fibo[fibo.length - 1] + fibo[fibo.length - 2];

  while (nextNum(fibo) <= num) {
    fibo.push(nextNum(fibo));
  };

  return fibo
  .filter(currentNum => currentNum%2 != 0) //odd
  .reduce((sum, currentNum) => sum + currentNum, 0); 

}

sumFibs(1);
sumFibs(4);
sumFibs(1000)
sumFibs(4000000);

13. Sum All Primes

function sumPrimes(num) {

  let primArr = [];

  const isPrime = num => { for(let i = 2; i < num; i++)
                            if(num % i === 0) return false;
                           return num > 1;
                          }

  for (let i = 0; i <= num; i++) {
    if(isPrime(i)) primArr.push(i);
  }

  return primArr.reduce((sum, currentNum) => sum + currentNum, 0);
}

sumPrimes(10);
sumPrimes(977);

14. Smallest Common Multiple

function smallestCommons(arr) {

  let rangeArr = [...arr];

  for (let i = Math.min(...arr) + 1; i < Math.max(...arr); i++) {
    rangeArr.push(i);
  }

  rangeArr.sort((a, b) => b-a);

  let lar = rangeArr[0];
  let scm = lar;
  let bool = false;

  while(!bool){
    
    bool = true;

    for (let i = 0; i < rangeArr.length; i++) {
      if (scm % rangeArr[i] != 0) bool = false;
    }
    
    if (bool) return scm;
    
    scm += lar;
  }

}


smallestCommons([1,5]);

15. Drop it

function dropElements(arr, func) {

  let copy = [...arr];

  for (let i = 0; i < arr.length; i++) {

    if (func(arr[i])) {
      break;
    }

    copy.shift();
    
  }

  return copy;
}

dropElements([1, 2, 3], function(n) {return n < 3; });

16. Steamroller (Recursion)

function steamrollArray(arr) {
 
  var flatArr = [];

  const flatten = arr => {
    for (let i = 0; i < arr.length; i++){
      (Array.isArray(arr[i])) ? flatten(arr[i]) : flatArr.push(arr[i]);
    }
    return flatArr;
  }
  
  return flatten(arr);
}

console.log(steamrollArray([1, [2], [3, [[4]]]]));

17. Binary Agents

function binaryAgent(binary) {

  return binary.split(' ') //Split string in array of binary chars
   .map(bin => String.fromCharCode(parseInt(bin, 2))) //Map every binary char to real char
   .join(''); //Join the array back to a string

}

binaryAgent("01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111");

18. Everything Be True

function truthCheck(collection, pre) {
  
  return collection.every(col => col.hasOwnProperty(pre) && Boolean(col[pre]));

}

truthCheck([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy", "sex": "male"}, {"user": "Laa-Laa", "sex": "female"}, {"user": "Po", "sex": "female"}], "sex");

19. Arguments Optionalf (was really tough… this is the sample solution)

function addTogether(first, second) {
  if (typeof first !== "number") {
    return undefined;
  }
  const sum = second =>
    typeof second === "number" ? first + second : undefined;
  return typeof second === "undefined" ? second => sum(second) : sum(second);
}

addTogether(2,3);
addTogether("http://bit.ly/IqT6zt");
addTogether(2, "3");
console.log(addTogether(2)([3]));

20. Make a Person

var Person = function(firstAndLast) {

  var _arr = firstAndLast.split(" ");

  // getter
  this.getFirstName = () => _arr[0];
  this.getLastName = () => _arr[1];
  this.getFullName = () => _arr.join(" ");

  // setter
  this.setFirstName = first => _arr[0] = first;
  this.setLastName = last => _arr[1] = last;
  this.setFullName = firstAndLast => _arr = firstAndLast.split(" ");

};

var bob = new Person('Bob Ross');
bob.getFullName();

21. Map the Debris

function orbitalPeriod(arr) {
  var GM = 398600.4418;
  var earthRadius = 6367.4447;
  
  for(let i in arr){
    arr[i].orbitalPeriod = Math.round((2*Math.PI)*Math.sqrt(Math.pow((earthRadius+arr[i].avgAlt),3)/GM));
    delete arr[i].avgAlt;
  }
  return arr;
}

orbitalPeriod([{name : "sputnik", avgAlt : 35873.5553}]);
orbitalPeriod([{name: "iss", avgAlt: 413.6}, {name: "hubble", avgAlt: 556.7}, {name: "moon", avgAlt: 378632.553}])