Intermediate Algorithm Scripting
1.
Sum All Numbers in a Range
We'll pass you an array of two numbers. Return the sum of those two
numbers plus the sum of all the numbers between them. The lowest number
will not always come first.
For example, sumAll([4,1]) should return 10 because sum of all the numbers between 1 and 4 (both inclusive) is 10.
function sumAll(arr) {
let max = Math.max(arr[0], arr[1]);
let min = Math.min(arr[0], arr[1]);
let sumBetween = 0;
for (let i = min; i <= max; i++) {
sumBetween += i;
}
return sumBetween;
}
sumAll([1, 4]);
or
const sumAll = arr => {
// Buckle up everything to one!
const startNum = arr[0];
const endNum = arr[1];
// Get the count of numbers between the two numbers by subtracting them and add 1 to the absolute value.
// ex. There are |1-4| + 1 = 4, (1, 2, 3, 4), 4 numbers between 1 and 4.
const numCount = Math.abs(startNum - endNum) + 1;
// Using Arithmetic Progression summing formula
const sum = ((startNum + endNum) * numCount) / 2;
return sum;
};
or
function sumAll(arr) {
let sumBetween = 0;
for (let i = Math.min(...arr); i <= Math.max(...arr); i++) {
sumBetween += i;
}
return sumBetween;
}
sumAll([1, 4]);
or
function sumAll(arr) {
const [first, last] = [...arr].sort((a, b) => a - b);
return first !== last
? first + sumAll([first + 1, last])
: first;
}
sumAll([1, 4]);
2.
Compare two arrays and return a new array with any items only found
in one of the two given arrays, but not both. In other words, return the
symmetric difference of the two arrays.
Note: You can return the array with its elements in any order.
function diffArray(arr1, arr2) {
const newArr = [];
function onlyInFirst(first, second) {
// Looping through an array to find elements that don't exist in another array
for (let i = 0; i < first.length; i++) {
if (second.indexOf(first[i]) === -1) {
// Pushing the elements unique to first to newArr
newArr.push(first[i]);
}
}
}
onlyInFirst(arr1, arr2);
onlyInFirst(arr2, arr1);
return newArr;
}
diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);
or
function diffArray(arr1, arr2) {
return arr1
.concat(arr2)
.filter(item => !arr1.includes(item) || !arr2.includes(item));
}
diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);
or
function diffArray(arr1, arr2) {
return [...diff(arr1, arr2), ...diff(arr2, arr1)];
function diff(a, b) {
return a.filter(item => b.indexOf(item) === -1);
}
}
3.
You will be provided with an initial array (the first argument in the destroyer
function), followed by one or more arguments. Remove all elements from
the initial array that are of the same value as these arguments.
Note: You have to use the arguments object.
function destroyer(arr) {
let valsToRemove = Object.values(arguments).slice(1);
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < valsToRemove.length; j++) {
if (arr[i] === valsToRemove[j]) {
delete arr[i];
}
}
}
return arr.filter(item => item !== null);
}
or
function destroyer(arr) {
var valsToRemove = Array.from(arguments).slice(1);
return arr.filter(function(val) {
return !valsToRemove.includes(val);
});
}
or
function destroyer(arr, ...valsToRemove) {
return arr.filter(elem => !valsToRemove.includes(elem));
}
4.
Make a function that looks through an array of objects (first
argument) and returns an array of all objects that have matching name
and value pairs (second argument). Each name and value pair of the
source object has to be present in the object from the collection if it
is to be included in the returned array.
For example, if the first argument is [{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], and the second argument is { last: "Capulet" },
then you must return the third object from the array (the first
argument), because it contains the name and its value, that was passed
on as the second argument.
function whatIsInAName(collection, source) {
// "What's in a name? that which we call a rose
// By any other name would smell as sweet.”
// -- by William Shakespeare, Romeo and Juliet
const souceKeys = Object.keys(source);
// filter the collection
return collection.filter(obj => {
for (let i = 0; i < souceKeys.length; i++) {
if (!obj.hasOwnProperty(souceKeys[i]) ||
obj[souceKeys[i]] !== source[souceKeys[i]]) {
return false;
}
}
return true;
});
}
// test here
whatIsInAName(
[
{ first: "Romeo", last: "Montague" },
{ first: "Mercutio", last: null },
{ first: "Tybalt", last: "Capulet" }
],
{ last: "Capulet" }
);
or
function whatIsInAName(collection, source) {
// "What's in a name? that which we call a rose
// By any other name would smell as sweet.”
// -- by William Shakespeare, Romeo and Juliet
const sourceKeys = Object.keys(source);
return collection
.filter(obj => sourceKeys
.every(key => obj.hasOwnProperty(key) &&
obj[key] === source[key]));
}
// test here
whatIsInAName(
[
{ first: "Romeo", last: "Montague" },
{ first: "Mercutio", last: null },
{ first: "Tybalt", last: "Capulet" }
],
{ last: "Capulet" }
);
or
function whatIsInAName(collection, source) {
// "What's in a name? that which we call a rose
// By any other name would smell as sweet.”
// -- by William Shakespeare, Romeo and Juliet
const souceKeys = Object.keys(source);
// filter the collection
return collection.filter(obj => souceKeys
.map(key => obj.hasOwnProperty(key) && obj[key] === source[key])
.reduce((a, b) => a && b));
}
// test here
whatIsInAName(
[
{ first: "Romeo", last: "Montague" },
{ first: "Mercutio", last: null },
{ first: "Tybalt", last: "Capulet" }
],
{ last: "Capulet" }
);
5.
Convert a string to spinal case. Spinal case is all-lowercase-words-joined-by-dashes.
function spinalCase(str) {
// Create a variable for the white space and underscores.
var regex = /\s+|_+/g;
// Replace low-upper case to low-space-uppercase
str = str.replace(/([a-z])([A-Z])/g, "$1 $2");
// Replace space and underscore with -
return str.replace(regex, "-").toLowerCase();
}
// test here
spinalCase("This Is Spinal Tap");
or
function spinalCase(str) {
// Replace low-upper case to low-space-uppercase
str = str.replace(/([a-z])([A-Z])/g, "$1 $2");
// Split on whitespace and underscores and join with dash
return str
.toLowerCase()
.split(/(?:_| )+/)
.join("-");
}
// test here
spinalCase("This Is Spinal Tap");
or
function spinalCase(str) {
// "It's such a fine line between stupid, and clever."
// --David St. Hubbins
return str
.split(/\s|_|(?=[A-Z])/)
.join("-")
.toLowerCase();
}
6.
Pig Latin is a way of altering English Words. The rules are as follows:
- If a word begins with a consonant, take the first consonant or consonant cluster, move it to the end of the word, and add ay to it.
- If a word begins with a vowel, just add way at the end.
Translate the provided string to Pig Latin. Input strings are guaranteed to be English words in all lowercase.
function translatePigLatin(str) {
let consonantRegex = /^[^aeiou]+/;
let myConsonants = str.match(consonantRegex);
return myConsonants !== null
? str
.replace(consonantRegex, "")
.concat(myConsonants)
.concat("ay")
: str.concat("way");
}
translatePigLatin("consonant");
or
function translatePigLatin(str) {
// Create variables to be used
var pigLatin = "";
var regex = /[aeiou]/gi;
// Check if the first character is a vowel
if (str[0].match(regex)) {
pigLatin = str + "way";
} else if (str.match(regex) === null) {
// Check if the string contains only consonants
pigLatin = str + "ay";
} else {
// Find how many consonants before the first vowel.
var vowelIndice = str.indexOf(str.match(regex)[0]);
// Take the string from the first vowel to the last char
// then add the consonants that were previously omitted and add the ending.
pigLatin = str.substr(vowelIndice) + str.substr(0, vowelIndice) + "ay";
}
return pigLatin;
}
// test here
translatePigLatin("consonant");
or
function translatePigLatin(str) {
if (str.match(/^[aeiou]/)) return str + "way";
const consonantCluster = str.match(/^[^aeiou]+/)[0];
return str.substring(consonantCluster.length) + consonantCluster + "ay";
}
// test here
translatePigLatin("consonant");
or
function translatePigLatin(str) {
return str
.replace(/^[aeiou]\w*/, "$&way")
.replace(/(^[^aeiou]+)(\w*)/, "$2$1ay");
}
// test here
translatePigLatin("consonant");
or
function translatePigLatin(str, charPos = 0) {
return ['a', 'e', 'i', 'o', 'u'].includes(str[0])
? str + (charPos === 0 ? 'way' : 'ay')
: charPos === str.length
? str + 'ay'
: translatePigLatin(str.slice(1) + str[0], charPos + 1);
}
8.
Perform a search and replace on the sentence using the arguments provided and return the new sentence.
First argument is the sentence to perform the search and replace on.
Second argument is the word that you will be replacing (before).
Third argument is what you will be replacing the second argument with (after).
Note: Preserve the case of the first character in
the original word when you are replacing it. For example if you mean to
replace the word Book with the word dog, it should be replaced as Dog
function myReplace(str, before, after) {
// Find index where before is on string
var index = str.indexOf(before);
// Check to see if the first letter is uppercase or not
if (str[index] === str[index].toUpperCase()) {
// Change the after word to be capitalized before we use it.
after = after.charAt(0).toUpperCase() + after.slice(1);
} else {
// Change the after word to be uncapitalized before we use it.
after = after.charAt(0).toLowerCase() + after.slice(1);
}
// Now replace the original str with the edited one.
str = str.replace(before, after);
return str;
}
or
function myReplace(str, before, after) {
// Check if first character of argument "before" is a capital or lowercase letter and change the first character of argument "after" to match the case
if (/^[A-Z]/.test(before)) {
after = after[0].toUpperCase() + after.substring(1)
} else {
after = after[0].toLowerCase() + after.substring(1)
}
// return string with argument "before" replaced by argument "after" (with correct case)
return str.replace(before, after);
}
// test here
myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped");
or
function myReplace(str, before, after) {
// create a function that will change the casing of any number of letter in parameter "target"
// matching parameter "source"
function applyCasing(source, target) {
// split the source and target strings to array of letters
var targetArr = target.split("");
var sourceArr = source.split("");
// iterate through all the items of sourceArr and targetArr arrays till loop hits the end of shortest array
for (var i = 0; i < Math.min(targetArr.length, sourceArr.length); i++) {
// find out the casing of every letter from sourceArr using regular expression
// if sourceArr[i] is upper case then convert targetArr[i] to upper case
if (/[A-Z]/.test(sourceArr[i])) {
targetArr[i] = targetArr[i].toUpperCase();
}
// if sourceArr[i] is not upper case then convert targetArr[i] to lower case
else targetArr[i] = targetArr[i].toLowerCase();
}
// join modified targetArr to string and return
return targetArr.join("");
}
// replace "before" with "after" with "before"-casing
return str.replace(before, applyCasing(before, after));
}
// test here
myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped");
or
// Add new method to the String object, not overriding it if one exists already
String.prototype.capitalize =
String.prototype.capitalize ||
function() {
return this[0].toUpperCase() + this.slice(1);
};
const Util = (function() {
// Create utility module to hold helper functions
function textCase(str, tCase) {
// Depending if the tCase argument is passed we either set the case of the
// given string or we get it.
// Those functions can be expanded for other text cases.
if (tCase) {
return setCase(str, tCase);
} else {
return getCase(str);
}
function setCase(str, tCase) {
switch (tCase) {
case "uppercase":
return str.toUpperCase();
case "lowercase":
return str.toLowerCase();
case "capitalized":
return str.capitalize();
default:
return str;
}
}
function getCase(str) {
if (str === str.toUpperCase()) {
return "uppercase";
}
if (str === str.toLowerCase()) {
return "lowercase";
}
if (str === str.capitalize()) {
return "capitalized";
}
return "normal";
}
}
return {
textCase
};
})();
function myReplace(str, before, after) {
const { textCase } = Util;
const regex = new RegExp(before, "gi");
const replacingStr = textCase(after, textCase(before));
return str.replace(regex, replacingStr);
}
or
function myReplace(str, before, after) {
const strArr = str.split(" ");
const [wordToReplace] = strArr.filter(item => item === before);
const replacement = wordToReplace[0] === wordToReplace[0].toUpperCase()
? after[0].toUpperCase() + after.slice(1)
: after[0].toLowerCase() + after.slice(1);
return strArr.map(item => (item === before ? replacement : item)).join(" ");
}
// test:
myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped");
9.
The DNA strand is missing the pairing element. Take each character, get its pair, and return the results as a 2d array.
Base pairs are a pair of AT and CG. Match the missing element to the provided character.
Return the provided character as the first element in each array.
For example, for the input GCG, return [["G", "C"], ["C","G"], ["G", "C"]]
The character and its pair are paired up in an array, and all the arrays are grouped into one encapsulating array.
function pairElement(str) {
// Return each strand as an array of two elements, the original and the pair.
var paired = [];
// Function to check with strand to pair.
var search = function(char) {
switch (char) {
case "A":
paired.push(["A", "T"]);
break;
case "T":
paired.push(["T", "A"]);
break;
case "C":
paired.push(["C", "G"]);
break;
case "G":
paired.push(["G", "C"]);
break;
}
};
// Loops through the input and pair.
for (var i = 0; i < str.length; i++) {
search(str[i]);
}
return paired;
}
// test here
pairElement("GCG");
or
function pairElement(str) {
//create object for pair lookup
var pairs = {
A: "T",
T: "A",
C: "G",
G: "C"
};
//split string into array of characters
var arr = str.split("");
//map character to array of character and matching pair
return arr.map(x => [x, pairs[x]]);
}
//test here
pairElement("GCG");
10.
Find the missing letter in the passed letter range and return it.
If all letters are present in the range, return undefined.
function fearNotLetter(str) {
for (var i = 0; i < str.length; i++) {
/* code of current character */
var code = str.charCodeAt(i);
/* if code of current character is not equal to first character + no of iteration
hence character has been escaped */
if (code !== str.charCodeAt(0) + i) {
/* if current character has escaped one character find previous char and return */
return String.fromCharCode(code - 1);
}
}
return undefined;
}
// test here
fearNotLetter("abce");
or
function fearNotLetter(str) {
let currCharCode = str.charCodeAt(0);
let missing = undefined;
str
.split("")
.forEach(letter => {
if (letter.charCodeAt(0) === currCharCode) {
currCharCode++;
} else {
missing = String.fromCharCode(currCharCode);
}
});
return missing;
}
// test here
fearNotLetter("abce");
or
function fearNotLetter(str) {
for (let i = 1; i < str.length; ++i) {
if (str.charCodeAt(i) - str.charCodeAt(i - 1) > 1) {
return String.fromCharCode(str.charCodeAt(i - 1) + 1);
}
}
}
11.
Write a function that takes two or more arrays and returns a new
array of unique values in the order of the original provided arrays.
In other words, all values present from all arrays should be included
in their original order, but with no duplicates in the final array.
The unique numbers should be sorted by their original order, but the final array should not be sorted in numerical order.
Check the assertion tests for examples.
function uniteUnique(arr1, arr2, arr3) {
// Creates an empty array to store our final result.
const finalArray = [];
// Loop through the arguments object to truly make the program work with two or more arrays
// instead of 3.
for (let i = 0; i < arguments.length; i++) {
const arrayArguments = arguments[i];
// Loops through the array at hand
for (let j = 0; j < arrayArguments.length; j++) {
let indexValue = arrayArguments[j];
// Checks if the value is already on the final array.
if (finalArray.indexOf(indexValue) < 0) {
finalArray.push(indexValue);
}
}
}
return finalArray;
}
uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);
or
function uniteUnique(arr) {
const args = [...arguments];
const result = [];
for (let i = 0; i < args.length; i++) {
for (let j = 0; j < args[i].length; j++) {
if (!result.includes(args[i][j])) {
result.push(args[i][j]);
}
}
}
return result;
}
uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);
or
function uniteUnique() {
return [...arguments]
.flat()
.filter((item, ind, arr) => arr.indexOf(item) === ind);
}
uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);
12.
Convert the characters &, <, >, " (double quote), and ' (apostrophe), in a string to their corresponding HTML entities.
function convertHTML(str) {
// Split by character to avoid problems.
var temp = str.split("");
// Since we are only checking for a few HTML elements, use a switch
for (var i = 0; i < temp.length; i++) {
switch (temp[i]) {
case "<":
temp[i] = "<";
break;
case "&":
temp[i] = "&";
break;
case ">":
temp[i] = ">";
break;
case '"':
temp[i] = """;
break;
case "'":
temp[i] = "'";
break;
}
}
temp = temp.join("");
return temp;
}
//test here
convertHTML("Dolce & Gabbana");
or
function convertHTML(str) {
// Use Object Lookup to declare as many HTML entities as needed.
const htmlEntities = {
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'"
};
// Using a regex, replace characters with it's corresponding html entity
return str.replace(/([&<>\"'])/g, match => htmlEntities[match]);
}
// test here
convertHTML("Dolce & Gabbana");
or
function convertHTML(str) {
// Use Object Lookup to declare as many HTML entities as needed.
const htmlEntities = {
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'"
};
//Use map function to return a filtered str with all entities changed automatically.
return str
.split("")
.map(entity => htmlEntities[entity] || entity)
.join("");
}
// test here
convertHTML("Dolce & Gabbana");
13.
Sum All Odd Fibonacci Numbers
Given a positive integer num, return the sum of all odd Fibonacci numbers that are less than or equal to num.
The first two numbers in the Fibonacci sequence are 1 and 1. Every
additional number in the sequence is the sum of the two previous
numbers. The first six numbers of the Fibonacci sequence are 1, 1, 2, 3,
5 and 8.
For example, sumFibs(10) should return 10 because all odd Fibonacci numbers less than or equal to 10 are 1, 1, 3, and 5.
function sumFibs(num) {
let prevNumber = 0;
let currNumber = 1;
let result = 0;
while (currNumber <= num) {
if (currNumber % 2 !== 0) {
result += currNumber;
}
currNumber += prevNumber;
prevNumber = currNumber - prevNumber;
}
return result;
}
// test here
sumFibs(4);
or
function sumFibs(num) {
// Perform checks for the validity of the input
if (num <= 0) return 0;
// Create an array of fib numbers till num
const arrFib = [1, 1];
let nextFib = 0;
// We put the new Fibonacci numbers to the front so we
// don't need to calculate the length of the array on each
// iteration
while ((nextFib = arrFib[0] + arrFib[1]) <= num) {
arrFib.unshift(nextFib);
}
// We filter the array to get the odd numbers and reduce them to get their sum.
return arrFib.filter(x => x % 2 != 0).reduce((a, b) => a + b);
}
// test here
sumFibs(4);
14.
A prime number is a whole number greater than 1 with
exactly two divisors: 1 and itself. For example, 2 is a prime number
because it is only divisible by 1 and 2. In contrast, 4 is not prime
since it is divisible by 1, 2 and 4.
Rewrite sumPrimes so it returns the sum of all prime numbers that are less than or equal to num.
function sumPrimes(num) {
// Helper function to check primality
function isPrime(num) {
for (let i = 2; i <= Math.sqrt(num); i++) {
if (num % i == 0)
return false;
}
return true;
}
// Check all numbers for primality
let sum = 0;
for (let i = 2; i <= num; i++) {
if (isPrime(i))
sum += i;
}
return sum;
}
or
function sumPrimes(num) {
// Check all numbers for primality
let primes = [];
for (let i = 2; i <= num; i++) {
if (primes.every((prime) => i % prime !== 0))
primes.push(i);
}
return primes.reduce((sum, prime) => sum + prime, 0);
}
or
function sumPrimes(num) {
// Prime number sieve
let isPrime = Array(num + 1).fill(true);
// 0 and 1 are not prime
isPrime[0] = false;
isPrime[1] = false;
for (let i = 2; i <= Math.sqrt(num); i++) {
if (isPrime[i]) {
// i has not been marked false -- it is prime
for (let j = i * i; j <= num; j += i)
isPrime[j] = false;
}
}
// Sum all values still marked prime
return isPrime.reduce(
(sum, prime, index) => prime ? sum + index : sum, 0
);
}
15.
Find the smallest common multiple of the provided parameters that can
be evenly divided by both, as well as by all sequential numbers in the
range between these parameters.
The range will be an array of two numbers that will not necessarily be in numerical order.
For example, if given 1 and 3, find the smallest common multiple of both 1 and 3 that is also evenly divisible by all numbers between 1 and 3. The answer here would be 6.
function smallestCommons(arr) {
// Setup
const [min, max] = arr.sort((a, b) => a - b);
const numberDivisors = max - min + 1;
// Largest possible value for SCM
let upperBound = 1;
for (let i = min; i <= max; i++) {
upperBound *= i;
}
// Test all multiples of 'max'
for (let multiple = max; multiple <= upperBound; multiple += max) {
// Check if every value in range divides 'multiple'
let divisorCount = 0;
for (let i = min; i <= max; i++) {
// Count divisors
if (multiple % i === 0) {
divisorCount += 1;
}
}
if (divisorCount === numberDivisors) {
return multiple;
}
}
}
smallestCommons([1, 5]);
or
function smallestCommons(arr) {
// Setup
const [min, max] = arr.sort((a, b) => a - b);
const range = Array(max - min + 1)
.fill(0)
.map((_, i) => i + min);
// Largest possible value for SCM
const upperBound = range.reduce((prod, curr) => prod * curr);
// Test all multiples of 'max'
for (let multiple = max; multiple <= upperBound; multiple += max) {
// Check if every value in range divides 'multiple'
const divisible = range.every((value) => multiple % value === 0);
if (divisible) {
return multiple;
}
}
}
smallestCommons([1, 5]);
or
function smallestCommons(arr) {
// Setup
const [min, max] = arr.sort((a, b) => a - b);
const range = Array(max - min + 1)
.fill(0)
.map((_, i) => i + min);
// GCD of two numbers
// https://en.wikipedia.org/wiki/Greatest_common_divisor#Euclid's_algorithm
const gcd = (a, b) => (b === 0) ? a : gcd(b, a % b);
// LCM of two numbers
// https://en.wikipedia.org/wiki/Least_common_multiple#Using_the_greatest_common_divisor
const lcm = (a, b) => a * b / gcd(a, b);
// LCM of multiple numbers
// https://en.wikipedia.org/wiki/Least_common_multiple#Other
return range.reduce((multiple, curr) => lcm(multiple, curr));
}
smallestCommons([1, 5]);
or
// Find the SCM of a range of numbers
function smallestCommons(arr) {
let primeFactors = {};
const [min, max] = arr.sort((a, b) => a - b);
for (let i = min; i <= max; i++) {
// Factorize number in range
let primes = getPrimeFactors(i);
for (let j in primes) {
// Add factor to set or update number of occurrences
if (!primeFactors[j] || primes[j] > primeFactors[j]) {
primeFactors[j] = primes[j]
}
}
}
// Build SCM from factorization
let multiple = 1;
for (let i in primeFactors) {
multiple *= i ** primeFactors[i]
}
return multiple;
}
// Compute prime factors of a number
function getPrimeFactors(num) {
const factors = {};
for (let prime = 2; prime <= num; prime++) {
// Count occurances of factor
// Note that composite values will not divide num
while ((num % prime) === 0) {
factors[prime] = (factors[prime]) ? factors[prime] + 1 : 1;
num /= prime;
}
}
return factors;
}
smallestCommons([1, 5]);
16.
Given the array arr, iterate through and remove each element starting from the first element (the 0 index) until the function func returns true when the iterated element is passed through it.
Then return the rest of the array once the condition is satisfied, otherwise, arr should be returned as an empty array.
function dropElements(arr, func) {
while (arr.length > 0 && !func(arr[0])) {
arr.shift();
}
return arr;
}
// test here
dropElements([1, 2, 3, 4], function(n) {
return n >= 3;
});
or
function dropElements(arr, func) {
let sliceIndex = arr.findIndex(func);
return arr.slice(sliceIndex >= 0 ? sliceIndex : arr.length);
}
// test here
dropElements([1, 2, 3, 4], function(n) {
return n >= 3;
});
or
function dropElements(arr, func) {
// drop them elements.
let originalLen = arr.length;
for (let i = 0; i < originalLen; i++) {
if (func(arr[0])) {
break;
} else {
arr.shift();
}
}
return arr;
}
// test here
dropElements([1, 2, 3, 4], function(n) {
return n >= 3;
});
or
function dropElements(arr, func, i = 0) {
return i < arr.length && !func(arr[i])
? (dropElements(arr.slice(i + 1), func, i))
: arr;
}
// test here
dropElements([1, 2, 3, 4], function(n) {
return n >= 3;
});
17.
Flatten a nested array. You must account for varying levels of nesting.
function steamrollArray(arr) {
const flattenedArray = [];
// Loop over array contents
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
// Recursively flatten entries that are arrays
// and push into the flattenedArray
flattenedArray.push(...steamrollArray(arr[i]));
} else {
// Copy contents that are not arrays
flattenedArray.push(arr[i]);
}
}
return flattenedArray;
};
// test here
steamrollArray([1, [2], [3, [[4]]]]);
or
function steamrollArray(arr) {
const flat = [].concat(...arr);
return flat.some(Array.isArray) ? steamrollArray(flat) : flat;
}
steamrollArray([1, [2], [3, [[4]]]]);
or
function steamrollArray(arr) {
return arr
.toString()
.replace(",,", ",") // "1,2,,3" => "1,2,3"
.split(",") // ['1','2','3']
.map(function(v) {
if (v == "[object Object]") {
// bring back empty objects
return {};
} else if (isNaN(v)) {
// if not a number (string)
return v;
} else {
return parseInt(v); // if a number in a string, convert it
}
});
}
or
function steamrollArray(val,flatArr=[]) {
val.forEach(item => {
if (Array.isArray(item)) steamrollArray(item, flatArr);
else flatArr.push(item);
});
return flatArr;
}
or
function steamrollArray(arr, flatArr = []) {
const elem = arr.pop();
return elem
? !Array.isArray(elem)
? steamrollArray(arr, [elem, ...flatArr])
: steamrollArray(arr.concat(elem), flatArr)
: flatArr;
}
18.
Return an English translated sentence of the passed binary string.
The binary string will be space separated.
function binaryAgent(str) {
var biString = str.split(" ");
var uniString = [];
/*using the radix (or base) parameter in parseInt, we can convert the binary
number to a decimal number while simultaneously converting to a char*/
for (var i = 0; i < biString.length; i++) {
uniString.push(String.fromCharCode(parseInt(biString[i], 2)));
}
// we then simply join the string
return uniString.join("");
}
// test here
binaryAgent(
"01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111
01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111"
);
or
function binaryAgent(str) {
// Separate the binary code by space.
str = str.split(" ");
var power;
var decValue = 0;
var sentence = "";
// Check each binary number from the array.
for (var s = 0; s < str.length; s++) {
// Check each bit from binary number
for (var t = 0; t < str[s].length; t++) {
// This only takes into consideration the active ones.
if (str[s][t] == 1) {
// This is quivalent to 2 ** position
power = Math.pow(2, +str[s].length - t - 1);
decValue += power;
// Record the decimal value by adding the number to the previous one.
}
}
// After the binary number is converted to decimal, convert it to string and store
sentence += String.fromCharCode(decValue);
// Reset decimal value for next binary number.
decValue = 0;
}
return sentence;
}
// test here
binaryAgent(
"01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111"
);
or
function binaryAgent(str) {
return String.fromCharCode(
...str.split(" ").map(function(char) {
return parseInt(char, 2);
})
);
}
// test here
binaryAgent(
"01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111"
);
19.
Check if the predicate (second argument) is truthy on all elements of a collection (first argument).
In other words, you are given an array collection of objects. The predicate pre will be an object property and you need to return true if its value is truthy. Otherwise, return false.
In JavaScript, truthy values are values that translate to true when evaluated in a Boolean context.
Remember, you can access object properties through either dot notation or [] notation.
function truthCheck(collection, pre) {
// Create a counter to check how many are true.
let counter = 0;
// Check for each object
for (let c in collection) {
// If it is has property and value is truthy
if (collection[c].hasOwnProperty(pre) && Boolean(collection[c][pre])) {
counter++;
}
}
// Outside the loop, check to see if we got true for all of them and return true or false
return counter == collection.length;
}
truthCheck([{ name: "Quincy", role: "Founder", isBot: false }, { name: "Naomi", role: "", isBot: false }, { name: "Camperbot", role: "Bot", isBot: true }], "isBot");
or
function truthCheck(collection, pre) {
return collection.every(function (element) {
return element.hasOwnProperty(pre) && Boolean(element[pre]);
});
}
truthCheck([{ name: "Quincy", role: "Founder", isBot: false }, { name: "Naomi", role: "", isBot: false }, { name: "Camperbot", role: "Bot", isBot: true }], "isBot");
or
function truthCheck(collection, pre) {
// Is everyone being true?
return collection.every(obj => obj[pre]);
}
truthCheck([{ name: "Quincy", role: "Founder", isBot: false }, { name: "Naomi", role: "", isBot: false }, { name: "Camperbot", role: "Bot", isBot: true }], "isBot");
20.
Create a function that sums two arguments together. If only one
argument is provided, then return a function that expects one argument
and returns the sum.
For example, addTogether(2, 3) should return 5, and addTogether(2) should return a function.
Calling this returned function with a single argument will then return the sum:
var sumTwoAnd = addTogether(2);
sumTwoAnd(3) returns 5.
If either argument isn't a valid number, return undefined.
function addTogether() {
const [first, second] = arguments;
if (typeof(first) !== "number")
return undefined;
if (second === undefined)
return (second) => addTogether(first, second);
if (typeof(second) !== "number")
return undefined;
return first + second;
}
or
function addTogether() {
const [first, second] = arguments;
// First argument is not a number
if (typeof(first) !== "number") {
return undefined;
}
// First argument is a number
// and second argument is not defined
else if (second === undefined) {
function addSecond(second) {
// New argument is not a number
if (typeof(second) !== "number") {
return undefined;
}
// New argument is a number
else {
return first + second;
}
}
// Note: returning a *function*
return addSecond;
}
// First argument is a number
// and second argument is not a number
else if (typeof(second) !== "number") {
return undefined;
}
// First argument is a number
// and second argument is a number
else {
return first + second;
}
}
21.
Fill in the object constructor with the following methods below:
getFirstName()
getLastName()
getFullName()
setFirstName(first)
setLastName(last)
setFullName(firstAndLast)
Run the tests to see the expected output for each method. The methods
that take an argument must accept only one argument and it has to be a
string. These methods must be the only available means of interacting
with the object.
var Person = function(firstAndLast) {
let fullName = firstAndLast;
this.getFirstName = function() {
return fullName.split(" ")[0];
};
this.getLastName = function() {
return fullName.split(" ")[1];
};
this.getFullName = function() {
return fullName;
};
this.setFirstName = function(name) {
fullName = name + " " + fullName.split(" ")[1];
};
this.setLastName = function(name) {
fullName = fullName.split(" ")[0] + " " + name;
};
this.setFullName = function(name) {
fullName = name;
};
};
var bob = new Person("Bob Ross");
bob.getFullName();
22.
Hint 1
The formula needed is:

Hint 2
Use Math.round() to round up to the next whole number as requested. Using Math.ceil() will let you pass the first test but fail the second one.
function orbitalPeriod(arr) {
const GM = 398600.4418;
const earthRadius = 6367.4447;
const a = 2 * Math.PI;
const newArr = [];
const getOrbPeriod = function(obj) {
const c = Math.pow(earthRadius + obj.avgAlt, 3);
const b = Math.sqrt(c / GM);
const orbPeriod = Math.round(a * b);
// create new object
return {name: obj.name, orbitalPeriod: orbPeriod};
};
for (let elem in arr) {
newArr.push(getOrbPeriod(arr[elem]));
}
return newArr;
}
or
function orbitalPeriod(arr) {
const GM = 398600.4418;
const earthRadius = 6367.4447;
const newArr = [];
//Looping through each key in arr object
for (let elem in arr) {
//Rounding off the orbital period value
const orbitalPer = Math.round(
2 * Math.PI * Math.sqrt(Math.pow(arr[elem].avgAlt + earthRadius, 3) / GM)
);
//Adding new object with orbitalPeriod property
newArr.push({name: arr[elem].name, orbitalPeriod: orbitalPer});
}
return newArr;
}
// test here
orbitalPeriod([{ name: "sputnik", avgAlt: 35873.5553 }]);
or
function orbitalPeriod(arr) {
const GM = 398600.4418;
const earthRadius = 6367.4447;
// Create new array to prevent modification of the original
const newArr = JSON.parse(JSON.stringify(arr));
// Loop through each item in the array arr
newArr.forEach(function(item) {
// Calculate the Orbital period value
const tmp = Math.round(
2 * Math.PI * Math.sqrt(Math.pow(earthRadius + item.avgAlt, 3) / GM)
);
//Delete the avgAlt property
delete item.avgAlt;
//Add orbitalPeriod property
item.orbitalPeriod = tmp;
});
return newArr;
}
or
function orbitalPeriod(arr) {
const GM = 398600.4418;
const earthRadius = 6367.4447;
return arr.map(({ name, avgAlt }) => {
const earth = earthRadius + avgAlt;
const orbitalPeriod = Math.round(2 * Math.PI * Math.sqrt(Math.pow(earth, 3)/GM));
return { name, orbitalPeriod };
});
}
orbitalPeriod([{name : "sputnik", avgAlt : 35873.5553}]);