Freecodecamp Algorithms
Basic Algorithm Scripting
Truncate a String
Basic Algorithm Scripting: Truncate a String | freeCodeCamp.org
My solution (substring + concat)
function truncateString(str, num) {
if (str.length <= num) { return str }
return str.substring(0, num).concat('...')
}
console.log(truncateString('A-tisket a-tasket A green and yellow basket', 8))
Solution with slice()
function truncateString(str, num) {
if (str.length <= num) { return str }
return str.slice(0, num).concat('...')
}
console.log(truncateString('A-tisket a-tasket A green and yellow basket', 8))
Repeat a String
- Basic Algorithm Scripting: Repeat a String Repeat a String | freeCodeCamp.org
- Three ways to repeat a string in JavaScript
My solution (padEnd)
function repeatStringNumTimes(str, num) {
if (num <= 0) { return '' }
else { return str.padEnd(num * str.length, str) }
}
console.log(repeatStringNumTimes('abc', 2))
Solution with repeat()
function repeatStringNumTimes(str, num) {
if (num <= 0) { return '' }
else { return str.repeat(num) }
}
console.log(repeatStringNumTimes('abc', 2))
Solution with while loop
function repeatStringNumTimes(str, num) {
let repeatedStr = ''
while (num > 0) {
repeatedStr = repeatedStr + str
num--
}
return repeatedStr
}
console.log(repeatStringNumTimes('abc', 2))
Recursive solution
function repeatStringNumTimes(str, num) {
if (num < 0) { return '' }
if (num === 1) { return str }
else { return str + repeatStringNumTimes(str, num - 1) }
}
console.log(repeatStringNumTimes('abc', 20))
Find the Longest Word in a String
Basic Algorithm Scripting: Find the Longest Word in a String | freeCodeCamp.org
My solution
function findLongestWordLength(str) {
const strArray = str.split(' ')
const strLength = strArray.length
let numArray = []
for (let a = 0; a < strLength; a++) {
numArray.push(strArray[a].length)
}
return Math.max(...numArray)
}
console.log(findLongestWordLength('The quick brown fox jumped over the lazy dog'))
Alternative for loop
function findLongestWordLength(str) {
const strArray = str.split(' ')
const strLength = strArray.length
let longestWordLength = 0
for (let a = 0; a < strLength; a++) {
if (strArray[a].length > longestWordLength) {
longestWordLength = strArray[a].length
}
}
return longestWordLength
}
console.log(findLongestWordLength('The quick brown fox jumped over the lazy dog'))
Solution with sort()
function findLongestWordLength(str) {
let longestWord = str.split(' ').sort((first, second) => {
return second.length - first.length
})
return longestWord[0].length
}
console.log(findLongestWordLength('The quick brown fox jumped over the lazy dog'))
Solution with reduce()
function findLongestWordLength(str) {
let longestWord = str.split(' ').reduce(function (a, b) {
if (b.length > a.length) { return b }
else { return a }
}, '')
return longestWord.length
}
console.log(findLongestWordLength('The quick brown fox jumped over the lazy dog'))
References:
- Math.max() - MDN
- Three Ways to Find the Longest Word in a String in JavaScript
- Array.prototype.sort() - MDN
Mutations
Basic Algorithm Scripting: Mutations | freeCodeCamp.org
First attempt (failed all tests)
function mutation(arr) {
let str1 = arr[0]
let arr2 = arr[1].split('')
for (let i = 0; i < arr2.length; i++) {
if (str1.includes(arr2[i]) == false) return false
}
return true
}
mutation(['hello', 'hey'])
Second attempt (passed)
function mutation(arr) {
let str1 = arr[0].toLowerCase()
let arr2 = arr[1].split('')
for (let i = 0; i < arr2.length; i++) {
if (str1.includes(arr2[i].toLowerCase()) == false) return false
}
return true
}
console.log(mutation(['Mary', 'Army']))
Slice and Splice
- Basic Algorithm Scripting: Slice and Splice | freeCodeCamp.org
- freeCodeCamp Challenge Guide: Slice and Splice
Two arrays and an index n. Insert first array into second array at index n. Both original arrays stay unchanged.
function frankenSplice(arr1, arr2, n) {
const arr3 = arr2.slice()
arr3.splice(n, 0, ...arr1)
return arr3
}
console.log(frankenSplice([1, 2, 3], [4, 5, 6], 1))
function frankenSplice(arr1, arr2, n) {
const arr3 = arr2.slice()
arr3.splice(n, 0, arr1)
return arr3.flat()
}
console.log(frankenSplice([1, 2, 3], [4, 5, 6], 1))
function frankenSplice(arr1, arr2, n) {
let localArray = arr2.slice()
for (let i = 0; i < arr1.length; i++) {
localArray.splice(n, 0, arr1[i])
n++
}
return localArray
}
Intermediate Algorithm Scripting
Sum All Numbers in a Range
Intermediate Algorithm Scripting: Sum All Numbers in a Range | freeCodeCamp.org
My solution - arithmetic series formula:
function sumAll(arr) {
const newArr = arr.sort((a, b) => a - b)
return ((newArr[1] + newArr[0]) * (newArr[1] - newArr[0] + 1)) / 2
}
sumAll([5, 10])
(上底 + 下底) x 高 / 2
Sum All Odd Fibonacci Numbers
Intermediate Algorithm Scripting: Sum All Odd Fibonacci Numbers | freeCodeCamp.org
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
}
function sumFibs(num) {
if (num <= 0) return 0
const arrFib = [1, 1]
let nextFib = 0
while ((nextFib = arrFib[0] + arrFib[1]) <= num) {
arrFib.unshift(nextFib)
}
return arrFib.filter((x) => x % 2 != 0).reduce((a, b) => a + b)
}
Sum All Primes
Intermediate Algorithm Scripting: Sum All Primes | freeCodeCamp.org
function primes(n) {
if (isNaN(n) || n < 1 || Math.floor(n) != n) {
return 'The input number must be a positive integer, please enter a correct value'
}
if (n === 2) { return true }
if (n % 2 === 0 || n === 1) { return false }
for (let i = 3, limit = Math.sqrt(n); i <= limit; i += 2) {
if (n % i === 0) { return false }
}
return true
}
function sumPrimes(num) {
let sum = 0
for (let i = 2; i <= num; i++) {
if (primes(i)) { sum += i }
}
return sum
}
console.log(sumPrimes(977))
References: https://forum.freecodecamp.org/t/freecodecamp-challenge-guide-sum-all-primes/16085, https://stackoverflow.com/a/12287599/12539782
Alternative solutions:
function sumPrimes(num) {
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)
}
function sumPrimes(num) {
let isPrime = Array(num + 1).fill(true)
isPrime[0] = false
isPrime[1] = false
for (let i = 2; i <= Math.sqrt(num); i++) {
if (isPrime[i]) {
for (let j = i * i; j <= num; j += i) isPrime[j] = false
}
}
return isPrime.reduce((sum, prime, index) => (prime ? sum + index : sum), 0)
}
Spinal Tap Case
Intermediate Algorithm Scripting: Spinal Tap Case | freeCodeCamp.org
Key regex: str.replace(/([a-z])([A-Z])/g, '$1 $2')
function spinalCase(str) {
let regex = /\s+|_+/g
str = str.replace(/([a-z])([A-Z])/g, '$1 $2')
return str.replace(regex, '-').toLowerCase()
}
console.log(spinalCase('ThisIsSpinalTap'))
function spinalCase(str) {
str = str.replace(/([a-z])([A-Z])/g, '$1 $2')
return str
.toLowerCase()
.split(/(?:_| )+/)
.join('-')
}
function spinalCase(str) {
return str
.split(/\s|_|(?=[A-Z])/)
.join('-')
.toLowerCase()
}
Sorted Union
Intermediate Algorithm Scripting: Sorted Union | freeCodeCamp.org
function uniteUnique(arr) {
for (let i = 1; i < arguments.length; i++) {
arr.push(arguments[i])
}
return Array.from(new Set(arr.flat().join('').split('')))
.toString()
.split(',')
.map((x) => Number(x))
}
console.log(uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]))
function uniteUnique(arr) {
const finalArray = []
for (let i = 0; i < arguments.length; i++) {
const arrayArguments = arguments[i]
for (let j = 0; j < arrayArguments.length; j++) {
let indexValue = arrayArguments[j]
if (finalArray.indexOf(indexValue) < 0) {
finalArray.push(indexValue)
}
}
}
return finalArray
}
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
}
function uniteUnique(...arr) {
return [...new Set(arr.flat())]
}
function uniteUnique() {
return [...arguments]
.flat()
.filter((item, ind, arr) => arr.indexOf(item) === ind)
}
Steamroller (Flatten Array)
- Intermediate Algorithm Scripting: Steamroller | freeCodeCamp.org
- freeCodeCamp Challenge Guide: Steamroller
function steamrollArray(arr) {
return flatDeep(arr, Infinity)
}
function flatDeep(arr, d = 1) {
return d > 0
? arr.reduce(
(acc, val) =>
acc.concat(Array.isArray(val) ? flatDeep(val, d - 1) : val),
[]
)
: arr.slice()
}
console.log(steamrollArray(['a', ['b']]))
Missing Letters
Intermediate Algorithm Scripting: Missing letters | freeCodeCamp.org
My solution:
function fearNotLetter(str) {
const allLetters = 'abcdefghijklmnopqrstuvwxyz'
const index = allLetters.indexOf(str[0])
if (str.match(/a-z/)) { return undefined }
for (let i = 0; i < str.length; i++) {
if (str[i] !== allLetters[index + i]) {
return allLetters[index + i]
}
}
}
function fearNotLetter(str) {
for (let i = 0; i < str.length; i++) {
let code = str.charCodeAt(i)
if (code !== str.charCodeAt(0) + i) {
return String.fromCharCode(code - 1)
}
}
return undefined
}
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
}
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)
}
}
}
Pig Latin
- Intermediate Algorithm Scripting: Pig Latin | freeCodeCamp.org
- freeCodeCamp Challenge Guide: Pig Latin
Rules:
- If word starts with consonant(s), move them to the end and add
ay - If word starts with a vowel, add
wayto the end
function translatePigLatin(str) {
let consonantRegex = /^[^aeiou]+/
let myConsonants = str.match(consonantRegex)
return myConsonants !== null
? str.replace(myConsonants, '').concat(myConsonants).concat('ay')
: str.concat('way')
}
console.log(translatePigLatin('paragraphs'))
function translatePigLatin(str) {
let pigLatin = ''
let regex = /[aeiou]/gi
if (str[0].match(regex)) {
pigLatin = str + 'way'
} else if (str.match(regex) === null) {
pigLatin = str + 'ay'
} else {
let vowelIndex = str.indexOf(str.match(regex)[0])
pigLatin = str.substring(vowelIndex) + str.substring(0, vowelIndex) + 'ay'
}
return pigLatin
}
Search and Replace
- Intermediate Algorithm Scripting: Search and Replace | freeCodeCamp.org
- freeCodeCamp Challenge Guide: Search and Replace
Given three parameters: sentence, word to replace, replacement word. If the word to replace starts with uppercase, the replacement should also start with uppercase.
function myReplace(str, before, after) {
const index = str.indexOf(before)
if (str[index] === str[index].toUpperCase()) {
after = after.charAt(0).toUpperCase() + after.slice(1)
} else {
after = after.charAt(0).toLowerCase() + after.slice(1)
}
return str.replace(before, after)
}
function myReplace(str, before, after) {
if (/^[A-Z]/.test(before)) {
after = after[0].toUpperCase() + after.slice(1)
} else {
after = after[0].toLowerCase() + after.slice(1)
}
return str.replace(before, after)
}
Make a Person
- Intermediate Algorithm Scripting: Make a Person | freeCodeCamp.org
- freeCodeCamp Challenge Guide: Make a Person
const 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 }
}
const bob = new Person('Bob Ross')
bob.getFullName()
Map the Debris
- Intermediate Algorithm Scripting: Map the Debris | freeCodeCamp.org
- freeCodeCamp Challenge Guide: Map the Debris
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)
return { name: obj.name, orbitalPeriod: orbPeriod }
}
for (let elem in arr) {
newArr.push(getOrbPeriod(arr[elem]))
}
return newArr
}
console.log(orbitalPeriod([{ name: 'sputnik', avgAlt: 35873.5553 }]))
Seek and Destroy
Intermediate Algorithm Scripting: Seek and Destroy | freeCodeCamp.org
function destroyer(arr) {
let i = 1
while (i < arguments.length) {
if (arr.includes(arguments[i])) {
arr = arr.filter((item) => item !== arguments[i])
} else {
++i
}
}
return arr
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3))
References: https://stackoverflow.com/a/5767357/12539782, https://stackoverflow.com/a/20690490/12539782
Smallest Common Multiple
- Intermediate Algorithm Scripting: Smallest Common Multiple | freeCodeCamp.org
- freeCodeCamp Challenge Guide: Smallest Common Multiple
Using GCD / LCM:
function gcd(a, b) {
if (b === 0) { return a }
else { return gcd(b, a % b) }
}
function lcm(a, b) {
return (a * b) / gcd(a, b)
}
function smallestCommons(arr) {
let min = Math.min(...arr)
let max = Math.max(...arr)
let array = []
for (min; min <= max; min++) {
array.push(min)
}
const lowestCommon = (currentValue) => n % currentValue === 0
let common = false
let n = max * (max - 1)
common = array.every(lowestCommon)
while (common === false) {
n++
common = array.every(lowestCommon)
}
return n
}
console.log(smallestCommons([2, 10]))
Using reduce:
function lcmOfRange(a, b) {
let result = a
for (let i = a + 1; i < b; i++) {
result = lcm(result, i)
}
return result
}
function lcmOfRange(a, b) {
let range = []
for (let i = a; i <= b; i++) {
range.push(i)
}
return lcmOfList(range)
}
function lcmOfList(arr) {
return arr.reduce(lcm)
}
JavaScript Algorithms and Data Structures Projects
Palindrome Checker
JavaScript Algorithms and Data Structures Projects: Palindrome Checker | freeCodeCamp.org
Requirements:
- Ignore punctuation, case, and spaces
- Remove all non-alphanumeric characters
- Convert all characters to same case
My solution:
function palindrome(str) {
str = str.replace(/[^A-Za-z0-9]/g, '').toLowerCase()
if (str.length % 2 !== 0) {
return (
str.substring(0, str.length / 2) ===
str
.substring(str.length / 2 + 1, str.length)
.split('')
.reverse()
.join('')
)
} else {
return (
str.substring(0, str.length / 2) ===
str
.substring(str.length / 2, str.length)
.split('')
.reverse()
.join('')
)
}
}
console.log(palindrome('A man, a plan, a canal. Panama'))
Roman Numeral Converter
- JavaScript Algorithms and Data Structures Projects: Roman Numeral Converter | freeCodeCamp.org
- Roman Numerals
My solution:
function convertToRoman(num) {
if (num >= 1000) {
let a = num / 1000
let int = Math.floor(a)
if (a == 1) { return 'M' }
if (a > 1) { return 'M'.repeat(int) + thousand(num % 1000) }
} else if (num < 1000 && num >= 100) {
return thousand(num)
} else if (num < 100 && num >= 10) {
return hundred(num)
} else {
return ten(num)
}
}
function thousand(num) {
let a = num / 100
let int = Math.floor(a)
if (a == 4) { return 'CD' }
else if (a == 5) { return 'D' }
else if (a == 9) { return 'CM' }
else if (a < 4) { return 'C'.repeat(a) + hundred(num - int * 100) }
else if (a > 4 && a < 5) { return 'CD' + hundred(num - int * 100) }
else if (a > 5 && a < 9) {
return 'D' + 'C'.repeat(Math.floor((num - 500) / 100)) + hundred(num - int * 100)
}
else if (a > 9 && a < 10) { return 'CM' + hundred(num - int * 100) }
}
function hundred(num) {
if (num == 40) { return 'XL' }
else if (num == 90) { return 'XC' }
else if (num < 40) { return 'X'.repeat(num / 10) + ten(num % 10) }
else if (num > 40 && num < 50) { return 'XL' + ten(num % 10) }
else if (num == 50) { return 'L' }
else if (num > 50 && num < 90) { return 'L' + 'X'.repeat((num - 50) / 10) + ten(num % 10) }
else if (num > 90) { return 'XC' + ten(num % 90) }
}
function ten(num) {
if (num == 4) { return 'IV' }
else if (num == 9) { return 'IX' }
else if (num < 4) { return 'I'.repeat(num) }
else if (num > 4 && num < 9) { return 'V' + 'I'.repeat(num - 5) }
}
console.log(convertToRoman(649))
Telephone Number Validator
JavaScript Algorithms and Data Structures Projects: Telephone Number Validator | freeCodeCamp.org
function telephoneCheck(str) {
let reg1 = /^(1\s?)?\d{3}[-\s]?\d{3}[-\s]?\d{4}$/
let reg2 = /^(1\s?)?\(\d{3}\)\s?\d{3}[-\s]?\d{4}$/
if (reg1.test(str)) { return true }
else { return reg2.test(str) ? true : false }
}
telephoneCheck('555-555-5555')