├── .gitignore ├── Beginner ├── README.md ├── capSentence │ ├── index-SOLUTION.js │ ├── index-START.js │ └── test.js ├── chunkArray │ ├── index-FINISHED.js │ ├── index-START.js │ └── test.js ├── factorial │ ├── index-SOLUTION.js │ ├── index-START.js │ └── test.js ├── falsyBouncer │ ├── index-SOLUTION.js │ ├── index-START.js │ └── test.js ├── fibonacci │ ├── index-SOLUTION.js │ ├── index-START.js │ └── test.js ├── fizzBuzz │ ├── index-SOLUTION.js │ ├── index-START.js │ └── test.js ├── hammingDistance │ ├── index-SOLUTION.js │ ├── index-START.js │ └── test.js ├── isAnagram │ ├── index-SOLUTION.js │ ├── index-START.js │ └── test.js ├── longestWord │ ├── index-SOLUTION.js │ ├── index-START.js │ └── test.js ├── maxRecurringChar │ ├── index-SOLUTION.js │ ├── index-START.js │ └── test.js ├── mergeArrays │ ├── index-FINISHED.js │ ├── index-START.js │ └── test.js ├── palindromeChecker │ ├── index-SOLUTION.js │ ├── index-START.js │ └── test.js ├── reverseString │ ├── index-SOLUTION.js │ ├── index-START.js │ └── test.js ├── searchReplace │ ├── index-SOLUTION.js │ ├── index-START.js │ └── test.js ├── vowelsCounter │ ├── index-SOLUTION.js │ ├── index-START.js │ └── test.js └── whereIBelong │ ├── index-SOLUTION.js │ ├── index-START.js │ └── test.js ├── README.md ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /Beginner/README.md: -------------------------------------------------------------------------------- 1 | # This contains all beginner algorithms and data structures -------------------------------------------------------------------------------- /Beginner/capSentence/index-SOLUTION.js: -------------------------------------------------------------------------------- 1 | // USING A FOREACH LOOP 2 | function capSentence(text) { 3 | let wordsArray = text.toLowerCase().split(' ') 4 | let capsArray = [] 5 | 6 | wordsArray.forEach(word => { 7 | capsArray.push(word[0].toUpperCase() + word.slice(1)) 8 | }); 9 | 10 | return capsArray.join(' ') 11 | } 12 | 13 | 14 | // USING .MAP() AND .SLICE() 15 | 16 | function capSentence(text) { 17 | let wordsArray = text.toLowerCase().split(' ') 18 | let capsArray = wordsArray.map(word=>{ 19 | return word[0].toUpperCase() + word.slice(1) 20 | }) 21 | 22 | return capsArray.join(' ') 23 | } 24 | 25 | 26 | // USING .MAP() AND .REPLACE() 27 | 28 | 29 | function capSentence(text) { 30 | let wordsArray = text.toLowerCase().split(' ') 31 | 32 | let capsArray = wordsArray.map( word=>{ 33 | return word.replace(word[0], word[0].toUpperCase()) 34 | }) 35 | 36 | return capsArray.join(' ') 37 | } 38 | 39 | -------------------------------------------------------------------------------- /Beginner/capSentence/index-START.js: -------------------------------------------------------------------------------- 1 | /* CHALLENGE 2 | Given a sentence containing two or more words, 3 | return the equivalent of the sentence when capitalised. E.g 4 | capSentence('the tales of scotch!') // would return 'The Tales Of Scotch!' 5 | */ 6 | 7 | 8 | 9 | 10 | function capSentence(text) { 11 | // Code goes here 12 | } 13 | 14 | 15 | 16 | module.exports = capSentence -------------------------------------------------------------------------------- /Beginner/capSentence/test.js: -------------------------------------------------------------------------------- 1 | const capSentence = require('./index-START') 2 | 3 | test('capSentence is a function', () => { 4 | expect(typeof capSentence).toEqual('function') 5 | }) 6 | 7 | test('capitalizes the first letter of each word in a lowercase sentence', () => { 8 | expect(capSentence('i must confess, this is so much fun.')).toEqual( 9 | 'I Must Confess, This Is So Much Fun.' 10 | ) 11 | }) 12 | 13 | test('capitalizes the first letter of each word in an uppercase sentence', () => { 14 | expect(capSentence('THIS ONE IS FOR SCOTCH.')).toEqual( 15 | 'This One Is For Scotch.' 16 | ) 17 | }) 18 | 19 | test('capitalizes the first letter of each word in mixed cased sentences', () => { 20 | expect(capSentence('i woulD lOVe to spEAk at jsconF.')).toEqual( 21 | 'I Would Love To Speak At Jsconf.' 22 | ) 23 | }) -------------------------------------------------------------------------------- /Beginner/chunkArray/index-FINISHED.js: -------------------------------------------------------------------------------- 1 | // LOOPING THROUGH THE ARRAY 2 | 3 | function chunkArray(array, size) { 4 | let result = [] 5 | 6 | for (value of array){ 7 | 8 | let lastArray = result[result.length -1 ] 9 | if(!lastArray || lastArray.length == size){ 10 | result.push([value]) 11 | }else{ 12 | lastArray.push(value) 13 | } 14 | } 15 | 16 | return result 17 | } 18 | 19 | // LOOPING THROUGH THE NUMBER OF CHUNKS 20 | 21 | function chunkArray(array, size) { 22 | let result = [] 23 | 24 | let arrayCopy = [...array] 25 | 26 | while (arrayCopy.length > 0) { 27 | result.push(arrayCopy.splice(0, size)) 28 | } 29 | 30 | return result 31 | } 32 | 33 | 34 | // USING .SLICE() 35 | 36 | function chunkArray(array, size) { 37 | let result = [] 38 | 39 | for (i = 0; i < array.length; i += size) { 40 | let chunk = array.slice(i, i + size) 41 | result.push(chunk) 42 | } 43 | 44 | return result 45 | } 46 | 47 | //RECURSION 48 | 49 | function chunkArray(array, size) { 50 | if(array.length <= size){ 51 | return [array] 52 | } 53 | return [array.slice(0,size), ...chunkArray(array.slice(size), size)] 54 | } -------------------------------------------------------------------------------- /Beginner/chunkArray/index-START.js: -------------------------------------------------------------------------------- 1 | /* 2 | Given two or more arrays, write a function that combines 3 | their elements into one array without any repetition. 4 | E.g mergeArrays([1,2,3,3,3], [1,4,5,2]) // should return [1,2,3,4,5] 5 | */ 6 | 7 | function chunkArray(array, size) { 8 | // Code goes here 9 | } 10 | 11 | 12 | module.exports = chunkArray -------------------------------------------------------------------------------- /Beginner/chunkArray/test.js: -------------------------------------------------------------------------------- 1 | const chunkArray = require('./index-START'); 2 | 3 | test('chunkArray is a function', () => { 4 | expect(typeof chunkArray).toEqual('function'); 5 | }); 6 | 7 | test('Chunks array of 10 elements in twos', () => { 8 | const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 9 | const chunkedArray = chunkArray(arr, 2); 10 | 11 | expect(chunkedArray).toEqual([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]); 12 | }); 13 | 14 | test('Chunks array of 13 elements in five and some', () => { 15 | const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; 16 | const chunkedArray = chunkArray(arr, 5); 17 | 18 | expect(chunkedArray).toEqual([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13]]); 19 | }); 20 | -------------------------------------------------------------------------------- /Beginner/factorial/index-SOLUTION.js: -------------------------------------------------------------------------------- 1 | // USING A FOR LOOP 2 | 3 | function factorial(n) { 4 | if (n <= 1) { 5 | return 1 6 | } 7 | for (let i = n - 1; i >= 1; i--) { 8 | n *= i; 9 | } 10 | return n; 11 | } 12 | 13 | // USING A WHILE LOOP 14 | 15 | function factorial(n) { 16 | var result = n 17 | if (n <= 1) { 18 | return 1 19 | } 20 | while (n > 1) { 21 | n-- 22 | result *= n 23 | } 24 | return result 25 | } 26 | 27 | // USING RECURSION 28 | 29 | function factorial(n) { 30 | if (n === 0) { 31 | return 1 32 | } 33 | return n * factorial(n - 1) 34 | } 35 | 36 | // USING MEMOIZATION 37 | 38 | function factorial(n, memo) { 39 | memo = memo || {} 40 | if(memo[n]){ 41 | return memo[n] 42 | } 43 | if (n === 0) { 44 | return 1 45 | } 46 | return memo[n] = n * factorial(n - 1, memo) 47 | } -------------------------------------------------------------------------------- /Beginner/factorial/index-START.js: -------------------------------------------------------------------------------- 1 | /* 2 | Write a function that returns the factorial of 3 | the provided integer(n). E.g 4 | factorial(5) // should return 120 5 | */ 6 | 7 | 8 | function factorial(n, memo) { 9 | memo = memo || {} 10 | if(memo[n]){ 11 | return memo[n] 12 | } 13 | if (n === 0) { 14 | return 1 15 | } 16 | return memo[n] = n * factorial(n - 1, memo) 17 | } 18 | 19 | module.exports = factorial -------------------------------------------------------------------------------- /Beginner/factorial/test.js: -------------------------------------------------------------------------------- 1 | const factorial = require('./index-START') 2 | 3 | test('factorial is a function', () => { 4 | expect(typeof factorial).toEqual('function') 5 | }) 6 | 7 | test('returns the factorial of 20', () => { 8 | expect(factorial(10)).toEqual(3628800) 9 | }) 10 | 11 | test('returns the factorial of 20', () => { 12 | expect(factorial(20)).toEqual(2432902008176640000) 13 | }) 14 | -------------------------------------------------------------------------------- /Beginner/falsyBouncer/index-SOLUTION.js: -------------------------------------------------------------------------------- 1 | // USING A FOR OF LOOP 2 | 3 | function falsyBouncer(array) { 4 | let result =[] 5 | 6 | for (value of array){ 7 | if(value){ 8 | result.push(value) 9 | } 10 | } 11 | 12 | return result 13 | } 14 | 15 | // USING .FILTER() 16 | 17 | function falsyBouncer(array) { 18 | return array.filter((value) =>{ 19 | return Boolean(value) 20 | }) 21 | } 22 | 23 | -------------------------------------------------------------------------------- /Beginner/falsyBouncer/index-START.js: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array, remove all falsy values from the array 3 | and return an array of only truthy values. 4 | 5 | E.g falsyBouncer([1, 0, null, '', 5]) // should return [1,5] 6 | */ 7 | 8 | 9 | function falsyBouncer(array) { 10 | // Code goes here 11 | } 12 | 13 | 14 | module.exports = falsyBouncer -------------------------------------------------------------------------------- /Beginner/falsyBouncer/test.js: -------------------------------------------------------------------------------- 1 | const falsyBouncer = require('./index-START'); 2 | 3 | test('falsyBouncer is a function', () => { 4 | expect(typeof falsyBouncer).toEqual('function'); 5 | }); 6 | 7 | test('Removes all falsy values', () => { 8 | expect(falsyBouncer([1, 0, null, '', 5])).toEqual([1, 5]); 9 | }) 10 | 11 | test('Removes all falsy values', () => { 12 | expect(falsyBouncer([NaN, 0, null, '', undefined])).toEqual([]); 13 | }) 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Beginner/fibonacci/index-SOLUTION.js: -------------------------------------------------------------------------------- 1 | // AN ITERATIVE APPROACH 2 | 3 | function fibonacci(n) { 4 | let previous = 1, 5 | current = 1 6 | 7 | if (n <= 1) { 8 | return 1 9 | } else { 10 | let counter = n - 1 11 | 12 | while (counter) { 13 | let temp = current 14 | current += previous 15 | previous = temp 16 | counter -- 17 | } 18 | } 19 | return current 20 | } 21 | 22 | 23 | // A RECURSIVE SOLUTION 24 | 25 | function fibonacci(n) { 26 | if (n <= 1) { 27 | return 1 28 | } 29 | return fibonacci(n - 1) + fibonacci(n - 2) 30 | } 31 | 32 | // USING MEMOIZATION 33 | 34 | function fibonacci(n,memo) { 35 | memo = memo || {} 36 | 37 | if (memo[n]) { 38 | return memo[n] 39 | } 40 | if (n <= 1) { 41 | return 1 42 | } 43 | 44 | return memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo) 45 | } -------------------------------------------------------------------------------- /Beginner/fibonacci/index-START.js: -------------------------------------------------------------------------------- 1 | /* 2 | Write a function to return the nth element in Fibonacci sequence, 3 | where the sequence is: 4 | [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …] 5 | */ 6 | 7 | 8 | function fibonacci(n) { 9 | // Code goes here 10 | } 11 | 12 | module.exports = fibonacci -------------------------------------------------------------------------------- /Beginner/fibonacci/test.js: -------------------------------------------------------------------------------- 1 | const fibonacci = require('./index-START') 2 | 3 | test('fibonacci is a function', () => { 4 | expect(typeof fibonacci).toEqual('function') 5 | }) 6 | 7 | test('returns the 6th fibonacci number', () => { 8 | expect(fibonacci(6)).toEqual(13) 9 | }) 10 | 11 | test('returns the 20th fibonacci number', () => { 12 | expect(fibonacci(20)).toEqual(10946) 13 | }) 14 | -------------------------------------------------------------------------------- /Beginner/fizzBuzz/index-SOLUTION.js: -------------------------------------------------------------------------------- 1 | // FOR LOOP SOLUTION 2 | 3 | function fizzBuzz(n) { 4 | for (let i = 1; i <= n; i++) { 5 | // Is a multiple of 3 and 5? 6 | if (i % 15 === 0) { 7 | console.log('fizzbuzz') 8 | } else if (i % 3 === 0) { 9 | // Is a multiple of 3? 10 | console.log('fizz') 11 | } else if (i % 5 === 0) { 12 | // Is a multiple of 5? 13 | console.log('buzz') 14 | } else { 15 | // Is neither of the above? 16 | console.log(i) 17 | } 18 | } 19 | } 20 | 21 | 22 | // CLEANER AND SMALLER 23 | 24 | function fizzBuzz(n) { 25 | for (let i = 0; i < n;) 26 | console.log((++i % 3 ? '' : 'fizz') + (i % 5 ? '' : 'buzz') || i) 27 | } 28 | -------------------------------------------------------------------------------- /Beginner/fizzBuzz/index-START.js: -------------------------------------------------------------------------------- 1 | /* 2 | Write a program that prints the numbers from 1 to n. But for 3 | multiples of three print “Fizz” instead of the number and for 4 | the multiples of five print “Buzz”. For numbers which are 5 | multiples of both three and five print “FizzBuzz”. 6 | */ 7 | 8 | 9 | 10 | function fizzBuzz(n) { 11 | // Code goes here 12 | } 13 | 14 | 15 | module.exports = fizzBuzz -------------------------------------------------------------------------------- /Beginner/fizzBuzz/test.js: -------------------------------------------------------------------------------- 1 | const fizzBuzz = require('./index-START'); 2 | 3 | test('fizzBuzz is a function', () => { 4 | expect(fizzBuzz).toBeDefined(); 5 | }); 6 | 7 | test('Calling fizzbuzz with `10` prints out 10 statements', () => { 8 | fizzBuzz(10); 9 | 10 | expect(console.log.mock.calls.length).toEqual(10); 11 | }); 12 | 13 | test('Calling fizzbuzz with 15 prints out the correct values', () => { 14 | fizzBuzz(15); 15 | 16 | expect(console.log.mock.calls[0][0]).toEqual(1); 17 | expect(console.log.mock.calls[1][0]).toEqual(2); 18 | expect(console.log.mock.calls[2][0]).toEqual('fizz'); 19 | expect(console.log.mock.calls[3][0]).toEqual(4); 20 | expect(console.log.mock.calls[4][0]).toEqual('buzz'); 21 | expect(console.log.mock.calls[5][0]).toEqual('fizz'); 22 | expect(console.log.mock.calls[6][0]).toEqual(7); 23 | expect(console.log.mock.calls[7][0]).toEqual(8); 24 | expect(console.log.mock.calls[8][0]).toEqual('fizz'); 25 | expect(console.log.mock.calls[9][0]).toEqual('buzz'); 26 | expect(console.log.mock.calls[10][0]).toEqual(11); 27 | expect(console.log.mock.calls[11][0]).toEqual('fizz'); 28 | expect(console.log.mock.calls[12][0]).toEqual(13); 29 | expect(console.log.mock.calls[13][0]).toEqual(14); 30 | expect(console.log.mock.calls[14][0]).toEqual('fizzbuzz'); 31 | }); 32 | 33 | beforeEach(() => { 34 | jest.spyOn(console, 'log').mockImplementation(() => {}); 35 | }); 36 | 37 | afterEach(() => { 38 | console.log.mockRestore(); 39 | }); 40 | -------------------------------------------------------------------------------- /Beginner/hammingDistance/index-SOLUTION.js: -------------------------------------------------------------------------------- 1 | // USING FOR LOOP 2 | function hammingDistance(stringA, stringB) { 3 | let result = 0 4 | 5 | if (stringA.length == stringB.length) { 6 | 7 | for (let i = 0; i < stringA.length; i++) { 8 | if (stringA[i].toLowerCase() != stringB[i].toLowerCase()) { 9 | result++ 10 | } 11 | } 12 | return result 13 | } else { 14 | throw new Error('Strings do not have equal length') 15 | } 16 | } -------------------------------------------------------------------------------- /Beginner/hammingDistance/index-START.js: -------------------------------------------------------------------------------- 1 | /* CHALLENGE 2 | Given two strings of equal length, calculate and return the the hamming distance. 3 | E.g hammingDistance('rover', 'river') // should return 1 4 | */ 5 | 6 | 7 | 8 | 9 | function hammingDistance(stringA, stringB) { 10 | // Code goes here 11 | } 12 | 13 | 14 | 15 | module.exports = hammingDistance -------------------------------------------------------------------------------- /Beginner/hammingDistance/test.js: -------------------------------------------------------------------------------- 1 | const hammingDistance = require('./index-START') 2 | 3 | test('hammingDistance is a function', () => { 4 | expect(typeof hammingDistance).toEqual('function') 5 | }) 6 | 7 | test('returns the hamming distance for letters', () => { 8 | expect(hammingDistance('river', 'rover')).toEqual(1) 9 | }) 10 | 11 | test('returns the hamming distance for numbers', () => { 12 | expect(hammingDistance('1011101', '1001001')).toEqual(2) 13 | }) 14 | 15 | test('returns the hamming distance for letters', () => { 16 | expect(hammingDistance('karolin', 'kerstin')).toEqual(3) 17 | }) 18 | 19 | test('returns the hamming distance for letters', () => { 20 | expect(hammingDistance('drummer', 'dresser')).toEqual(3) 21 | }) 22 | 23 | 24 | -------------------------------------------------------------------------------- /Beginner/isAnagram/index-SOLUTION.js: -------------------------------------------------------------------------------- 1 | // DIRECT COMPARISON 2 | 3 | function isAnagram(stringA, stringB) { 4 | 5 | const sanitizeString = function (str) { 6 | return str.toLowerCase().replace(/[^a-z\d]/g, '').split('').sort().join(''); 7 | } 8 | 9 | return sanitizeString(stringA) == sanitizeString(stringB) 10 | 11 | } 12 | 13 | // CHARACTER MAP COMPARISON 14 | 15 | function isAnagram(stringA, stringB) { 16 | 17 | function createCharMap(text) { 18 | let charMap = {} 19 | for (let char of text) { 20 | if (charMap.hasOwnProperty(char)) { 21 | charMap[char]++ 22 | } else { 23 | charMap[char] = 1 24 | } 25 | } 26 | return charMap 27 | } 28 | 29 | if (stringA.length === stringB.length) { 30 | 31 | let stringAMap = createCharMap(stringA) 32 | let stringBMap = createCharMap(stringB) 33 | 34 | for (let char in stringAMap) { 35 | if (stringAMap[char] !== stringBMap[char]) { 36 | return false 37 | } 38 | } 39 | 40 | return true 41 | } else { 42 | return false 43 | } 44 | } -------------------------------------------------------------------------------- /Beginner/isAnagram/index-START.js: -------------------------------------------------------------------------------- 1 | /* CHALLENGE 2 | Given a two strings, write an algorithm to check if they are anagrams 3 | of each other. Return true if the pass the test and false if they 4 | don't. E.g 5 | isAnagram('silent', 'listen') // should return true 6 | */ 7 | 8 | 9 | 10 | function isAnagram(stringA, stringB) { 11 | // Code goes here 12 | } 13 | 14 | 15 | module.exports = isAnagram -------------------------------------------------------------------------------- /Beginner/isAnagram/test.js: -------------------------------------------------------------------------------- 1 | const isAnagram = require('./index-START') 2 | 3 | test('isAnagram is a function', () => { 4 | expect(typeof isAnagram).toEqual('function') 5 | }) 6 | 7 | test('"dog" is an anagram of "god"', () => { 8 | expect(isAnagram('dog', 'god')).toBeTruthy() 9 | }) 10 | 11 | test('"Scotchy is Scotch!" is an anagram of "Scotch is Scotchy!"', () => { 12 | expect(isAnagram('Scotchy is Scotch!', 'Scotch is Scotchy!')).toBeTruthy() 13 | }) 14 | 15 | test('"I do not work weekends." is not an anagram of "I do not work weekdays!"', () => { 16 | expect(isAnagram('I do not work weekends.', 'I do not work weekdays!')).toBeFalsy() 17 | }) -------------------------------------------------------------------------------- /Beginner/longestWord/index-SOLUTION.js: -------------------------------------------------------------------------------- 1 | // USING A FOR LOOP 2 | 3 | function longestWord(text) { 4 | let wordArray = text.split(' ') 5 | let maxLength = 0 6 | let result = '' 7 | for (let i = 0; i < wordArray.length; i++) { 8 | if (wordArray[i].length > maxLength) { 9 | maxLength = wordArray[i].length 10 | result = wordArray[i] 11 | } 12 | } 13 | return result 14 | } 15 | 16 | 17 | 18 | // USING .REDUCE() 19 | 20 | function longestWord(text) { 21 | var result = text.split(' ').reduce((maxLengthWord, currentWord) => { 22 | if (currentWord.length > maxLengthWord.length) { 23 | return currentWord 24 | } else { 25 | return maxLengthWord 26 | } 27 | }, "") 28 | return result 29 | } 30 | 31 | 32 | // USING .SORT() 33 | 34 | function longestWord(text) { 35 | 36 | var sortedArray = text.split(' ') 37 | .sort((wordA, wordB) => wordB.length - wordA.length) 38 | 39 | return sortedArray[0] 40 | } -------------------------------------------------------------------------------- /Beginner/longestWord/index-START.js: -------------------------------------------------------------------------------- 1 | /* CHALLENGE 2 | Given a string of text, write an algorithm that returns the text received in a reversed format. 3 | E.g reverseString('algorithms') // should return 'smhtirogla' 4 | */ 5 | 6 | 7 | 8 | function longestWord(text) { 9 | // Code goes here 10 | } 11 | 12 | 13 | module.exports = longestWord -------------------------------------------------------------------------------- /Beginner/longestWord/test.js: -------------------------------------------------------------------------------- 1 | const longestWord = require('./index-START') 2 | 3 | test('longestWord is a function', () => { 4 | expect(typeof longestWord).toEqual('function'); 5 | }); 6 | 7 | test('returns the longet word in a mixed case string of text', () => { 8 | expect(longestWord('Top Shelf Web Development Training on Scotch') ).toEqual('Development'); 9 | }); 10 | 11 | test('returns the longet word in a lowercase string', () => { 12 | expect(longestWord('the ultimate guide to js algorithms') ).toEqual('algorithms'); 13 | }); 14 | test('returns the longet word in an uppercase string', () => { 15 | expect(longestWord('BUILDING FOR THE NEXT BILLION USERS') ).toEqual('BUILDING'); 16 | }); -------------------------------------------------------------------------------- /Beginner/maxRecurringChar/index-SOLUTION.js: -------------------------------------------------------------------------------- 1 | // FOR...IN ITERATION METHOD 2 | function maxRecurringChar(text) { 3 | let charMap = {} 4 | let maxCharValue = 0 5 | let maxChar = '' 6 | for (let char of text) { 7 | if (charMap.hasOwnProperty(char)) { 8 | charMap[char]++ 9 | } else { 10 | charMap[char] = 1 11 | } 12 | } 13 | for (let char in charMap) { 14 | if (charMap[char] > maxCharValue) { 15 | maxCharValue = charMap[char] 16 | maxChar = char 17 | } 18 | } 19 | return maxChar 20 | } 21 | 22 | // FORMING ARRAYS FROM THE CHARACTER MAP METHOD 23 | function maxRecurringChar(text) { 24 | let charMap = {} 25 | let charArray =[] 26 | let vaulesArray = [] 27 | let maxCharValue = 0 28 | 29 | for (let char of text) { 30 | if (charMap.hasOwnProperty(char)) { 31 | charMap[char]++ 32 | } else { 33 | charMap[char] = 1 34 | } 35 | } 36 | charArray = Object.keys(charMap) 37 | vaulesArray = Object.values(charMap) 38 | maxCharValue = Math.max(...vaulesArray) 39 | 40 | return charArray[vaulesArray.indexOf(maxCharValue)] 41 | } -------------------------------------------------------------------------------- /Beginner/maxRecurringChar/index-START.js: -------------------------------------------------------------------------------- 1 | /* CHALLENGE 2 | Given a string of text, find and return the most recurring character. 3 | e.g maxRecurringChar('aabacada') // will return 'a' 4 | */ 5 | 6 | 7 | 8 | function maxRecurringChar(text) { 9 | // Code goes here 10 | } 11 | 12 | 13 | 14 | module.exports = maxRecurringChar; -------------------------------------------------------------------------------- /Beginner/maxRecurringChar/test.js: -------------------------------------------------------------------------------- 1 | const maxRecurringChar = require('./index-START'); 2 | 3 | test('maxRecurringChar is a function', () => { 4 | expect(typeof maxRecurringChar).toEqual('function'); 5 | }); 6 | 7 | test('Finds the most frequently used character', () => { 8 | expect(maxRecurringChar('sisusbsnshsjsmskslstsw')).toEqual('s'); 9 | }); 10 | 11 | test('Finds the most frequently used character even with mixed capitalization', () => { 12 | expect(maxRecurringChar('AbAdAabnmkAAAynjfaA')).toEqual('A'); 13 | }); 14 | 15 | test('Finds the most used number as well', () => { 16 | expect(maxRecurringChar('b2n3n2m2l2k2i2o2')).toEqual('2'); 17 | }); 18 | -------------------------------------------------------------------------------- /Beginner/mergeArrays/index-FINISHED.js: -------------------------------------------------------------------------------- 1 | // USING A SET 2 | function mergeArrays(...arrays) { 3 | 4 | let jointArray = [] 5 | 6 | arrays.forEach(array => { 7 | jointArray = [...jointArray, ...array] 8 | }); 9 | 10 | return [...new Set([...jointArray])] 11 | 12 | } 13 | 14 | // USING ARRAY.FROM() WITH SET 15 | 16 | function mergeArrays(...arrays) { 17 | let jointArray = [] 18 | 19 | arrays.forEach(array => { 20 | jointArray = [...jointArray, ...array] 21 | }); 22 | return Array.from(new Set([...jointArray])) 23 | } 24 | 25 | // USING .FILTER() 26 | 27 | function mergeArrays(...arrays) { 28 | 29 | let jointArray = [] 30 | 31 | arrays.forEach(array => { 32 | jointArray = [...jointArray, ...array] 33 | }) 34 | 35 | const uniqueArray = jointArray.filter((item,index) => jointArray.indexOf(item) === index) 36 | 37 | return uniqueArray 38 | } 39 | 40 | // USING .REDUCE() 41 | 42 | function mergeArrays(...arrays) { 43 | 44 | let jointArray = [] 45 | 46 | arrays.forEach(array => { 47 | jointArray = [...jointArray, ...array] 48 | }) 49 | 50 | const uniqueArray = jointArray.reduce((newArray, item) =>{ 51 | if (newArray.includes(item)){ 52 | return newArray 53 | } else { 54 | return [...newArray, item] 55 | } 56 | }, []) 57 | 58 | return uniqueArray 59 | } -------------------------------------------------------------------------------- /Beginner/mergeArrays/index-START.js: -------------------------------------------------------------------------------- 1 | /* 2 | Given two or more arrays, write a function that combines 3 | their elements into one array without any repetition. 4 | E.g mergeArrays([1,2,3,3,3], [1,4,5,2]) // should return [1,2,3,4,5] 5 | */ 6 | 7 | function mergeArrays(...arrays) { 8 | 9 | let jointArray = [] 10 | 11 | arrays.forEach(array => { 12 | jointArray = [...jointArray, ...array] 13 | }); 14 | 15 | return [...new Set([...jointArray])] 16 | 17 | 18 | } 19 | 20 | 21 | module.exports = mergeArrays -------------------------------------------------------------------------------- /Beginner/mergeArrays/test.js: -------------------------------------------------------------------------------- 1 | const mergeArrays = require('./index-START'); 2 | 3 | test('mergeArrays is a function', () => { 4 | expect(typeof mergeArrays).toEqual('function'); 5 | }); 6 | 7 | test('Combines 5 arrays of numbers without dubplicates', () => { 8 | expect(mergeArrays([1,2],[2,3],[3,4],[4,5])).toEqual([1,2,3,4,5]); 9 | }); 10 | 11 | test('Combines 3 arrays of strings without dubplicates', () => { 12 | expect(mergeArrays(['a','b','z'],['m','n','a'],['z','y'])).toEqual(['a','b', 'z', 'm', 'n', 'y']); 13 | }); 14 | 15 | 16 | -------------------------------------------------------------------------------- /Beginner/palindromeChecker/index-SOLUTION.js: -------------------------------------------------------------------------------- 1 | // AN INTUITIVE APPROACH 2 | 3 | function palindromeChecker(text) { 4 | 5 | var reversedText = text.toLowerCase() 6 | .split('').reverse().join('') 7 | 8 | return text === reversedText 9 | } 10 | 11 | 12 | // LOOPING THROUGH AND COMPARING CHARACTERS 13 | 14 | 15 | function palindromeChecker(text) { 16 | let charArray = text.toLowerCase().split('') 17 | 18 | let result = charArray.every((letter, index) => { 19 | return letter === charArray[charArray.length - index - 1]; 20 | }) 21 | 22 | return result 23 | } 24 | 25 | // LOOPING THROUGH AND COMPARING CHARACTERS(OPTIMIZED) 26 | 27 | 28 | function palindromeChecker(text) { 29 | var textLen = text.length; 30 | for (var i = 0; i < textLen / 2; i++) { 31 | if (text[i] !== text[textLen - 1 - i]) { 32 | return false; 33 | } 34 | } 35 | return true; 36 | } -------------------------------------------------------------------------------- /Beginner/palindromeChecker/index-START.js: -------------------------------------------------------------------------------- 1 | /* CHALLENGE 2 | Given a string of text, return true or false indicating whether or not the text is a palindrome. 3 | e.g palindromeChecker('racecar') // will return true 4 | */ 5 | 6 | 7 | 8 | 9 | function palindromeChecker(text) { 10 | v// Code goes here 11 | } 12 | 13 | 14 | 15 | module.exports = palindromeChecker; -------------------------------------------------------------------------------- /Beginner/palindromeChecker/test.js: -------------------------------------------------------------------------------- 1 | const palindromeChecker = require('./index-START'); 2 | 3 | test('palindromeChecker is a function', () => { 4 | expect(typeof palindromeChecker).toEqual('function'); 5 | }); 6 | 7 | test('"php" is a palindrome', () => { 8 | expect(palindromeChecker('php')).toBeTruthy(); 9 | }); 10 | 11 | test('" php " is not a palindrome', () => { 12 | expect(palindromeChecker(' php ')).toBeFalsy(); 13 | }); 14 | 15 | test('"developer" is not a palindrome', () => { 16 | expect(palindromeChecker('developer')).toBeFalsy(); 17 | }); 18 | 19 | test('"2002" a palindrome', () => { 20 | expect(palindromeChecker('2002')).toBeTruthy(); 21 | }); 22 | 23 | -------------------------------------------------------------------------------- /Beginner/reverseString/index-SOLUTION.js: -------------------------------------------------------------------------------- 1 | // CHAINING BUILT-IN METHODS 2 | 3 | function reverseString(text) { 4 | return text.split("").reverse().join(""); 5 | } 6 | 7 | // CHAINING BUILT-IN METHODS USING ES6 8 | 9 | function reverseString(text) { 10 | return [...text].reverse().join(''); 11 | } 12 | 13 | // USING A FOR LOOP 14 | 15 | function reverseString(text) { 16 | let result = ""; 17 | for (let i = text.length - 1; i >= 0; i--) { 18 | result += text[i]; 19 | } 20 | return result; 21 | } 22 | 23 | // USING A FOR..OF LOOP IN ES6 24 | 25 | function reverseString(text) { 26 | let result = ""; 27 | for (let char of text) { 28 | result = char + result 29 | } 30 | return result; 31 | } 32 | 33 | // RECURSIVE METHOD 34 | 35 | function reverseString(text) { 36 | if (text === "") { 37 | return "" 38 | } else { 39 | return reverseString(text.substr(1)) + text[0] 40 | } 41 | } 42 | 43 | 44 | // USING .REDUCE() 45 | 46 | function reverseString(text) { 47 | return text.split("").reduce((acc, char) => char + acc); 48 | } -------------------------------------------------------------------------------- /Beginner/reverseString/index-START.js: -------------------------------------------------------------------------------- 1 | /* CHALLENGE 2 | Given a string of text, write an algorithm that returns the text received in a reversed format. 3 | E.g reverseString('algorithms') // should return 'smhtirogla' 4 | */ 5 | 6 | 7 | 8 | function reverseString(text) { 9 | // Code goes here 10 | } 11 | 12 | 13 | 14 | module.exports = reverseString -------------------------------------------------------------------------------- /Beginner/reverseString/test.js: -------------------------------------------------------------------------------- 1 | const reverseString = require('./index-START') 2 | 3 | test('reverseString is a function', () => { 4 | expect(typeof reverseString).toEqual('function'); 5 | }); 6 | 7 | test('reverses a string of text', () => { 8 | expect(reverseString('aeiou')).toEqual('uoiea'); 9 | }); 10 | 11 | test('reverses a string containing numbers', () => { 12 | expect(reverseString('123456789')).toEqual('987654321'); 13 | }); 14 | 15 | test('reverses a string containing mixed case characters', () => { 16 | expect(reverseString('AsDfGhJkL')).toEqual('LkJhGfDsA'); 17 | }); 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Beginner/searchReplace/index-SOLUTION.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scotch-io/ultimate-guide-to-javascript-algorithms/58a4c4ffb1be5c92fc59b98e42c7529cf7885860/Beginner/searchReplace/index-SOLUTION.js -------------------------------------------------------------------------------- /Beginner/searchReplace/index-START.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scotch-io/ultimate-guide-to-javascript-algorithms/58a4c4ffb1be5c92fc59b98e42c7529cf7885860/Beginner/searchReplace/index-START.js -------------------------------------------------------------------------------- /Beginner/searchReplace/test.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scotch-io/ultimate-guide-to-javascript-algorithms/58a4c4ffb1be5c92fc59b98e42c7529cf7885860/Beginner/searchReplace/test.js -------------------------------------------------------------------------------- /Beginner/vowelsCounter/index-SOLUTION.js: -------------------------------------------------------------------------------- 1 | // ITERATIVE APPROACH 2 | const vowels = ["a", "e", "i", "o", "u"] 3 | 4 | 5 | function vowelsCounter(text) { 6 | // Initialize counter 7 | let counter = 0; 8 | 9 | 10 | // Loop through text to test if each character is a vowel 11 | for (let letter of text.toLowerCase()) { 12 | if (vowels.includes(letter)) { 13 | counter++ 14 | } 15 | } 16 | 17 | // Return number of vowels 18 | return counter 19 | } 20 | 21 | // REGULAR EXPRESSIONS 22 | 23 | function vowelsCounter(text) { 24 | // Search text with Regex and store all matching instances 25 | let matchingInstances = text.match(/[aeiou]/gi); 26 | 27 | // Check if matching instances exist then calculate length 28 | if (matchingInstances) { 29 | // Return number of vowels 30 | return matchingInstances.length 31 | } else { 32 | return 0 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Beginner/vowelsCounter/index-START.js: -------------------------------------------------------------------------------- 1 | /* CHALLENGE 2 | Given a string of text, return the number of vowels found within the text 3 | e.g vowelsCounter('anehizxcv') // will return 3 4 | */ 5 | 6 | 7 | function vowelsCounter(text) { 8 | // Code goes here 9 | } 10 | 11 | 12 | 13 | module.exports = vowelsCounter; 14 | -------------------------------------------------------------------------------- /Beginner/vowelsCounter/test.js: -------------------------------------------------------------------------------- 1 | const vowelsCounter = require('./index-START'); 2 | 3 | test('vowelsCounter is a function', () => { 4 | expect(typeof vowelsCounter).toEqual('function'); 5 | }); 6 | 7 | test('returns the number of vowels found', () => { 8 | expect(vowelsCounter('aeiou')).toEqual(5); 9 | }); 10 | 11 | test('returns the number of vowels found when string is capitalized', () => { 12 | expect(vowelsCounter('AEIOU')).toEqual(5); 13 | }); 14 | 15 | test('returns the number of vowels found when all alphabets are passed in', () => { 16 | expect(vowelsCounter('abcdefghijklmnopqrstuvwxyz')).toEqual(5); 17 | }); 18 | 19 | test('returns the number of vowels found when string has mixed capitalization', () => { 20 | expect(vowelsCounter('Abcdegfizzjbhso')).toEqual(4); 21 | }); 22 | -------------------------------------------------------------------------------- /Beginner/whereIBelong/index-SOLUTION.js: -------------------------------------------------------------------------------- 1 | // ITERATING AND COMPARING WITH A FORLOOP(BY FINDING THE IMMEDIATE LARGER VALUE) 2 | 3 | function whereIBelong(arr, num) { 4 | arr.sort((a, b) => { 5 | return a - b 6 | }) 7 | 8 | for (var i = 0; i < arr.length; i++) { 9 | if (arr[i] >= num) { 10 | return i 11 | } 12 | } 13 | 14 | return arr.length 15 | 16 | } 17 | 18 | // ITERATING AND COMPARING WITH A FORLOOP(BY COUNTING ALL SMALLER VALUES) 19 | 20 | function whereIBelong(arr, num) { 21 | 22 | var counter = 0 23 | for (i = 0; i < arr.length; i++) { 24 | if (num > arr[i]) { 25 | counter++ 26 | } 27 | } 28 | 29 | return counter 30 | } 31 | 32 | 33 | // USING A WHILE LOOP 34 | 35 | function whereIBelong(arr, num) { 36 | arr.sort((a, b) => { 37 | return a - b 38 | }) 39 | 40 | let counter = 0; 41 | while (num > arr[counter]) { 42 | counter++ 43 | } 44 | 45 | return counter 46 | } 47 | 48 | 49 | // FINDING THE NUMBER'S INDEX IN THE ARRAY 50 | 51 | function whereIBelong(arr, num) { 52 | arr.push(num) 53 | 54 | arr.sort((a, b) => a - b) 55 | 56 | return arr.indexOf(num) 57 | 58 | } -------------------------------------------------------------------------------- /Beginner/whereIBelong/index-START.js: -------------------------------------------------------------------------------- 1 | /* 2 | Return the lowest index at which a value (second argument) should be 3 | inserted into an array (first argument) once it has been sorted. The 4 | returned value should be a number. E.g 5 | 6 | whereIBelong([1,2,3,4], 1.5) // should return 1 because it is greater 7 | than 1(index 0), but less than 2(index 1). 8 | */ 9 | 10 | 11 | 12 | function whereIBelong(arr, num) { 13 | // Code goes here 14 | 15 | } 16 | 17 | 18 | 19 | module.exports = whereIBelong -------------------------------------------------------------------------------- /Beginner/whereIBelong/test.js: -------------------------------------------------------------------------------- 1 | const whereIBelong = require('./index-START'); 2 | 3 | test('whereIBelong is a function', () => { 4 | expect(typeof whereIBelong).toEqual('function'); 5 | }); 6 | 7 | test('returns the appropriate index', () => { 8 | expect(whereIBelong([1,2,3,4], 1.5)).toEqual(1); 9 | }); 10 | 11 | 12 | test('returns the index of the specified number', () => { 13 | expect(whereIBelong([10, 20, 30, 40, 50], 30)).toEqual(2); 14 | }); 15 | 16 | test('returns the index even with an empty array', () => { 17 | expect(whereIBelong([], 1)).toEqual(0); 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # js-algorithms-demo- 2 | Demo repository for JS Algorithms Course 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js-algorithms", 3 | "version": "1.0.0", 4 | "description": "sample course setup", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest" 8 | }, 9 | "author": "Obosi Philip", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "jest": "^23.6.0" 13 | } 14 | } 15 | --------------------------------------------------------------------------------