├── .github └── FUNDING.yml ├── .gitignore ├── README.md ├── algoexperts ├── SameBST.js ├── firstNonRepeatingCharacterAlt.js ├── firstNonRepeatingCharacters.js └── minMaxStack.js ├── allUnique.js ├── areThereDuplicates.js ├── averagePair.js ├── batches.js ├── binarySearch.js ├── capitalizeFirst.js ├── compareWithBackspace.js ├── condensedString.js ├── consonantValue.js ├── countSockPairs.js ├── countUniqueValues.js ├── cracklePop.js ├── domTree.js ├── doubly-linked-lists ├── dllGetExercise.js ├── dllPopExercise.js ├── dllPushExercise.js ├── dllSetExercise.js ├── dllShiftExercise.js ├── dllUnshiftExercise.js ├── getDoublyLinkedList.js ├── initialDoublyLinkedList.js ├── insertDoublyLinkedList.js ├── popDoublyLinkedList.js ├── pushDoublyLinkedList.js ├── removeDoublyLinkedList.js ├── setDoublyLinkedList.js ├── shiftDoublyLinkedList.js └── unshiftDoublyLinkedList.js ├── duplicates.js ├── factorial.js ├── filterExercises.js ├── findLongestSubstring.js ├── firstUniqueLetter.js ├── flattenArray.js ├── functional-javascript-node-school ├── call.js ├── everySome.js ├── filter.js ├── higherOrderFunction.js ├── map.js ├── reduce.js └── upperCaser.js ├── functionalProgrammingPractice.js ├── getByPath.js ├── goatLatin.js ├── groupAnagrams.js ├── happynumber.js ├── highestProduct.js ├── isOdd.js ├── isPalindrome.js ├── isSubsequence.js ├── jewelsAndStones.js ├── largestPerimeterTriangles.js ├── largestUniqueNumber.js ├── lastStoneWeight.js ├── learnyounode ├── baby-steps.js ├── filtered-ls.js ├── hello-world.js ├── http-client.js ├── http-collect.js ├── make-it-modular.js ├── my-first-async-io.js ├── my-first-io.js └── mymodule.js ├── lemonadeChange.js ├── letter-count.js ├── letterOccurence.js ├── linearSearch.js ├── linked-lists ├── README.md ├── singlyLinkedListGet.js ├── singlyLinkedListInsert.js ├── singlyLinkedListPop.js ├── singlyLinkedListPush.js ├── singlyLinkedListRemove.js ├── singlyLinkedListReverse.js ├── singlyLinkedListSet.js ├── singlyLinkedListShift.js └── singlyLinkedListUnshift.js ├── mapExercises.js ├── max69.js ├── maxProduct.js ├── maxProfit.js ├── maxSubarraySum.js ├── maximumNumberOfBalloons.js ├── maximumSubArray.js ├── middleOfLinkedList.js ├── minSubArrayLen.js ├── minValueInStack.js ├── mostCommonWord.js ├── moveZeroes.js ├── numberComplement.js ├── oneAway.js ├── oneAwayTakeTwo.js ├── overlappingMeetings.js ├── pairSum.js ├── palindromePermutation.js ├── palindromePermutation2.js ├── perfectNumber.js ├── perfectNumbers2.js ├── permutations.js ├── power.js ├── productOfArray.js ├── query-string-parser.js ├── queue └── queue.js ├── ransomNote.js ├── recursive ├── recursiveCapitalizeWords.js ├── recursiveFibonnaci.js ├── recursivePalindrome.js ├── recursiveRange.js ├── recursiveReverseString.js └── someRecursive.js ├── reduceExercises.js ├── reduceReuseRecycle.js ├── removeDuplicatesFromString.js ├── reverseStringInPlace.js ├── reverseWords.js ├── roundBasedOnValue ├── index.js └── readme.md ├── sameFrequency.js ├── scrambles.js ├── shiftString.js ├── singleNumber.js ├── sortExercises.js ├── squaredValuesMatch.js ├── stacks └── stack.js ├── stringCompression.js ├── transform-practice.js ├── trees ├── BinarySearchTree.js └── BinarySearchTreeFind.js ├── twoSum.js ├── uncommonWordsFromTwoSentences.js ├── urlify.js ├── validAnagram.js └── writeSafeGet.js /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: m0nica # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: m0nica # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # algorithm-practice 2 | Misc. algorithm solutions from practicing [Interview Cake](https://www.interviewcake.com/), [Udemy](https://www.udemy.com/share/100F3uA0oecFdbRng=/?xref=E0ESdF9bTH8FSWUuAAcqP1kSWSRM), [Frontend Masters Frontend Interviewing Course](https://github.com/young/frontend-interviewing) and [LeetCode](https://leetcode.com/) problems. 3 | 4 | 5 | ## Table Of Contents 6 | - [Linked List Implementation](https://github.com/M0nica/algorithm-practice/tree/master/linked-lists) 7 | - [Recursion Practice](https://github.com/M0nica/algorithm-practice/tree/master/recursive) 8 | -------------------------------------------------------------------------------- /algoexperts/SameBST.js: -------------------------------------------------------------------------------- 1 | function sameBsts(arrayOne, arrayTwo) { 2 | if(arrayOne.length == 0 && arrayTwo.length == 0) return true; 3 | if(arrayOne.length !== arrayTwo.length ||arrayOne[0] !== arrayTwo[0]) return false 4 | 5 | return sameBsts(getLeftSubTree(arrayOne), getLeftSubTree(arrayTwo)) && 6 | sameBsts(getRightSubTree(arrayOne), getRightSubTree(arrayTwo)) 7 | } 8 | 9 | function getLeftSubTree(array){ 10 | const [root, ...subtree] = array; 11 | return subtree.filter((a) => a < root ) 12 | } 13 | function getRightSubTree(array){ 14 | const [root, ...subtree] = array; 15 | return subtree.filter((a) => a >=root ) 16 | } 17 | 18 | 19 | // find all numbers less than root, they need to be in the same order 20 | // 10 -> 8 -> 5 - > 2 21 | // find all numbers greater than root , they need to be in fhe sams order but we must look at subtrees 22 | // their right and left node lengths need to be the same 23 | // for each recursive call 24 | 25 | // the root node for each recrusive call need to be equal 26 | 27 | // return true as base case if we've gone through 28 | // every single item in arrayone and arraytwo 29 | // without encountering a false statement earlier 30 | 31 | // Do not edit the line below. 32 | exports.sameBsts = sameBsts; 33 | 34 | //true same bst: 35 | 36 | //{ 37 | // "arrayOne": [10, 15, 8, 12, 94, 81, 5, 2, 11], 38 | // "arrayTwo": [10, 8, 5, 15, 2, 12, 11, 94, 81] 39 | //} 40 | 41 | //false not same bst 42 | //{ 43 | // "arrayOne": [10, 15, 8, 12, 94, 81, 5, 2], 44 | // "arrayTwo": [11, 8, 5, 15, 2, 12, 94, 81] 45 | //} 46 | -------------------------------------------------------------------------------- /algoexperts/firstNonRepeatingCharacterAlt.js: -------------------------------------------------------------------------------- 1 | // return the index of first non-repeating character, 2 | // if there are no non-repeating chartacter then return -1 3 | 4 | // O(N) time complexity, O(1) space complexity since hash table 5 | // size is limited to alphabet size in this problem 6 | function firstNonRepeatingCharacter(string) { 7 | let letterCount = {}; 8 | 9 | for (let letter of string) { 10 | letterCount[letter] = letterCount[letter] ? 2 : 1; 11 | } 12 | 13 | // avoid for...in when the order matters 14 | // in this instance order matters as we want the first occurence 15 | for (let idx = 0; idx < string.length; idx++) { 16 | if (letterCount[string[idx]] == 1) return idx; 17 | } 18 | 19 | return -1; 20 | } 21 | 22 | // Do not edit the line below. 23 | exports.firstNonRepeatingCharacter = firstNonRepeatingCharacter; 24 | 25 | // all should return true if the fn is working as expected 26 | console.log(firstNonRepeatingCharacter("abcdcaf") === 1); 27 | console.log(firstNonRepeatingCharacter("faadabcbbebdf") === 6); 28 | console.log(firstNonRepeatingCharacter("a") === 0); 29 | console.log(firstNonRepeatingCharacter("abc") === 0); 30 | console.log(firstNonRepeatingCharacter("ababac") === 5); 31 | console.log(firstNonRepeatingCharacter("ababacc") === -1); 32 | console.log(firstNonRepeatingCharacter("lmnopqldsafmnopqsa") === 7); 33 | -------------------------------------------------------------------------------- /algoexperts/firstNonRepeatingCharacters.js: -------------------------------------------------------------------------------- 1 | // return the index of first non-repeating character, 2 | // if there are no non-repeating chartacter then return -1 3 | 4 | // O(N) time complexity, O(1) space complexity since hash table 5 | // size is limited to alphabet size in this problem 6 | function firstNonRepeatingCharacter(string) { 7 | const letterCount = new Array(26); 8 | 9 | for (let index in string) { 10 | const currentCharCode = string.charCodeAt(index); 11 | letterCount[currentCharCode] = letterCount[currentCharCode] 12 | ? "multiple" 13 | : 1; 14 | } 15 | 16 | // avoid for...in when the order matters 17 | // in this instance order matters as we want the first occurence 18 | for (let idx = 0; idx < string.length; idx++) { 19 | if (letterCount[string.charCodeAt(idx)] == 1) return idx; 20 | } 21 | 22 | return -1; 23 | } 24 | 25 | // Do not edit the line below. 26 | exports.firstNonRepeatingCharacter = firstNonRepeatingCharacter; 27 | 28 | // all should return true if the fn is working as expected 29 | console.log(firstNonRepeatingCharacter("abcdcaf") === 1); 30 | console.log(firstNonRepeatingCharacter("faadabcbbebdf") === 6); 31 | console.log(firstNonRepeatingCharacter("a") === 0); 32 | console.log(firstNonRepeatingCharacter("abc") === 0); 33 | console.log(firstNonRepeatingCharacter("ababac") === 5); 34 | console.log(firstNonRepeatingCharacter("ababacc") === -1); 35 | console.log(firstNonRepeatingCharacter("lmnopqldsafmnopqsa") === 7); 36 | -------------------------------------------------------------------------------- /algoexperts/minMaxStack.js: -------------------------------------------------------------------------------- 1 | // Write a MinMaxStack class for a Min Max Stack. The class should 2 | // support: 3 | // - Pushing and popping values on and off the stack. 4 | // - Peeking at the value at the top of the stack. 5 | // - 6 | // Getting both the minimum and the maximum values in the stack at any given 7 | // point in time. 8 | // - All class methods, when considered independently, should run in constant time and with constant space. 9 | 10 | // Stack = Last In, First Out, 11 | class MinMaxStack { 12 | constructor() { 13 | this.stack = []; 14 | this.minMaxStack = [{ min: null, max: null }]; 15 | } 16 | 17 | // O(1) time | O(1) space 18 | peek() { 19 | return this.stack[this.stack.length - 1]; 20 | } 21 | 22 | // O(1) time | O(1) space 23 | pop() { 24 | this.minMaxStack.pop(); 25 | return this.stack.pop(); 26 | } 27 | 28 | // O(1) time | O(1) space 29 | push(number) { 30 | // rename current "min" and current "max" to currentMin and currentMax 31 | const { min: currentMin, max: currentMax } = 32 | this.minMaxStack[this.minMaxStack.length - 1]; 33 | 34 | this.minMaxStack.push({ 35 | min: currentMin !== null ? Math.min(currentMin, number) : number, 36 | max: currentMax !== null ? Math.max(currentMax, number) : number, 37 | }); 38 | this.stack.push(number); 39 | } 40 | 41 | // O(1) time | O(1) space 42 | getMin() { 43 | return this.minMaxStack[this.minMaxStack.length - 1].min; 44 | } 45 | 46 | // O(1) time | O(1) space 47 | getMax() { 48 | return this.minMaxStack[this.minMaxStack.length - 1].max; 49 | } 50 | } 51 | 52 | // Do not edit the line below. 53 | exports.MinMaxStack = MinMaxStack; 54 | -------------------------------------------------------------------------------- /allUnique.js: -------------------------------------------------------------------------------- 1 | // Is Unique: Implement an algorithm to determine if a string has all unique 2 | // characters.What if you cannot use additional data structures ? 3 | 4 | function isUniqueWord(word) { 5 | const letterMap = new Map(); 6 | for (let letter of word) { 7 | if (letterMap.has(letter)) { 8 | return false; 9 | } else { 10 | letterMap.set(letter, 1); 11 | } 12 | } 13 | 14 | return true; 15 | } 16 | 17 | // not unique; 'hotpotato' 18 | // look at each letter in word and add to hash map 19 | // if letter already exists in map then return early 20 | 21 | function isUnique(word) { 22 | const letterMap = new Map(); 23 | for (letter of word) { 24 | if (letterMap.has(letter)) { 25 | return false; 26 | } else { 27 | letterMap.set(letter, 1); 28 | } 29 | } 30 | 31 | return true; 32 | } 33 | 34 | // console.log(isUnique("moonica")); 35 | //console.log(isUnique("abc")); 36 | 37 | function isUniqueTwo(word) { 38 | // sort letters in array - if the next item is the same letter than return false 39 | 40 | word.split("").sort((a, b) => a - b); 41 | let i; 42 | for (i = 0; i < word.length; i++) { 43 | if (word[i] == word[i + 1]) { 44 | return false; 45 | } 46 | } 47 | return true; 48 | } 49 | 50 | console.log(isUniqueWord("moonica")); 51 | console.log(isUniqueWord("monica")); 52 | console.log(isUniqueWord("abc")); 53 | 54 | console.log(isUniqueTwo("moonica")); 55 | console.log(isUniqueTwo("abc")); 56 | -------------------------------------------------------------------------------- /areThereDuplicates.js: -------------------------------------------------------------------------------- 1 | function areThereDuplicates() { 2 | const seen = {}; 3 | for (let value of arguments) { 4 | // use the arguments keyword to access variable number of arguments 5 | if (!seen[value]) { 6 | seen[value] = value; 7 | } else { 8 | return true; 9 | } 10 | } 11 | return false; 12 | } 13 | 14 | // function areThereDuplicates(...values) { 15 | // const seen = {}; 16 | // for (let value of values) { 17 | // // use the arguments keyword to access variable number of arguments 18 | // if (!seen[value]) { 19 | // seen[value] = value; 20 | // } else { 21 | // return true; 22 | // } 23 | // } 24 | // return false; 25 | // } 26 | 27 | console.log(areThereDuplicates(1, 2, 3)); // false 28 | console.log(areThereDuplicates(1, 2, 2)); // true 29 | console.log(areThereDuplicates("a", "b", "c", "a")); //true 30 | -------------------------------------------------------------------------------- /averagePair.js: -------------------------------------------------------------------------------- 1 | function averagePair(array, average) { 2 | //have pointer at beginning and end 3 | // if smaller than avg move pointer beginning up 4 | // if larger than avg move pointer end down 5 | //if avg is found return true 6 | 7 | // if smaller == larger / exit 8 | 9 | if (array.length == 0) { 10 | return false; 11 | } 12 | 13 | let start = 0; 14 | let end = array.length - 1; 15 | 16 | while (start != end) { 17 | if ((array[start] + array[end]) / 2 == average) { 18 | return true; 19 | } else if ((array[start] + array[end]) / 2 > average) { 20 | end--; 21 | } else { 22 | start++; 23 | } 24 | } 25 | 26 | return false; 27 | } 28 | 29 | console.log(averagePair([1, 2, 3], 2.5)); // true 30 | 31 | console.log(averagePair([1, 3, 3, 5, 6, 7, 10, 12, 19], 8)); // true 32 | 33 | console.log(averagePair([-1, 0, 3, 4, 5, 6], 4.1)); // false 34 | 35 | console.log(averagePair([], 4)); // false 36 | -------------------------------------------------------------------------------- /batches.js: -------------------------------------------------------------------------------- 1 | /** 2 | It accepts two objects as arguments: the first object is the recipe 3 | for the food, while the second object is the available ingredients. 4 | Each ingredient's value is a number representing how many units there are. 5 | 6 | `batches(recipe, available)` 7 | */ 8 | 9 | function batches(recipe, available) { 10 | const recipeArray = Object.keys(recipe); 11 | const possibleServings = []; 12 | for (const ingredient of recipeArray) { 13 | possibleServings.push(available[ingredient] / recipe[ingredient] || 0); 14 | } 15 | 16 | return Math.floor(Math.min(...possibleServings)); 17 | } 18 | 19 | // const batches = (recipe, available) => 20 | // Math.floor( 21 | // Math.min( 22 | // ...Object.keys(recipe).map( 23 | // ingredient => available[ingredient] / recipe[ingredient] || 0 24 | // ) 25 | // ) 26 | // ); 27 | // 0 batches can be made 28 | console.log( 29 | batches( 30 | { milk: 100, butter: 50, flour: 5 }, 31 | { milk: 132, butter: 48, flour: 51 } 32 | ) 33 | ); 34 | 35 | console.log( 36 | batches( 37 | { milk: 100, flour: 4, sugar: 10, butter: 5 }, 38 | { milk: 1288, flour: 9, sugar: 95 } 39 | ) 40 | ); 41 | 42 | // 1 batch can be made 43 | console.log( 44 | batches( 45 | { milk: 100, butter: 50, cheese: 10 }, 46 | { milk: 198, butter: 52, cheese: 10 } 47 | ) 48 | ); 49 | 50 | // 2 batches can be made 51 | console.log( 52 | batches( 53 | { milk: 2, sugar: 40, butter: 20 }, 54 | { milk: 5, sugar: 120, butter: 500 } 55 | ) 56 | ); 57 | -------------------------------------------------------------------------------- /binarySearch.js: -------------------------------------------------------------------------------- 1 | function binarySearch(array, target) { 2 | let max = array.length - 1; 3 | let min = 0; 4 | 5 | while (max >= min) { 6 | let guess = Math.floor((max + min) / 2); 7 | if (array[guess] == target) { 8 | return guess; 9 | } else if (array[guess] > target) { 10 | max = guess - 1; 11 | } else if (array[guess] < target) { 12 | min = guess + 1; 13 | } 14 | } 15 | 16 | return -1; 17 | } 18 | 19 | console.log(binarySearch([1, 2, 3, 4, 5], 2)); //1 20 | 21 | console.log(binarySearch([1, 2, 3, 4, 5], 3)); //2 22 | 23 | console.log(binarySearch([1, 2, 3, 4, 5], 5)); //4 24 | 25 | console.log(binarySearch([1, 2, 3, 4, 5], 6)); //-1 26 | -------------------------------------------------------------------------------- /capitalizeFirst.js: -------------------------------------------------------------------------------- 1 | function capitalizeFirst(words, index) { 2 | if (index === undefined) { 3 | return capitalizeFirst(words, words.length - 1); 4 | } else if (index < 0) { 5 | return words; 6 | } else { 7 | const firstLetter = words[index].charAt(0); 8 | words[index] = words[index].replace(firstLetter, firstLetter.toUpperCase()); 9 | return capitalizeFirst(words, index - 1); 10 | } 11 | } 12 | 13 | console.log(capitalizeFirst(["car", "taco", "banana"])); // ['Car','Taco','Banana'] 14 | -------------------------------------------------------------------------------- /compareWithBackspace.js: -------------------------------------------------------------------------------- 1 | // This week's question: 2 | // Given two strings n and m, return true if they are equal when both are typed into empty text editors. The twist: # means a backspace character. 3 | function processString(str) { 4 | return str 5 | .split("") 6 | .reduce((acc, letter) => { 7 | letter == "#" ? acc.pop() : acc.push(letter); 8 | return acc; 9 | }, []) 10 | .join(""); 11 | } 12 | function compareWithBackspace(a, b) { 13 | return processString(a) == processString(b); 14 | } 15 | console.log(compareWithBackspace("a##c", "#a#c")); // true -both strings become "c" 16 | console.log(compareWithBackspace("xy##", "z#w#")); // true - both strings become "" 17 | -------------------------------------------------------------------------------- /condensedString.js: -------------------------------------------------------------------------------- 1 | /* 2 | Write a function to compress a stringby counting the repeated characters. 3 | Example: `aabbbbccdeeffffddddd` -> `a2b4c2d1e2f4d5` 4 | */ 5 | 6 | // for each letter 7 | // add the letter to my new string 8 | // count the new occurences of it 9 | // add the final count to my string 10 | 11 | function compressString(string) { 12 | let i; 13 | let currentLetter = string[0]; 14 | let compressedString = ""; 15 | let currentCount = 0; 16 | 17 | // aaabb 18 | 19 | if (!string) { 20 | return ""; 21 | } 22 | 23 | for (i = 0; i < string.length; i++) { 24 | // first time seeing this letter 25 | if (string[i] != currentLetter) { 26 | compressedString = compressedString + currentLetter + currentCount; 27 | currentLetter = string[i]; 28 | currentCount = 1; 29 | } else { 30 | // not first time seeing letter 31 | 32 | currentCount++; 33 | } 34 | } 35 | 36 | return compressedString + currentLetter + currentCount; 37 | } 38 | 39 | console.log(compressString("aabbb")); 40 | console.log(compressString("a")); 41 | console.log(compressString("")); 42 | console.log(compressString("ab")); 43 | console.log(compressString("aabbbbccdeef")); 44 | -------------------------------------------------------------------------------- /consonantValue.js: -------------------------------------------------------------------------------- 1 | // Given a lowercase string that has alphabetic characters only and no spaces, return the highest value of consonant substrings.Consonants are any letters of the alpahabet except "aeiou". 2 | 3 | // We shall assign the following values: a = 1, b = 2, c = 3, ....z = 26. 4 | 5 | // For example, for the word "zodiacs", let's cross out the vowels. We get: "z o d ia cs" 6 | 7 | // --The consonant substrings are: "z", "d" and "cs" and the values are z = 26, d = 4 and cs = 3 + 19 = 22. The highest is 26. 8 | // solve("zodiacs") = 26 9 | 10 | // For the word "strength", solve("strength") = 57 11 | // --The consonant substrings are: "str" and "ngth" with values "str" = 19 + 20 + 18 = 57 and "ngth" = 14 + 7 + 20 + 8 = 49. The highest is 57 12 | 13 | function solve(s) { 14 | const alphabet = "abcdefghijklmnopqrstuvwxyz".split(""); 15 | const letterValue = new Map(); 16 | 17 | for (letter in alphabet) { 18 | letterValue.set(alphabet[letter], parseInt(letter) + 1); 19 | } 20 | // console.log(letterValue); 21 | 22 | const input = s.split(""); 23 | let max = 0; 24 | let currentStreak = 0; 25 | 26 | for (letter of input) { 27 | if (["a", "e", "i", "o", "u"].includes(letter)) { 28 | currentStreak = 0; 29 | } else { 30 | currentStreak += letterValue.get(letter); 31 | if (currentStreak > max) { 32 | max = currentStreak; 33 | } 34 | } 35 | } 36 | 37 | return max; 38 | } 39 | -------------------------------------------------------------------------------- /countSockPairs.js: -------------------------------------------------------------------------------- 1 | // John works at a clothing store.He has a large pile of socks that he must pair by color for sale.Given an array of integers representing the color of each sock, determine how many pairs of socks with matching colors there are. 2 | 3 | // For example, there are 4 | // socks with colors.There is one pair of color and one of color.There are three odd socks left, one of each color.The number of pairs is 5 | 6 | // . 7 | 8 | // Function Description 9 | 10 | // Complete the sockMerchant function in the editor below.It must return an integer representing the number of matching pairs of socks that are available. 11 | 12 | // sockMerchant has the following parameter(s): 13 | 14 | // n: the number of socks in the pile 15 | // ar: the colors of each sock 16 | 17 | // https://www.hackerrank.com/challenges/sock-merchant/problem?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=warmup 18 | 19 | function sockMerchant(n, ar) { 20 | const sockCollection = new Map(); 21 | let pairs = 0; 22 | for (var sock of ar) { 23 | if (sockCollection.has(sock)) { 24 | sockCollection.set(sock, sockCollection.get(sock) + 1); 25 | if (sockCollection.get(sock) % 2 == 0) { 26 | pairs++; 27 | } 28 | } else { 29 | sockCollection.set(sock, 1); 30 | } 31 | } 32 | 33 | return pairs; 34 | } 35 | -------------------------------------------------------------------------------- /countUniqueValues.js: -------------------------------------------------------------------------------- 1 | function countUniqueValues(values) { 2 | let count = 0; 3 | for (value in values) { 4 | if ( 5 | values[value] != values[value - 1] && 6 | values[value] != values[value + 1] 7 | ) { 8 | count++; 9 | } 10 | } 11 | return count; 12 | } 13 | 14 | // console.log(countUniqueValues([])); // 0 15 | 16 | // console.log(countUniqueValues([1])); // 1 17 | // console.log(countUniqueValues([1, 1, 2, 3, 4])); //4 18 | // console.log(countUniqueValues([-2, -1, -1, 0, 1])); //4 19 | 20 | // can we alter array? if so, let's use pointers! 21 | // function countUniqueValuesWithPointer(values) { 22 | // let j = 0; 23 | 24 | // if (values.length === 0) { 25 | // return 0; 26 | // } 27 | 28 | // for (let value in values) { 29 | // if (values[value] == values[j]) { 30 | // values[j] = values[value]; 31 | // } else { 32 | // j++; 33 | // values[j] = values[value]; 34 | // } 35 | // } 36 | 37 | // return j + 1; 38 | // } 39 | 40 | function countUniqueValuesWithPointer(array) { 41 | if (!array || array.length === 0) { 42 | return 0; 43 | } 44 | 45 | let pointer = 0; 46 | 47 | for (let number of array) { 48 | if (number !== array[pointer]) { 49 | pointer++; 50 | array[pointer] = number; 51 | } 52 | } 53 | return pointer + 1; 54 | } 55 | 56 | console.log(countUniqueValuesWithPointer([])); // 0 57 | console.log(countUniqueValuesWithPointer([1])); // 1 58 | 59 | // [1,2,3, 4, xxxx ] //3 60 | 61 | console.log(countUniqueValuesWithPointer([1, 1, 2, 3, 4])); //4 62 | console.log(countUniqueValuesWithPointer([-2, -1, -1, 0, 1])); //4 63 | -------------------------------------------------------------------------------- /cracklePop.js: -------------------------------------------------------------------------------- 1 | // Code CracklePop 2 | // Write a program that prints out the numbers 1 to 100(inclusive). 3 | // If the number is divisible by 3, print Crackle instead of the number. 4 | // If it's divisible by 5, print Pop. 5 | // If it's divisible by both 3 and 5, print CracklePop.You can use any language. 6 | 7 | function cracklePop() { 8 | let count = 0; 9 | 10 | while (count != 101) { 11 | if (count % 3 == 0 && count % 5 === 0) { 12 | console.log("CracklePop"); 13 | } else if (count % 3 == 0) { 14 | console.log("Crackle"); 15 | } else if (count % 5 === 0) { 16 | console.log("Pop"); 17 | } else { 18 | console.log(count); 19 | } 20 | count++; 21 | } 22 | } 23 | 24 | cracklePop(); 25 | -------------------------------------------------------------------------------- /domTree.js: -------------------------------------------------------------------------------- 1 | // code-along .. should redo 2 | // we have two identical DOM trees, A and B. For DOM tree A, we have 3 | // the location of an element. Create a function to find that same element 4 | // in tree B. 5 | 6 | function reversePath(element, root) { 7 | const path = []; 8 | let pointer = element; 9 | 10 | while (pointer.parent) { 11 | const index = pointer.parent.children.indexOf(pointer); 12 | path.push(index); 13 | pointer = pointer.parent; 14 | } 15 | 16 | pointer = root; 17 | 18 | while (path.length) { 19 | pointer = children(path.pop()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /doubly-linked-lists/dllGetExercise.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | this.prev = null; 6 | } 7 | } 8 | 9 | class DoublyLinkedList { 10 | constructor(val) { 11 | this.length = 0; 12 | this.head = null; 13 | this.tail = null; 14 | } 15 | push(val) { 16 | var node = new Node(val); 17 | if (this.head === null) { 18 | this.head = node; 19 | this.tail = this.head; 20 | } else { 21 | this.tail.next = node; 22 | node.prev = this.tail; 23 | this.tail = node; 24 | } 25 | this.length++; 26 | return this; 27 | } 28 | get(index) { 29 | //find node at specified index 30 | //is the index valid? 31 | 32 | if (index > this.length || index < 0) return undefined; 33 | 34 | if (index === 0) { 35 | return this.head; 36 | } 37 | 38 | if (index === this.length - 1) { 39 | return this.tail; 40 | } 41 | 42 | let count; 43 | let node; 44 | if (index >= this.length / 2) { 45 | count = this.length - 1; 46 | node = this.tail; 47 | while (count !== index) { 48 | node = node.prev; 49 | count--; 50 | } 51 | } 52 | 53 | if (index < this.length / 2) { 54 | node = this.head; 55 | count = 0; 56 | 57 | while (count !== index) { 58 | node = node.next; 59 | count++; 60 | } 61 | } 62 | return node; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /doubly-linked-lists/dllPopExercise.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | this.prev = null; 6 | } 7 | } 8 | 9 | class DoublyLinkedList { 10 | constructor(val) { 11 | this.head = null; 12 | this.tail = null; 13 | this.length = 0; 14 | } 15 | push(val) { 16 | const newNode = new Node(val); 17 | if (!this.head) { 18 | this.head = newNode; 19 | this.tail = newNode; 20 | this.length = 1; 21 | return this; 22 | } else { 23 | this.tail.next = newNode; 24 | newNode.prev = this.tail; 25 | this.tail = newNode; 26 | } 27 | this.length++; 28 | return this; 29 | } 30 | pop() { 31 | let oldTail = this.tail; 32 | 33 | //remove the last item from list 34 | if (this.length == 0) { 35 | return undefined; 36 | } 37 | if (this.length === 1) { 38 | this.head = null; 39 | this.tail = null; 40 | } else { 41 | this.tail = oldTail.prev; 42 | this.tail.next = null; 43 | oldTail.prev = null; 44 | oldTail.next = null; 45 | } 46 | this.length--; 47 | return oldTail; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /doubly-linked-lists/dllPushExercise.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | this.prev = null; 6 | } 7 | } 8 | 9 | class DoublyLinkedList { 10 | constructor(val) { 11 | // this.val = val; 12 | // this.next = null; 13 | this.length = 0; 14 | this.head = null; 15 | this.tail = null; 16 | } 17 | // accept a value 18 | // add node to the end of DoublyLinkedList 19 | // return the DoubleLinkedList 20 | push(val) { 21 | const newNode = new Node(val); 22 | if (!this.head) { 23 | this.head = newNode; 24 | this.tail = newNode; 25 | this.length = 1; 26 | return this; 27 | } else { 28 | this.tail.next = newNode; 29 | newNode.prev = this.tail; 30 | this.tail = newNode; 31 | } 32 | this.length++; 33 | return this; 34 | } 35 | } 36 | 37 | const list = new DoublyLinkedList(); 38 | console.log(list.push(2)); 39 | console.log(list.push(6)); 40 | 41 | // class Node { 42 | // constructor(val) { 43 | // this.val = val 44 | // this.next = null; 45 | // this.prev = null; 46 | // } 47 | // } 48 | 49 | // class DoublyLinkedList { 50 | // constructor(val) { 51 | // this.val = val 52 | // this.next = null; 53 | // } 54 | // push() { 55 | // } 56 | 57 | //} 58 | -------------------------------------------------------------------------------- /doubly-linked-lists/dllSetExercise.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | this.prev = null; 6 | } 7 | } 8 | 9 | class DoublyLinkedList { 10 | constructor(val) { 11 | // this.val = val; 12 | // this.next = null; 13 | this.tail = null; 14 | this.head = null; 15 | this.length = 0; 16 | } 17 | push(val) { 18 | var node = new Node(val); 19 | if (this.head === null) { 20 | this.head = node; 21 | this.tail = this.head; 22 | } else { 23 | this.tail.next = node; 24 | node.prev = this.tail; 25 | this.tail = node; 26 | } 27 | this.length++; 28 | return this; 29 | } 30 | 31 | //update value at specified index 32 | set(index, val) { 33 | if (index < 0 || index > this.length - 1) { 34 | return false; 35 | } 36 | 37 | if (index == this.length) { 38 | return this.push(val); 39 | } 40 | 41 | let count = 0; 42 | 43 | let currentNode = this.head; 44 | 45 | while (count != index) { 46 | currentNode = currentNode.next; 47 | count++; 48 | } 49 | 50 | currentNode.val = val; 51 | 52 | return true; 53 | } 54 | } 55 | 56 | const list = new DoublyLinkedList(); 57 | 58 | list.push(1); 59 | list.push(2); 60 | list.push(3); 61 | 62 | console.log(list.set(0, 100)); 63 | console.log(list); 64 | 65 | console.log(list.set(2, 500)); 66 | 67 | console.log(list); 68 | -------------------------------------------------------------------------------- /doubly-linked-lists/dllShiftExercise.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | this.prev = null; 6 | } 7 | } 8 | 9 | class DoublyLinkedList { 10 | constructor(val) { 11 | // this.val = val; 12 | // this.next = null; 13 | this.length = 0; 14 | this.head = null; 15 | this.tail = null; 16 | } 17 | push(val) { 18 | var node = new Node(val); 19 | if (this.head === null) { 20 | this.head = node; 21 | this.tail = this.head; 22 | } else { 23 | this.tail.next = node; 24 | node.prev = this.tail; 25 | this.tail = node; 26 | } 27 | this.length++; 28 | return this; 29 | } 30 | //remove the node at the beginning of linked list 31 | shift() { 32 | if (!this.head) return undefined; 33 | 34 | let removedNode = this.head; 35 | if (this.length == 1) { 36 | this.tail = null; 37 | this.head = null; 38 | } else { 39 | this.head = removedNode.next; 40 | this.head.prev = null; 41 | removedNode.next = null; 42 | removedNode.prev = null; 43 | } 44 | 45 | this.length--; 46 | return removedNode; 47 | } 48 | } 49 | 50 | const list = new DoublyLinkedList(); 51 | console.log(list.push(4)); 52 | console.log(list.push(4)); 53 | console.log(list.shift()); 54 | console.log(list); 55 | -------------------------------------------------------------------------------- /doubly-linked-lists/dllUnshiftExercise.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | this.prev = null; 6 | } 7 | } 8 | 9 | class DoublyLinkedList { 10 | constructor(val) { 11 | // this.val = val; 12 | // this.next = null; 13 | this.length = 0; 14 | this.head = null; 15 | this.tail = null; 16 | } 17 | push(val) { 18 | var node = new Node(val); 19 | if (this.head === null) { 20 | this.head = node; 21 | this.tail = this.head; 22 | } else { 23 | this.tail.next = node; 24 | node.prev = this.tail; 25 | this.tail = node; 26 | } 27 | this.length++; 28 | return this; 29 | } 30 | unshift(val) { 31 | // add node to the beginning of linked list 32 | const newNode = new Node(val); 33 | if (!this.head) { 34 | this.head = newNode; 35 | this.tail = newNode; 36 | } else { 37 | let currentHead = this.head; 38 | this.head.prev = newNode; 39 | newNode.next = currentHead; 40 | this.head = newNode; 41 | } 42 | 43 | this.length++; 44 | return this; 45 | } 46 | } 47 | 48 | const list = new DoublyLinkedList(); 49 | 50 | console.log(list.unshift(1)); 51 | console.log(list.unshift(200)); 52 | -------------------------------------------------------------------------------- /doubly-linked-lists/getDoublyLinkedList.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | this.prev = null; 6 | } 7 | } 8 | 9 | class DoublyLinkedList { 10 | constructor() { 11 | this.head = null; 12 | this.tail = null; 13 | this.length = 0; 14 | } 15 | 16 | get(index) { 17 | // if index is less than 0 18 | // or greater or equal to length return null 19 | 20 | // if index is less than or equal to half the length og list 21 | 22 | // index is greather than half the length of the list 23 | 24 | if (index < 0 || index >= this.length) return null; 25 | 26 | let count, current; 27 | if (index <= this.length / 2) { 28 | count = 0; 29 | current = this.head; 30 | while (count != index) { 31 | current = current.next; 32 | count++; 33 | } 34 | } else if (index > this.length / 2) { 35 | count = this.length - 1; 36 | current = this.tail; 37 | while (count !== index) { 38 | current = current.prev; 39 | count--; 40 | } 41 | } 42 | return current; 43 | } 44 | 45 | unshift(val) { 46 | const newNode = new Node(val); 47 | 48 | if (this.length === 0) { 49 | this.head = newNode; 50 | this.tail = newNode; 51 | } else { 52 | this.head.prev = newNode; 53 | newNode.next = this.head; 54 | this.head = newNode; 55 | } 56 | 57 | this.length++; 58 | return this; 59 | } 60 | 61 | shift() { 62 | ///if length == 0 return undefined 63 | // else store oldhead 64 | // if length is oone, head and tail should be null 65 | //update the head to be the next of the old head 66 | // set the head's prev property to null 67 | // set the old head's next to null 68 | 69 | // decremeent length 70 | 71 | if (this.length === 0) return undefined; 72 | 73 | const oldHead = this.head; 74 | 75 | if (this.length === 1) { 76 | this.head = null; 77 | this.tail = null; 78 | } else { 79 | this.head = oldHead.next; 80 | this.head.prev = null; 81 | oldHead.next = null; 82 | } 83 | 84 | this.length--; 85 | 86 | return oldHead; 87 | } 88 | 89 | push(val) { 90 | // create a new node with value passed into the function 91 | // if the head property === null 92 | // set the head and tail to be the newly created node 93 | 94 | const newNode = new Node(val); 95 | 96 | if (this.length === 0) { 97 | this.head = newNode; 98 | this.tail = newNode; 99 | } else { 100 | // the tail's next should equal newly added node 101 | this.tail.next = newNode; 102 | // the newly added node's previous value should equal the tail 103 | newNode.prev = this.tail; 104 | 105 | this.tail = newNode; 106 | } 107 | this.length++; 108 | return this; 109 | } 110 | 111 | pop() { 112 | // if no head return undefined 113 | // take current tail, store it in variable 114 | 115 | const oldTail = this.tail; 116 | // if length is 1 set head and tail to null 117 | // update tail to be the previous node 118 | // set the newTails.next to null 119 | // return the old tail 120 | 121 | // the list is empty 122 | if (!this.head) { 123 | return undefined; 124 | } else if (this.length == 1) { 125 | this.head = null; 126 | this.tail = null; 127 | } else { 128 | this.tail = oldTail.prev; 129 | // this.tail = this.tail.prev; 130 | this.tail.next = null; 131 | } 132 | this.length--; 133 | // return this; 134 | return oldTail; 135 | } 136 | } 137 | 138 | let list = new DoublyLinkedList(); 139 | 140 | list.push(4); 141 | list.push("Hello"); 142 | list.push(42); 143 | 144 | list.push(200); 145 | console.log(list.get(3)); 146 | -------------------------------------------------------------------------------- /doubly-linked-lists/initialDoublyLinkedList.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | this.prev = null; 6 | } 7 | } 8 | 9 | class DoublyLinkedList { 10 | constructor() { 11 | this.head = null; 12 | this.length = 0; 13 | this.tail = null; 14 | } 15 | } 16 | 17 | first = new Node(12); 18 | first.next = new Node(12); 19 | console.log(first); 20 | -------------------------------------------------------------------------------- /doubly-linked-lists/insertDoublyLinkedList.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | this.prev = null; 6 | } 7 | } 8 | 9 | class DoublyLinkedList { 10 | constructor() { 11 | this.head = null; 12 | this.tail = null; 13 | this.length = 0; 14 | } 15 | 16 | set(index, val) { 17 | let node = this.get(index); 18 | 19 | if (node !== null) { 20 | node.val = val; 21 | return true; 22 | } 23 | return false; 24 | } 25 | 26 | insert(index, val) { 27 | if (index > 0 || index > this.length) return false; 28 | 29 | if (index == 0) return this.unshift(val); 30 | 31 | if (index === this.length) return this.push(val); 32 | 33 | let newNode = new Node(val); 34 | let prevNode = this.get(index - 1); 35 | 36 | //let afterNode = prevNode.next; 37 | 38 | let nextNode = prevNode.next; 39 | (prevNode.next = newNode), (newNode.prev = prevNode); 40 | (newNode.next = nextNode), (nextNode.prev = newNode); 41 | 42 | length++; 43 | return true; 44 | } 45 | 46 | get(index) { 47 | // if index is less than 0 48 | // or greater or equal to length return null 49 | 50 | // if index is less than or equal to half the length og list 51 | 52 | // index is greather than half the length of the list 53 | 54 | if (index < 0 || index >= this.length) return null; 55 | 56 | let count, current; 57 | if (index <= this.length / 2) { 58 | count = 0; 59 | current = this.head; 60 | while (count != index) { 61 | current = current.next; 62 | count++; 63 | } 64 | } else if (index > this.length / 2) { 65 | count = this.length - 1; 66 | current = this.tail; 67 | while (count !== index) { 68 | current = current.prev; 69 | count--; 70 | } 71 | } 72 | return current; 73 | } 74 | 75 | unshift(val) { 76 | const newNode = new Node(val); 77 | 78 | if (this.length === 0) { 79 | this.head = newNode; 80 | this.tail = newNode; 81 | } else { 82 | this.head.prev = newNode; 83 | newNode.next = this.head; 84 | this.head = newNode; 85 | } 86 | 87 | this.length++; 88 | return this; 89 | } 90 | 91 | shift() { 92 | ///if length == 0 return undefined 93 | // else store oldhead 94 | // if length is oone, head and tail should be null 95 | //update the head to be the next of the old head 96 | // set the head's prev property to null 97 | // set the old head's next to null 98 | 99 | // decremeent length 100 | 101 | if (this.length === 0) return undefined; 102 | 103 | const oldHead = this.head; 104 | 105 | if (this.length === 1) { 106 | this.head = null; 107 | this.tail = null; 108 | } else { 109 | this.head = oldHead.next; 110 | this.head.prev = null; 111 | oldHead.next = null; 112 | } 113 | 114 | this.length--; 115 | 116 | return oldHead; 117 | } 118 | 119 | push(val) { 120 | // create a new node with value passed into the function 121 | // if the head property === null 122 | // set the head and tail to be the newly created node 123 | 124 | const newNode = new Node(val); 125 | 126 | if (this.length === 0) { 127 | this.head = newNode; 128 | this.tail = newNode; 129 | } else { 130 | // the tail's next should equal newly added node 131 | this.tail.next = newNode; 132 | // the newly added node's previous value should equal the tail 133 | newNode.prev = this.tail; 134 | 135 | this.tail = newNode; 136 | } 137 | this.length++; 138 | return this; 139 | } 140 | 141 | pop() { 142 | // if no head return undefined 143 | // take current tail, store it in variable 144 | 145 | const oldTail = this.tail; 146 | // if length is 1 set head and tail to null 147 | // update tail to be the previous node 148 | // set the newTails.next to null 149 | // return the old tail 150 | 151 | // the list is empty 152 | if (!this.head) { 153 | return undefined; 154 | } else if (this.length == 1) { 155 | this.head = null; 156 | this.tail = null; 157 | } else { 158 | this.tail = oldTail.prev; 159 | // this.tail = this.tail.prev; 160 | this.tail.next = null; 161 | } 162 | this.length--; 163 | // return this; 164 | return oldTail; 165 | } 166 | } 167 | 168 | let list = new DoublyLinkedList(); 169 | 170 | list.push(4); 171 | list.push("Hello"); 172 | list.push(42); 173 | 174 | list.push(200); 175 | console.log(list.set(0, "Goodbye")); 176 | console.log(list.insert(0, "hoop")); 177 | console.log(list); 178 | -------------------------------------------------------------------------------- /doubly-linked-lists/popDoublyLinkedList.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | this.prev = null; 6 | } 7 | } 8 | 9 | class DoublyLinkedList { 10 | constructor() { 11 | this.head = null; 12 | this.tail = null; 13 | this.length = 0; 14 | } 15 | 16 | push(val) { 17 | // create a new node with value passed into the function 18 | // if the head property === null 19 | // set the head and tail to be the newly created node 20 | 21 | const newNode = new Node(val); 22 | 23 | if (this.length === 0) { 24 | this.head = newNode; 25 | this.tail = newNode; 26 | } else { 27 | // the tail's next should equal newly added node 28 | this.tail.next = newNode; 29 | // the newly added node's previous value should equal the tail 30 | newNode.prev = this.tail; 31 | 32 | this.tail = newNode; 33 | } 34 | this.length++; 35 | return this; 36 | } 37 | 38 | pop() { 39 | // if no head return undefined 40 | // take current tail, store it in variable 41 | 42 | const oldTail = this.tail; 43 | // if length is 1 set head and tail to null 44 | // update tail to be the previous node 45 | // set the newTails.next to null 46 | // return the old tail 47 | 48 | // the list is empty 49 | if (!this.head) { 50 | return undefined; 51 | } else if (this.length == 1) { 52 | this.head = null; 53 | this.tail = null; 54 | } else { 55 | this.tail = oldTail.prev; 56 | // this.tail = this.tail.prev; 57 | this.tail.next = null; 58 | } 59 | this.length--; 60 | // return this; 61 | return oldTail; 62 | } 63 | } 64 | 65 | let list = new DoublyLinkedList(); 66 | 67 | console.log(list.push(4)); 68 | console.log(list.push("Hello")); 69 | console.log(list.push(42)); 70 | console.log(list.pop()); 71 | console.log(list.pop()); 72 | console.log(list.pop()); 73 | console.log(list.pop()); 74 | -------------------------------------------------------------------------------- /doubly-linked-lists/pushDoublyLinkedList.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | this.prev = null; 6 | } 7 | } 8 | 9 | class DoublyLinkedList { 10 | constructor() { 11 | this.head = null; 12 | this.tail = null; 13 | this.length = 0; 14 | } 15 | 16 | push(val) { 17 | // create a new node with value passed into the function 18 | // if the head property === null 19 | // set the head and tail to be the newly created node 20 | 21 | const newNode = new Node(val); 22 | 23 | if (this.length === 0) { 24 | this.head = newNode; 25 | this.tail = newNode; 26 | } else { 27 | // the tail's next should equal newly added node 28 | this.tail.next = newNode; 29 | // the newly added node's previous value should equal the tail 30 | newNode.prev = this.tail; 31 | 32 | this.tail = newNode; 33 | } 34 | this.length++; 35 | return this; 36 | } 37 | } 38 | 39 | let list = new DoublyLinkedList(); 40 | 41 | console.log(list.push(4)); 42 | console.log(list.push("Hello")); 43 | console.log(list.push(42)); 44 | -------------------------------------------------------------------------------- /doubly-linked-lists/removeDoublyLinkedList.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | this.prev = null; 6 | } 7 | } 8 | 9 | class DoublyLinkedList { 10 | constructor() { 11 | this.head = null; 12 | this.tail = null; 13 | this.length = 0; 14 | } 15 | 16 | remove(index) { 17 | if (index < 0 || index >= this.length) return undefined; 18 | 19 | if (index === 0) return this.shift(); 20 | if (index === this.length - 1) return this.pop(); 21 | 22 | let foundNode = this.get(index); 23 | 24 | foundNode.prev.next = foundNode.next; 25 | foundNode.next.prev = foundNode.prev; 26 | 27 | foundNode.prev = null; 28 | foundNode.next = null; 29 | 30 | this.length--; 31 | 32 | return foundNode; 33 | } 34 | 35 | set(index, val) { 36 | let node = this.get(index); 37 | 38 | if (node !== null) { 39 | node.val = val; 40 | return true; 41 | } 42 | return false; 43 | } 44 | 45 | insert(index, val) { 46 | if (index > 0 || index > this.length) return false; 47 | 48 | if (index == 0) return this.unshift(val); 49 | 50 | if (index === this.length) return this.push(val); 51 | 52 | let newNode = new Node(val); 53 | let prevNode = this.get(index - 1); 54 | 55 | //let afterNode = prevNode.next; 56 | 57 | let nextNode = prevNode.next; 58 | (prevNode.next = newNode), (newNode.prev = prevNode); 59 | (newNode.next = nextNode), (nextNode.prev = newNode); 60 | 61 | length++; 62 | return true; 63 | } 64 | 65 | get(index) { 66 | // if index is less than 0 67 | // or greater or equal to length return null 68 | 69 | // if index is less than or equal to half the length og list 70 | 71 | // index is greather than half the length of the list 72 | 73 | if (index < 0 || index >= this.length) return null; 74 | 75 | let count, current; 76 | if (index <= this.length / 2) { 77 | count = 0; 78 | current = this.head; 79 | while (count != index) { 80 | current = current.next; 81 | count++; 82 | } 83 | } else if (index > this.length / 2) { 84 | count = this.length - 1; 85 | current = this.tail; 86 | while (count !== index) { 87 | current = current.prev; 88 | count--; 89 | } 90 | } 91 | return current; 92 | } 93 | 94 | unshift(val) { 95 | const newNode = new Node(val); 96 | 97 | if (this.length === 0) { 98 | this.head = newNode; 99 | this.tail = newNode; 100 | } else { 101 | this.head.prev = newNode; 102 | newNode.next = this.head; 103 | this.head = newNode; 104 | } 105 | 106 | this.length++; 107 | return this; 108 | } 109 | 110 | shift() { 111 | ///if length == 0 return undefined 112 | // else store oldhead 113 | // if length is oone, head and tail should be null 114 | //update the head to be the next of the old head 115 | // set the head's prev property to null 116 | // set the old head's next to null 117 | 118 | // decremeent length 119 | 120 | if (this.length === 0) return undefined; 121 | 122 | const oldHead = this.head; 123 | 124 | if (this.length === 1) { 125 | this.head = null; 126 | this.tail = null; 127 | } else { 128 | this.head = oldHead.next; 129 | this.head.prev = null; 130 | oldHead.next = null; 131 | } 132 | 133 | this.length--; 134 | 135 | return oldHead; 136 | } 137 | 138 | push(val) { 139 | // create a new node with value passed into the function 140 | // if the head property === null 141 | // set the head and tail to be the newly created node 142 | 143 | const newNode = new Node(val); 144 | 145 | if (this.length === 0) { 146 | this.head = newNode; 147 | this.tail = newNode; 148 | } else { 149 | // the tail's next should equal newly added node 150 | this.tail.next = newNode; 151 | // the newly added node's previous value should equal the tail 152 | newNode.prev = this.tail; 153 | 154 | this.tail = newNode; 155 | } 156 | this.length++; 157 | return this; 158 | } 159 | 160 | pop() { 161 | // if no head return undefined 162 | // take current tail, store it in variable 163 | 164 | const oldTail = this.tail; 165 | // if length is 1 set head and tail to null 166 | // update tail to be the previous node 167 | // set the newTails.next to null 168 | // return the old tail 169 | 170 | // the list is empty 171 | if (!this.head) { 172 | return undefined; 173 | } else if (this.length == 1) { 174 | this.head = null; 175 | this.tail = null; 176 | } else { 177 | this.tail = oldTail.prev; 178 | // this.tail = this.tail.prev; 179 | this.tail.next = null; 180 | } 181 | this.length--; 182 | // return this; 183 | return oldTail; 184 | } 185 | } 186 | 187 | let list = new DoublyLinkedList(); 188 | 189 | list.push(4); 190 | list.push("Hello"); 191 | list.push(42); 192 | 193 | list.push(200); 194 | // console.log(list.set(0, "Goodbye")); 195 | // console.log(list.insert(0, "hoop")); 196 | console.log(list.remove(0)); 197 | console.log(list); 198 | -------------------------------------------------------------------------------- /doubly-linked-lists/setDoublyLinkedList.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | this.prev = null; 6 | } 7 | } 8 | 9 | class DoublyLinkedList { 10 | constructor() { 11 | this.head = null; 12 | this.tail = null; 13 | this.length = 0; 14 | } 15 | 16 | set(index, val) { 17 | let node = this.get(index); 18 | 19 | if (node !== ) { 20 | node.val = val; 21 | return true; 22 | } 23 | return false; 24 | } 25 | get(index) { 26 | // if index is less than 0 27 | // or greater or equal to length return null 28 | 29 | // if index is less than or equal to half the length og list 30 | 31 | // index is greather than half the length of the list 32 | 33 | if (index < 0 || index >= this.length) return null; 34 | 35 | let count, current; 36 | if (index <= this.length / 2) { 37 | count = 0; 38 | current = this.head; 39 | while (count != index) { 40 | current = current.next; 41 | count++; 42 | } 43 | } else if (index > this.length / 2) { 44 | count = this.length - 1; 45 | current = this.tail; 46 | while (count !== index) { 47 | current = current.prev; 48 | count--; 49 | } 50 | } 51 | return current; 52 | } 53 | 54 | unshift(val) { 55 | const newNode = new Node(val); 56 | 57 | if (this.length === 0) { 58 | this.head = newNode; 59 | this.tail = newNode; 60 | } else { 61 | this.head.prev = newNode; 62 | newNode.next = this.head; 63 | this.head = newNode; 64 | } 65 | 66 | this.length++; 67 | return this; 68 | } 69 | 70 | shift() { 71 | ///if length == 0 return undefined 72 | // else store oldhead 73 | // if length is oone, head and tail should be null 74 | //update the head to be the next of the old head 75 | // set the head's prev property to null 76 | // set the old head's next to null 77 | 78 | // decremeent length 79 | 80 | if (this.length === 0) return undefined; 81 | 82 | const oldHead = this.head; 83 | 84 | if (this.length === 1) { 85 | this.head = null; 86 | this.tail = null; 87 | } else { 88 | this.head = oldHead.next; 89 | this.head.prev = null; 90 | oldHead.next = null; 91 | } 92 | 93 | this.length--; 94 | 95 | return oldHead; 96 | } 97 | 98 | push(val) { 99 | // create a new node with value passed into the function 100 | // if the head property === null 101 | // set the head and tail to be the newly created node 102 | 103 | const newNode = new Node(val); 104 | 105 | if (this.length === 0) { 106 | this.head = newNode; 107 | this.tail = newNode; 108 | } else { 109 | // the tail's next should equal newly added node 110 | this.tail.next = newNode; 111 | // the newly added node's previous value should equal the tail 112 | newNode.prev = this.tail; 113 | 114 | this.tail = newNode; 115 | } 116 | this.length++; 117 | return this; 118 | } 119 | 120 | pop() { 121 | // if no head return undefined 122 | // take current tail, store it in variable 123 | 124 | const oldTail = this.tail; 125 | // if length is 1 set head and tail to null 126 | // update tail to be the previous node 127 | // set the newTails.next to null 128 | // return the old tail 129 | 130 | // the list is empty 131 | if (!this.head) { 132 | return undefined; 133 | } else if (this.length == 1) { 134 | this.head = null; 135 | this.tail = null; 136 | } else { 137 | this.tail = oldTail.prev; 138 | // this.tail = this.tail.prev; 139 | this.tail.next = null; 140 | } 141 | this.length--; 142 | // return this; 143 | return oldTail; 144 | } 145 | } 146 | 147 | let list = new DoublyLinkedList(); 148 | 149 | list.push(4); 150 | list.push("Hello"); 151 | list.push(42); 152 | 153 | list.push(200); 154 | console.log(list.set(1, "Goodbye")); 155 | -------------------------------------------------------------------------------- /doubly-linked-lists/shiftDoublyLinkedList.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | this.prev = null; 6 | } 7 | } 8 | 9 | class DoublyLinkedList { 10 | constructor() { 11 | this.head = null; 12 | this.tail = null; 13 | this.length = 0; 14 | } 15 | 16 | shift() { 17 | ///if length == 0 return undefined 18 | // else store oldhead 19 | // if length is oone, head and tail should be null 20 | //update the head to be the next of the old head 21 | // set the head's prev property to null 22 | // set the old head's next to null 23 | 24 | // decremeent length 25 | 26 | if (this.length === 0) return undefined; 27 | 28 | const oldHead = this.head; 29 | 30 | if (this.length === 1) { 31 | this.head = null; 32 | this.tail = null; 33 | } else { 34 | this.head = oldHead.next; 35 | this.head.prev = null; 36 | oldHead.next = null; 37 | } 38 | 39 | this.length--; 40 | 41 | return oldHead; 42 | } 43 | 44 | push(val) { 45 | // create a new node with value passed into the function 46 | // if the head property === null 47 | // set the head and tail to be the newly created node 48 | 49 | const newNode = new Node(val); 50 | 51 | if (this.length === 0) { 52 | this.head = newNode; 53 | this.tail = newNode; 54 | } else { 55 | // the tail's next should equal newly added node 56 | this.tail.next = newNode; 57 | // the newly added node's previous value should equal the tail 58 | newNode.prev = this.tail; 59 | 60 | this.tail = newNode; 61 | } 62 | this.length++; 63 | return this; 64 | } 65 | 66 | pop() { 67 | // if no head return undefined 68 | // take current tail, store it in variable 69 | 70 | const oldTail = this.tail; 71 | // if length is 1 set head and tail to null 72 | // update tail to be the previous node 73 | // set the newTails.next to null 74 | // return the old tail 75 | 76 | // the list is empty 77 | if (!this.head) { 78 | return undefined; 79 | } else if (this.length == 1) { 80 | this.head = null; 81 | this.tail = null; 82 | } else { 83 | this.tail = oldTail.prev; 84 | // this.tail = this.tail.prev; 85 | this.tail.next = null; 86 | } 87 | this.length--; 88 | // return this; 89 | return oldTail; 90 | } 91 | } 92 | 93 | let list = new DoublyLinkedList(); 94 | 95 | console.log(list.push(4)); 96 | console.log(list.push("Hello")); 97 | console.log(list.push(42)); 98 | // console.log(list.pop()); 99 | // console.log(list.pop()); 100 | // console.log(list.pop()); 101 | // console.log(list.pop()); 102 | 103 | console.log(list.shift()); 104 | console.log(list); 105 | -------------------------------------------------------------------------------- /doubly-linked-lists/unshiftDoublyLinkedList.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | this.prev = null; 6 | } 7 | } 8 | 9 | class DoublyLinkedList { 10 | constructor() { 11 | this.head = null; 12 | this.tail = null; 13 | this.length = 0; 14 | } 15 | 16 | unshift(val) { 17 | const newNode = new Node(val); 18 | 19 | if (this.length === 0) { 20 | this.head = newNode; 21 | this.tail = newNode; 22 | } else { 23 | this.head.prev = newNode; 24 | newNode.next = this.head; 25 | this.head = newNode; 26 | } 27 | 28 | this.length++; 29 | return this; 30 | } 31 | 32 | shift() { 33 | ///if length == 0 return undefined 34 | // else store oldhead 35 | // if length is oone, head and tail should be null 36 | //update the head to be the next of the old head 37 | // set the head's prev property to null 38 | // set the old head's next to null 39 | 40 | // decremeent length 41 | 42 | if (this.length === 0) return undefined; 43 | 44 | const oldHead = this.head; 45 | 46 | if (this.length === 1) { 47 | this.head = null; 48 | this.tail = null; 49 | } else { 50 | this.head = oldHead.next; 51 | this.head.prev = null; 52 | oldHead.next = null; 53 | } 54 | 55 | this.length--; 56 | 57 | return oldHead; 58 | } 59 | 60 | push(val) { 61 | // create a new node with value passed into the function 62 | // if the head property === null 63 | // set the head and tail to be the newly created node 64 | 65 | const newNode = new Node(val); 66 | 67 | if (this.length === 0) { 68 | this.head = newNode; 69 | this.tail = newNode; 70 | } else { 71 | // the tail's next should equal newly added node 72 | this.tail.next = newNode; 73 | // the newly added node's previous value should equal the tail 74 | newNode.prev = this.tail; 75 | 76 | this.tail = newNode; 77 | } 78 | this.length++; 79 | return this; 80 | } 81 | 82 | pop() { 83 | // if no head return undefined 84 | // take current tail, store it in variable 85 | 86 | const oldTail = this.tail; 87 | // if length is 1 set head and tail to null 88 | // update tail to be the previous node 89 | // set the newTails.next to null 90 | // return the old tail 91 | 92 | // the list is empty 93 | if (!this.head) { 94 | return undefined; 95 | } else if (this.length == 1) { 96 | this.head = null; 97 | this.tail = null; 98 | } else { 99 | this.tail = oldTail.prev; 100 | // this.tail = this.tail.prev; 101 | this.tail.next = null; 102 | } 103 | this.length--; 104 | // return this; 105 | return oldTail; 106 | } 107 | } 108 | 109 | let list = new DoublyLinkedList(); 110 | 111 | list.push(4); 112 | list.push("Hello"); 113 | list.push(42); 114 | 115 | console.log(list.unshift(200)); 116 | -------------------------------------------------------------------------------- /duplicates.js: -------------------------------------------------------------------------------- 1 | // Is Unique: Implement an algorithm to determine if a string has all unique characters. 2 | // What if you cannot use additional data structures ? 3 | 4 | function isUnique(word) { 5 | const letters = word.split(""); 6 | const addedLetters = new Map(); 7 | 8 | for (var letter of letters) { 9 | if (addedLetters.has(letter)) { 10 | return false; 11 | } else { 12 | addedLetters.set(letter, 1); 13 | } 14 | } 15 | return true; 16 | } 17 | -------------------------------------------------------------------------------- /factorial.js: -------------------------------------------------------------------------------- 1 | //return the factorial of a number 2 | 3 | function factorial(number) { 4 | if (number <= 1) { 5 | return 1; 6 | } else { 7 | return number * factorial(number - 1); 8 | } 9 | } 10 | 11 | console.log(factorial(1)); //1 12 | console.log(factorial(2)); //2 13 | console.log(factorial(4)); //24 14 | console.log(factorial(7)); //5040 15 | -------------------------------------------------------------------------------- /filterExercises.js: -------------------------------------------------------------------------------- 1 | function fiveAndGreaterOnly(arr) { 2 | return arr.filter(item => item >= 5); 3 | } 4 | // test 5 | console.log(fiveAndGreaterOnly([3, 6, 8, 2])); /// [6, 8] 6 | 7 | function evensOnly(arr) { 8 | return arr.filter(item => item % 2 == 0); 9 | } 10 | // test 11 | console.log(evensOnly([3, 6, 8, 2])); /// [6, 8, 2] 12 | 13 | function fiveCharactersOrFewerOnly(arr) { 14 | return arr.filter(item => item.length <= 5); 15 | } 16 | // test 17 | console.log( 18 | fiveCharactersOrFewerOnly(["dog", "wolf", "by", "family", "eaten", "camping"]) 19 | ); // ["by", "dog", "wolf", "eaten"] 20 | 21 | function peopleWhoBelongToTheIlluminati(arr) { 22 | return arr.filter(person => person.member); 23 | } 24 | // test 25 | console.log( 26 | peopleWhoBelongToTheIlluminati([ 27 | { name: "Angelina Jolie", member: true }, 28 | { name: "Eric Jones", member: false }, 29 | { name: "Paris Hilton", member: true }, 30 | { name: "Kayne West", member: false }, 31 | { name: "Bob Ziroll", member: true } 32 | ]) 33 | ); 34 | // => 35 | //[ { name: 'Angelina Jolie', member: true }, 36 | // { name: 'Paris Hilton', member: true }, 37 | // { name: 'Bob Ziroll', member: true } ] 38 | 39 | function ofAge(arr) { 40 | return arr.filter(person => person.age > 18); 41 | } 42 | // test 43 | console.log( 44 | ofAge([ 45 | { name: "Angelina Jolie", age: 80 }, 46 | { name: "Eric Jones", age: 2 }, 47 | { name: "Paris Hilton", age: 5 }, 48 | { name: "Kayne West", age: 16 }, 49 | { name: "Bob Ziroll", age: 100 } 50 | ]) 51 | ); 52 | // => 53 | //[ { name: 'Angelina Jolie', age: 80 }, 54 | // { name: 'Bob Ziroll', age: 100 } ] 55 | -------------------------------------------------------------------------------- /findLongestSubstring.js: -------------------------------------------------------------------------------- 1 | // findLongestSubstring with distinct characters 2 | // set longest substring to 0; 3 | // create map for letters; 4 | // if same letter is encountered twice 5 | // reset streak and letter count 6 | 7 | // function findLongestSubstring(word) { 8 | // let longest = 0; 9 | // let seen = {}; 10 | // let streak = 0; 11 | 12 | // for (let letter of word) { 13 | // if (!seen[letter]) { 14 | // seen[letter] = 1; 15 | // streak++; 16 | // } else { 17 | // seen = {}; 18 | // if (streak > longest) { 19 | // longest = streak; 20 | // } 21 | // streak = 0; 22 | // } 23 | // } 24 | 25 | // return longest > streak ? longest : streak; 26 | // } 27 | 28 | console.log(findLongestSubstring("")); //0 29 | 30 | console.log(findLongestSubstring("rithmschool")); //7 31 | 32 | console.log(findLongestSubstring("thisisawesome")); //6 33 | -------------------------------------------------------------------------------- /firstUniqueLetter.js: -------------------------------------------------------------------------------- 1 | // Given a string, find the first non - repeating character in it and return it's index. If it doesn't exist, return -1. 2 | 3 | // Examples: 4 | 5 | // s = "leetcode" 6 | // return 0. 7 | 8 | // s = "loveleetcode", 9 | // return 2. 10 | 11 | // Note: You may assume the string contain only lowercase letters. 12 | 13 | /** 14 | * @param {string} s 15 | * @return {number} 16 | */ 17 | var firstUniqChar = function (s) { 18 | let letterCount = {}; 19 | let firstUnique = { seen: false, value: null }; 20 | const sArray = s.split(""); 21 | 22 | if (s.length == 0) { 23 | return -1; 24 | } 25 | 26 | for (let char of sArray) { 27 | if (letterCount[char]) { 28 | letterCount[char] = letterCount[char] + 1; 29 | } else { 30 | letterCount[char] = 1; 31 | } 32 | } 33 | 34 | for (let letter in sArray) { 35 | if (letterCount[sArray[letter]] == 1) { 36 | return letter; 37 | } 38 | } 39 | 40 | return -1; 41 | }; 42 | 43 | console.log(firstUniqChar("leetcode")); // 0 44 | console.log(firstUniqChar("loveleetcode")); // 2 45 | console.log(firstUniqChar("")); // -1 46 | console.log(firstUniqChar("aa")); // -1 47 | -------------------------------------------------------------------------------- /flattenArray.js: -------------------------------------------------------------------------------- 1 | const arr1 = [1, 2, [3, 4]]; 2 | console.log(flatten(arr1)); 3 | // [1, 2, 3, 4] 4 | 5 | const arr2 = [1, 2, [3, 4, [5, 6]]]; 6 | console.log(flatten(arr2)); 7 | // [1, 2, 3, 4, 5, 6] 8 | 9 | function flatten(array) { 10 | return array.reduce((acc, item) => { 11 | if (Array.isArray(item)) { 12 | acc = acc.concat(flatten(item)); 13 | } else { 14 | acc.push(item); 15 | } 16 | return acc; 17 | }, []); 18 | } 19 | -------------------------------------------------------------------------------- /functional-javascript-node-school/call.js: -------------------------------------------------------------------------------- 1 | // FUNCTIONAL JAVASCRIPT IS GOOD 2 | // ─────────────────────────────── 3 | // Basic: Call 4 | // Exercise 8 of 18 5 | 6 | // JavaScript implements 'duck' typing. Duck typing is a style of dynamic typing in which an object's methods and properties determine the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface. The name of the concept refers to the duck test, attributed to James Whitcomb Riley, which may be phrased as follows: 7 | 8 | // "When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck" 9 | 10 | // In JavaScript, in order to write robust programs we sometimes need to check an object conforms to the type that we need. 11 | 12 | // We can use Object#hasOwnProperty to detect if an object 'has' a property defined on itself (i.e. not inherited from its prototype): 13 | 14 | // var duck = { 15 | // quack: function() { 16 | // console.log('quack') 17 | // } 18 | // } 19 | 20 | // duck.hasOwnProperty('quack') // => true 21 | 22 | // We didn't give the duck a .hasOwnProperty method, where did it come from? 23 | 24 | // Duck was created with the {} syntax, and as such it inherits from Object.prototype: 25 | 26 | // var object = {quack: true} 27 | 28 | // Object.getPrototypeOf(object) === Object.prototype // => true 29 | // object.hasOwnProperty('quack') // => true 30 | 31 | // But what if an object doesn't inherit from Object.prototype? 32 | 33 | // // create an object with 'null' prototype. 34 | // var object = Object.create(null) 35 | // object.quack = function() { 36 | // console.log('quack') 37 | // } 38 | 39 | // Object.getPrototypeOf(object) === Object.prototype // => false 40 | // Object.getPrototypeOf(object) === null // => true 41 | 42 | // object.hasOwnProperty('quack') 43 | // // => TypeError: Object object has no method 'hasOwnProperty' 44 | 45 | // We can still use hasOwnProperty from the Object.prototype though, if we call it with the this value set to something that 'looks like an object'. Function#call allows us to invoke any function with an altered this value. 46 | 47 | // // the first argument to call becomes the value of `this` 48 | // // the rest of the arguments are passed to the function as per 49 | 50 | // Object.prototype.hasOwnProperty.call(object, 'quack') // => true 51 | 52 | // # Task: 53 | 54 | // Write a function duckCount that returns the number of arguments passed to it which have a property 'quack' defined directly on them. Do not match values inherited from prototypes. 55 | 56 | // Example: 57 | 58 | // var notDuck = Object.create({quack: true}) 59 | // var duck = {quack: true} 60 | // duckCount(duck, notDuck) // 1 61 | 62 | // ## Arguments 63 | 64 | // * You will be passed 0-20 arguments. Each argument could be of any type with any properties. Some of these items will have a 'quack' property. 65 | 66 | // ## Conditions 67 | 68 | // * Do not use any for/while loops or Array#forEach. 69 | // * Do not create any counter/accumulator variables. 70 | // * Do not create any unnecessary functions e.g. helpers. 71 | 72 | // ## Hint 73 | 74 | // * The `arguments` variable, available in every function, is an *Object* that quacks like an *Array*: 75 | 76 | // { 77 | // 0: 'argument0', 78 | // 1: 'argument1', // etc 79 | // length: 2 80 | // } 81 | 82 | // ## Resources 83 | 84 | // * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call 85 | // * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty 86 | // * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in 87 | // * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice#Array-like 88 | // * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments 89 | 90 | // ## Boilerplate 91 | 92 | function duckCount(ducks) { 93 | console.log(ducks); 94 | if ("quack" in ducks && ducks.hasOwnProperty("quack")) { 95 | return true; 96 | } 97 | // console.log("DUCKS", duck); 98 | // return duck.hasOwnProperty("quack"); 99 | } 100 | 101 | module.exports = duckCount; 102 | -------------------------------------------------------------------------------- /functional-javascript-node-school/everySome.js: -------------------------------------------------------------------------------- 1 | // Basic: Every Some 2 | // Exercise 5 of 18 3 | 4 | // # Task 5 | 6 | // Return a function that takes a list of valid users, and returns a function that returns true if all of the supplied users exist in the original list of users. 7 | 8 | // You only need to check that the ids match. 9 | 10 | // ## Example 11 | 12 | // var goodUsers = [ 13 | // { id: 1 }, 14 | // { id: 2 }, 15 | // { id: 3 } 16 | // ] 17 | 18 | // // `checkUsersValid` is the function you'll define 19 | // var testAllValid = checkUsersValid(goodUsers) 20 | 21 | // testAllValid([ 22 | // { id: 2 }, 23 | // { id: 1 } 24 | // ]) 25 | // // => true 26 | 27 | // testAllValid([ 28 | // { id: 2 }, 29 | // { id: 4 }, 30 | // { id: 1 } 31 | // ]) 32 | // // => false 33 | 34 | // ## Arguments 35 | 36 | // * goodUsers: a list of valid users 37 | 38 | // Use array#some and Array#every to check every user passed to your returned function exists in the array passed to the exported function. 39 | 40 | // ## Conditions 41 | 42 | // * Do not use any for/while loops or Array#forEach. 43 | // * Do not create any unnecessary functions e.g. helpers. 44 | 45 | // ## Resources 46 | 47 | // * https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/every 48 | // * https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/some 49 | 50 | // ## Boilerplate 51 | 52 | function checkUsersValid(goodUsers) { 53 | return function allUsersValid(submittedUsers) { 54 | return submittedUsers.every(user => { 55 | return goodUsers.some(element => element.id == user.id); 56 | }); 57 | }; 58 | } 59 | 60 | module.exports = checkUsersValid; 61 | -------------------------------------------------------------------------------- /functional-javascript-node-school/filter.js: -------------------------------------------------------------------------------- 1 | // FUNCTIONAL JAVASCRIPT IS GOOD 2 | // ─────────────────────────────── 3 | // Basic: Filter 4 | // Exercise 4 of 18 5 | 6 | // # Task 7 | 8 | // Use Array#filter to write a function called getShortMessages. 9 | 10 | // getShortMessages takes an array of objects with '.message' properties and returns an array of messages that are less than < 50 characters long. 11 | 12 | // The function should return an array containing the messages themselves, without their containing object. 13 | 14 | // ## Arguments 15 | 16 | // * messages: an Array of 10 to 100 random objects that look something like this: 17 | 18 | // { 19 | // message: 'Esse id amet quis eu esse aute officia ipsum.' // random 20 | // } 21 | 22 | // ## Conditions 23 | 24 | // * Do not use any for/while loops or Array#forEach. 25 | // * Do not create any unnecessary functions e.g. helpers. 26 | 27 | // ## Hint 28 | 29 | // * Try chaining some Array methods! 30 | 31 | // ## Example 32 | 33 | // [ 'Tempor quis esse consequat sunt ea eiusmod.', 34 | // 'Id culpa ad proident ad nulla laborum incididunt.', 35 | // 'Ullamco in ea et ad anim anim ullamco est.', 36 | // 'Est ut irure irure nisi.' ] 37 | 38 | // ## Resources 39 | 40 | // * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter 41 | // * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map 42 | 43 | // ## Boilerplate 44 | 45 | function getShortMessages(messages) { 46 | return messages 47 | .filter(({ message }) => message.length < 50) 48 | .map(({ message }) => message); 49 | } 50 | 51 | module.exports = getShortMessages; 52 | -------------------------------------------------------------------------------- /functional-javascript-node-school/higherOrderFunction.js: -------------------------------------------------------------------------------- 1 | // A higher-order function is a function that does at least one of the following: 2 | 3 | // * Take one or more functions as an input 4 | // * Output a function 5 | 6 | // All other functions are first order functions. [1] 7 | 8 | // Unlike many other languages with imperative features, JavaScript allows you to utilize higher-order functions because it has "first-class functions". This means functions can be treated just like any other value in JavaScript: just like Strings or Numbers, Function values can be stored as variables, properties on objects or passed to other functions as arguments. Function values are actually Objects (inheriting from Function.prototype) so you can even add properties and store values on them, just like any regular Object. 9 | 10 | // The key difference between Functions and other value types in JavaScript is the call syntax: if a reference to a function is followed by parenthesis and some optional comma-separated values: someFunctionValue(arg1, arg2, etc), then the function body will be executed with the supplied arguments (if any). 11 | 12 | // In this exercise we're going to demonstrate that functions can be passed as values by passing you a function as an argument. 13 | 14 | // # Task 15 | 16 | // Implement a function that takes a function as its first argument, a number num as its second argument, then executes the passed in function num times. 17 | 18 | // Use the boilerplate code given to you below to get started. Most/all future exercises will provide boilerplate. 19 | 20 | // ## Arguments 21 | 22 | // * operation: A Function, takes no arguments, returns no useful value. 23 | // * num: the number of times to call `operation` 24 | 25 | // ## Resources 26 | 27 | // * https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions_and_function_scope 28 | // * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/prototype 29 | 30 | // ## Hints 31 | 32 | // * Don't overthink it, the code should be rather simple. 33 | // * It's ok to use a loop in your implementation, bonus points if you use recursion instead. 34 | // * You may notice some output. That is coming from the function we passed you. 35 | // * You do not need to console.log anything. 36 | 37 | // ## Boilerplate 38 | 39 | function repeat(operation, num) { 40 | let count = 0; 41 | 42 | while (num < count) { 43 | operation(); 44 | count++; 45 | } 46 | } 47 | 48 | // Do not remove the line below 49 | module.exports = repeat; 50 | -------------------------------------------------------------------------------- /functional-javascript-node-school/map.js: -------------------------------------------------------------------------------- 1 | // # Task 2 | 3 | // Convert the following code from a for-loop to Array#map: 4 | 5 | // function doubleAll(numbers) { 6 | // var result = [] 7 | // for (var i = 0; i < numbers.length; i++) { 8 | // result.push(numbers[i] * 2) 9 | // } 10 | // return result 11 | // } 12 | 13 | // module.exports = doubleAll 14 | 15 | // ## Arguments 16 | 17 | // * numbers: An Array of 0 to 20 Integers between 0 and 9 18 | 19 | // ## Conditions 20 | 21 | // * Your solution should use Array.prototype.map() 22 | // * Do not use any for/while loops or Array.prototype.forEach. 23 | // * Do not create any unnecessary functions e.g. helpers. 24 | 25 | // ## Resources 26 | 27 | // * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map 28 | 29 | // ## Boilerplate 30 | 31 | function doubleAll(numbers) { 32 | return numbers.map(number => number * 2); 33 | } 34 | 35 | module.exports = doubleAll; 36 | -------------------------------------------------------------------------------- /functional-javascript-node-school/reduce.js: -------------------------------------------------------------------------------- 1 | // FUNCTIONAL JAVASCRIPT IS GOOD 2 | // ─────────────────────────────── 3 | // Basic: Reduce 4 | // Exercise 6 of 18 5 | 6 | // # Task 7 | 8 | // Given an Array of strings, use Array#reduce to create an object that contains the number of times each string occured in the array. Return the object directly (no need to console.log). 9 | 10 | // ## Example 11 | 12 | // var inputWords = ['Apple', 'Banana', 'Apple', 'Durian', 'Durian', 'Durian'] 13 | 14 | // console.log(countWords(inputWords)) 15 | 16 | // // => 17 | // // { 18 | // // Apple: 2, 19 | // // Banana: 1, 20 | // // Durian: 3 21 | // // } 22 | 23 | // ## Arguments 24 | 25 | // * inputWords: An array of random Strings. 26 | 27 | // ## Conditions 28 | 29 | // * Do not use any for/while loops or Array#forEach. 30 | // * Do not create any unnecessary functions e.g. helpers. 31 | 32 | // ## Resources 33 | 34 | // * https://en.wikipedia.org/wiki/Reduce_(higher-order_function) 35 | // * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce 36 | 37 | // ## Boilerplate 38 | 39 | function countWords(inputWords) { 40 | return inputWords.reduce((acc, word) => { 41 | acc[word] = (acc[word] || 0) + 1; 42 | return acc; 43 | }, {}); 44 | } 45 | 46 | module.exports = countWords; 47 | -------------------------------------------------------------------------------- /functional-javascript-node-school/upperCaser.js: -------------------------------------------------------------------------------- 1 | // # Task 2 | 3 | // Write a function that takes an input string and returns it uppercased. 4 | 5 | // ## Arguments 6 | 7 | // * input: a String of random words (lorem ipsum). 8 | 9 | function upperCaser(input) { 10 | return input.toUpperCase(); 11 | } 12 | 13 | module.exports = upperCaser; 14 | -------------------------------------------------------------------------------- /functionalProgrammingPractice.js: -------------------------------------------------------------------------------- 1 | // https://scotch.io/bar-talk/code-challenge-11-javascript-functional-programming 2 | // ARRAY 1 3 | const texasss = [ 4 | { 5 | name: "Mike", 6 | age: 23, 7 | gender: "m", 8 | us: false 9 | }, 10 | { 11 | name: "Liz", 12 | age: 20, 13 | gender: "f", 14 | us: true 15 | }, 16 | { 17 | name: "Chris", 18 | age: 102, 19 | gender: "m", 20 | us: true 21 | }, 22 | { 23 | name: "Chuloo", 24 | age: 27, 25 | gender: "m", 26 | us: false 27 | }, 28 | { 29 | name: "Annie", 30 | age: 30, 31 | gender: "f", 32 | us: true 33 | } 34 | ]; 35 | 36 | // Part 1 - Find all users older than 24 37 | console.log(texasss.filter(user => user.age > 24)); 38 | // Part 2 - Find the total age of all users 39 | console.log(texasss.reduce((acc, user) => acc + parseInt(user.age), 0)); 40 | // Part 3 - List all female coders 41 | console.log(texasss.filter(coder => coder.gender == "f")); 42 | // ARRAY 2 43 | const newieyork = [ 44 | { 45 | name: "Michelle", 46 | age: 19, 47 | coder: true, 48 | gender: "f", 49 | us: true 50 | }, 51 | { 52 | name: "Sam", 53 | age: 25, 54 | coder: false, 55 | gender: "m", 56 | us: false 57 | }, 58 | { 59 | name: "Ivy", 60 | age: 26, 61 | coder: true, 62 | gender: "f", 63 | us: false 64 | }, 65 | { 66 | name: "Nick", 67 | age: 32, 68 | coder: true, 69 | gender: "m", 70 | us: true 71 | }, 72 | { 73 | name: "Jim Beglin", 74 | age: 65, 75 | coder: false, 76 | gender: "m", 77 | us: true 78 | } 79 | ]; 80 | 81 | // Part 1 - List all users in US in ascending order 82 | console.log(newieyork.filter(user => user.us).sort()); 83 | // Part 2 - Sort all users by age 84 | console.log(newieyork.sort((a, b) => a.age - b.age)); 85 | // Part 3 - List all female coders 86 | console.log(newieyork.filter(user => user.gender == "f")); 87 | // ARRAY 3 88 | const vegzas = [ 89 | { 90 | name: "Charly", 91 | age: 32, 92 | coder: true, 93 | gender: "m" 94 | }, 95 | { 96 | name: "Law", 97 | age: 21, 98 | coder: true, 99 | gender: "m" 100 | }, 101 | { 102 | name: "Rosey", 103 | age: 42, 104 | coder: false, 105 | gender: "f" 106 | }, 107 | { 108 | name: "Steph", 109 | age: 18, 110 | coder: true, 111 | gender: "f" 112 | }, 113 | { 114 | name: "Jon", 115 | age: 47, 116 | coder: false, 117 | gender: "m" 118 | } 119 | ]; 120 | 121 | // Part 1 - Find the total age of male coders under 25 122 | console.log( 123 | vegzas 124 | .filter(coder => coder.age < 25 && coder.gender == "m") 125 | .reduce((acc, coder) => acc + coder.age, 0) 126 | ); 127 | // Part 2 - List all male coders over 30 128 | console.log(vegzas.filter(coder => coder.age > 30 && coder.gender == "m")); 129 | // Part 3 - Find the total age of everyone in texasss, newieyork and vegzas combined. 130 | console.log( 131 | vegzas 132 | .concat(newieyork) 133 | .concat(texasss) 134 | .reduce((acc, user) => acc + user.age, 0) 135 | ); 136 | -------------------------------------------------------------------------------- /getByPath.js: -------------------------------------------------------------------------------- 1 | // Write a function that returns the value at a give path 2 | 3 | let testObj = { 4 | foo: 2, 5 | bar: "car", 6 | baz: { x: "xx", y: "yy", biz: { a: 56 } } 7 | }; 8 | 9 | console.log(getByPath(["baz", "biz", "a"], testObj)); //56 10 | 11 | function getByPath(path, object) { 12 | if (!path) { 13 | return undefined; 14 | } 15 | return path.reduce((acc, value) => { 16 | return acc[value] || undefined; 17 | }, object); 18 | } 19 | -------------------------------------------------------------------------------- /goatLatin.js: -------------------------------------------------------------------------------- 1 | // A sentence S is given, composed of words separated by spaces.Each word consists of lowercase and uppercase letters only. 2 | 3 | // We would like to convert the sentence to "Goat Latin"(a made - up language similar to Pig Latin.) 4 | 5 | // The rules of Goat Latin are as follows: 6 | 7 | // If a word begins with a vowel(a, e, i, o, or u), append "ma" to the end of the word. 8 | // For example, the word 'apple' becomes 'applema'. 9 | 10 | // If a word begins with a consonant(i.e.not a vowel), remove the first letter and append it to the end, then add "ma". 11 | // For example, the word "goat" becomes "oatgma". 12 | 13 | // Add one letter 'a' to the end of each word per its word index in the sentence, starting with 1. 14 | // For example, the first word gets "a" added to the end, the second word gets "aa" added to the end and so on. 15 | // Return the final sentence representing the conversion from S to Goat Latin. 16 | 17 | function goatLatin(sentence) { 18 | const vowels = ["a", "e", "i", "o", "u"]; 19 | const words = sentence.split(" "); 20 | let newWords = []; 21 | for (word in words) { 22 | const letters = words[word].split(""); 23 | if (vowels.includes(letters[0].toLowerCase())) { 24 | // do nothing 25 | } else { 26 | //swap first and lrngth + 1 (end of list/empty) 27 | [letters[0], letters[letters.length]] = [ 28 | letters[letters.length], 29 | letters[0] 30 | ]; 31 | } 32 | 33 | letters.push("m"); 34 | letters.push("a"); 35 | 36 | let count = 0; 37 | 38 | while (count <= word) { 39 | letters.push("a"); 40 | count++; 41 | } 42 | 43 | newWords.push(letters.join("")); 44 | } 45 | 46 | return newWords.join(" "); 47 | } 48 | 49 | const firstSentence = "I speak Goat Latin"; 50 | console.log(goatLatin(firstSentence)); //"Imaa peaksmaaa oatGmaaaa atinLmaaaaa"; 51 | 52 | const secondSentence = "The quick brown fox jumped over the lazy dog"; 53 | console.log(goatLatin(secondSentence)); 54 | ("heTmaa uickqmaaa rownbmaaaa oxfmaaaaa umpedjmaaaaaa overmaaaaaaa hetmaaaaaaaa azylmaaaaaaaaa ogdmaaaaaaaaaa"); 55 | -------------------------------------------------------------------------------- /groupAnagrams.js: -------------------------------------------------------------------------------- 1 | // Given an array of strings, group anagrams together. 2 | 3 | // Example: 4 | 5 | // Input: ["eat", "tea", "tan", "ate", "nat", "bat"], 6 | // Output: 7 | // [ 8 | // ["ate","eat","tea"], 9 | // ["nat","tan"], 10 | // ["bat"] 11 | // ] 12 | // Note: 13 | 14 | // All inputs will be in lowercase. 15 | // The order of your output does not matter. 16 | 17 | /** 18 | * @param {string[]} strs 19 | * @return {string[][]} 20 | */ 21 | var groupAnagrams = function (strs) { 22 | // for each item in array store it in an object - the key is the alphabetized version - value is an array 23 | // then iterate through object to only return keys 24 | 25 | let mappings = {}; 26 | 27 | for (let string of strs) { 28 | let sortedString = string.split("").sort().join(""); 29 | 30 | if (mappings[sortedString]) { 31 | mappings[sortedString].push(string); 32 | } else { 33 | mappings[sortedString] = [string]; 34 | } 35 | } 36 | 37 | let anagrams = []; 38 | for (let [key, value] of Object.entries(mappings)) { 39 | anagrams.push(value); 40 | } 41 | 42 | return anagrams; 43 | }; 44 | 45 | // Time Complexity: O(NK \log K)O(NKlogK), where NN is the length of strs, and KK is the maximum length of a string in strs. The outer loop has complexity O(N)O(N) as we iterate through each string. Then, we sort each string in O(K \log K)O(KlogK) time. 46 | 47 | // Space Complexity: O(NK)O(NK), the total information content stored in ans. 48 | -------------------------------------------------------------------------------- /happynumber.js: -------------------------------------------------------------------------------- 1 | // Write an algorithm to determine if a number is "happy". 2 | 3 | // A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1(where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers. 4 | 5 | /** 6 | * @param {number} n 7 | * @return {boolean} 8 | */ 9 | 10 | function isHappy(n) { 11 | return getSquares(n) == 1; 12 | } 13 | 14 | function getSquares(n, seen = {}) { 15 | const nums = n.toString().split(""); 16 | const squaredSum = nums.reduce((acc, value) => { 17 | return acc + Math.pow(value, 2); 18 | }, 0); 19 | if (seen[squaredSum] == "true") { 20 | return 0; 21 | } else if (squaredSum == 1) { 22 | return squaredSum; 23 | } else { 24 | seen[squaredSum] = "true"; 25 | return getSquares(squaredSum, seen); 26 | } 27 | } 28 | 29 | // var isHappy = function(n) { 30 | // return getSquares(n) == 1; 31 | // }; 32 | 33 | // var getSquares = function(number, seen = {}) { 34 | // if (number in seen) { 35 | // return false; 36 | // } else if (number == 1) { 37 | // return true; 38 | // } else { 39 | // let digits = number.toString().split(""); 40 | // let sum = 0; 41 | 42 | // for (digit of digits) { 43 | // sum += Math.pow(digit, 2); 44 | // } 45 | 46 | // seen[number] = "true"; 47 | 48 | // return getSquares(sum, seen); 49 | // } 50 | // }; 51 | 52 | console.log(isHappy(19)); // true 53 | -------------------------------------------------------------------------------- /highestProduct.js: -------------------------------------------------------------------------------- 1 | function highestProductOf3(arrayOfInts) { 2 | if (arrayOfInts.length < 3) { 3 | throw new Error( 4 | "oops something went wrong. Please try again with a different input." 5 | ); 6 | } 7 | 8 | const highestAbsoluteValues = arrayOfInts 9 | .sort((a, b) => Math.abs(a) - Math.abs(b)) 10 | .slice(-3); 11 | 12 | let highestProduct = highestAbsoluteValues.reduce((accumulator, item) => { 13 | return accumulator * item; 14 | }, 1); 15 | 16 | if (highestProduct < 0) { 17 | highestProduct = arrayOfInts 18 | .sort((a, b) => a - b) 19 | .slice(-3) 20 | .reduce((accumulator, item) => { 21 | return accumulator * item; 22 | }, 1); 23 | } 24 | 25 | return highestProduct; 26 | } 27 | 28 | console.log(highestProductOf3([1, 2, 3, 4])); // 24 29 | console.log(highestProductOf3([-10, 1, 3, 2, -10])); // 300 30 | -------------------------------------------------------------------------------- /isOdd.js: -------------------------------------------------------------------------------- 1 | function findOdd(array) { 2 | let isOdd = new Map(); 3 | for (let item of array) { 4 | if (isOdd.get(item)) { 5 | isOdd.set(item, 0); 6 | } else { 7 | isOdd.set(item, 1); 8 | } 9 | } 10 | 11 | let oddItem; 12 | const item = isOdd.forEach((value, key) => { 13 | if (value == 1) { 14 | oddItem = key; 15 | } 16 | }); 17 | 18 | return oddItem; 19 | } 20 | 21 | console.log(findOdd([1, 2, 2, 1, 3])); 22 | -------------------------------------------------------------------------------- /isPalindrome.js: -------------------------------------------------------------------------------- 1 | function isPalindrome(word) { 2 | let endPointer = word.length - 1; 3 | for (let i = 0; i < word.length / 2; i++) { 4 | if (word[i] !== word[endPointer]) { 5 | return false; 6 | } 7 | endPointer--; 8 | } 9 | return true; 10 | } 11 | 12 | console.log(isPalindrome("awesome")); // false 13 | console.log(isPalindrome("foobar")); // false 14 | console.log(isPalindrome("tacocat")); // true 15 | console.log(isPalindrome("amanaplanacanalpanama")); // true 16 | console.log(isPalindrome("amanaplanacanalpandemonium")); // false 17 | -------------------------------------------------------------------------------- /isSubsequence.js: -------------------------------------------------------------------------------- 1 | function isSubsequence(substring, word) { 2 | let pointer = 0; 3 | 4 | for (let letter of word) { 5 | if (letter == substring[pointer]) { 6 | pointer++; 7 | } 8 | // else do nothing 9 | } 10 | 11 | return pointer == substring.length; 12 | } 13 | 14 | console.log(isSubsequence("hello", "hello world")); // true 15 | console.log(isSubsequence("sing", "sting")); // true 16 | console.log(isSubsequence("abc", "abracadabra")); // true 17 | console.log(isSubsequence("abc", "acb")); // true 18 | -------------------------------------------------------------------------------- /jewelsAndStones.js: -------------------------------------------------------------------------------- 1 | // Jewels and Stones 2 | 3 | // You're given strings J representing the types of stones that are jewels, and S representing the stones you have. Each character in S is a type of stone you have. You want to know how many of the stones you have are also jewels. 4 | 5 | // The letters in J are guaranteed distinct, and all characters in J and S are letters.Letters are case sensitive, so "a" is considered a different type of stone from "A". 6 | 7 | // Example 1: 8 | 9 | // Input: J = "aA", S = "aAAbbbb" 10 | // Output: 3 11 | // Example 2: 12 | 13 | // Input: J = "z", S = "ZZ" 14 | // Output: 0 15 | // Note: 16 | 17 | // S and J will consist of letters and have length at most 50. 18 | // The characters in J are distinct. 19 | 20 | //https://leetcode.com/explore/challenge/card/may-leetcoding-challenge/534/week-1-may-1st-may-7th/3317/ 21 | 22 | /** 23 | * @param {string} J 24 | * @param {string} S 25 | * @return {number} 26 | */ 27 | var numJewelsInStones = function (J, S) { 28 | const jewels = {}; 29 | for (let jewel of J) { 30 | jewels[jewel] = true; 31 | } 32 | 33 | let jewelCount = 0; 34 | for (let stone of S) { 35 | if (jewels[stone]) { 36 | jewelCount++; 37 | } 38 | } 39 | 40 | return jewelCount; 41 | }; 42 | 43 | console.log(numJewelsInStones("aA", "aAAbbbb")); // 3 44 | console.log(numJewelsInStones("z", "ZZ")); // 0 45 | -------------------------------------------------------------------------------- /largestPerimeterTriangles.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} A 3 | * @return {number} 4 | * Source: LeetCode https://leetcode.com/problems/largest-perimeter-triangle/ 5 | */ 6 | 7 | // . For a triangle with sides a, b and c, the perimeter P is defined as: P = a + b + c. 8 | var largestPerimeter = function(A) { 9 | if (A.length < 3) { 10 | return 0; 11 | } 12 | 13 | A.sort((a, b) => b - a); 14 | 15 | for (let i = 0; i < A.length - 2; i++) { 16 | if (A[i] < A[i + 1] + A[i + 2]) { 17 | // return the highest three numbers 18 | // that satisfy the a + b > c rule 19 | return A[i] + A[i + 1] + A[i + 2]; 20 | } 21 | } 22 | return 0; 23 | }; 24 | 25 | console.log(largestPerimeter([3, 6, 2, 3])); 26 | -------------------------------------------------------------------------------- /largestUniqueNumber.js: -------------------------------------------------------------------------------- 1 | // 1133. Largest Unique Number 2 | // Easy 3 | 4 | // 68 5 | 6 | // 6 7 | 8 | // Add to List 9 | 10 | // Share 11 | // Given an array of integers A, return the largest integer that only occurs once. 12 | 13 | // If no integer occurs once, return -1. 14 | 15 | var largestUniqueNumber = function (A) { 16 | const frequencyMap = {}; 17 | 18 | for (num of A) { 19 | frequencyMap[num] ? frequencyMap[num]++ : (frequencyMap[num] = 1); 20 | } 21 | 22 | let max = -1; 23 | 24 | for (let [key, value] of Object.entries(frequencyMap)) { 25 | if (value == 1 && Number.parseInt(key, 10) > Number.parseInt(max, 10)) { 26 | max = key; 27 | } 28 | } 29 | 30 | return max; 31 | }; 32 | 33 | console.log(largestUniqueNumber([5, 7, 3, 9, 4, 9, 8, 3, 1])); // 8 34 | console.log( 35 | largestUniqueNumber([ 36 | 397, 37 | 513, 38 | 784, 39 | 485, 40 | 253, 41 | 360, 42 | 924, 43 | 37, 44 | 97, 45 | 624, 46 | 743, 47 | 203, 48 | 406, 49 | 77, 50 | 23, 51 | 123, 52 | 748, 53 | 309, 54 | 230, 55 | 669, 56 | ]) 57 | ); //924 58 | -------------------------------------------------------------------------------- /lastStoneWeight.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} stones 3 | * @return {number} 4 | */ 5 | var lastStoneWeight = function (stones) { 6 | while (stones.length >= 2) { 7 | stones.sort((a, b) => b - a); 8 | if (stones[0] == stones[1]) { 9 | stones.shift(); 10 | stones.shift(); 11 | } else { 12 | stones[1] = stones[0] - stones[1]; 13 | stones.shift(); 14 | } 15 | } 16 | 17 | return stones.length ? stones[0] : 0; 18 | }; 19 | 20 | console.log(lastStoneWeight([2, 7, 4, 1, 8, 1])); // 1 21 | 22 | // https://leetcode.com/explore/featured/card/30-day-leetcoding-challenge/529/week-2/3297/ 23 | 24 | // We have a collection of stones, each stone has a positive integer weight. 25 | 26 | // Each turn, we choose the two heaviest stones and smash them together.Suppose the stones have weights x and y with x <= y.The result of this smash is: 27 | 28 | // If x == y, both stones are totally destroyed; 29 | // If x != y, the stone of weight x is totally destroyed, and the stone of weight y has new weight y - x. 30 | 31 | // At the end, there is at most 1 stone left.Return the weight of this stone(or 0 if there are no stones left.) 32 | 33 | // Example 1: 34 | 35 | // Input: [2, 7, 4, 1, 8, 1] 36 | // Output: 1 37 | // Explanation: 38 | // We combine 7 and 8 to get 1 so the array converts to[2, 4, 1, 1, 1] then, 39 | // we combine 2 and 4 to get 2 so the array converts to[2, 1, 1, 1] then, 40 | // we combine 2 and 1 to get 1 so the array converts to[1, 1, 1] then, 41 | // we combine 1 and 1 to get 0 so the array converts to[1] then that's the value of last stone. 42 | 43 | // Note: 44 | 45 | // 1 <= stones.length <= 30 46 | // 1 <= stones[i] <= 1000 47 | -------------------------------------------------------------------------------- /learnyounode/baby-steps.js: -------------------------------------------------------------------------------- 1 | const [node, path, ...args] = process.argv; 2 | const sum = args.reduce((acc, arg) => acc + parseInt(arg), 0); 3 | console.log(sum); 4 | -------------------------------------------------------------------------------- /learnyounode/filtered-ls.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | 3 | function processFile() { 4 | const [node, path, directory, extension] = process.argv; 5 | 6 | fs.readdir(directory, function doneReading(err, files) { 7 | if (err) { 8 | return console.log(err); 9 | } 10 | 11 | const filteredFiles = files 12 | .filter(file => file.endsWith("." + extension)) 13 | .forEach(item => console.log(item)); 14 | }); 15 | } 16 | 17 | processFile(); 18 | -------------------------------------------------------------------------------- /learnyounode/hello-world.js: -------------------------------------------------------------------------------- 1 | console.log("HELLO WORLD"); 2 | -------------------------------------------------------------------------------- /learnyounode/http-client.js: -------------------------------------------------------------------------------- 1 | // const fs = require("fs"); 2 | const http = require("http"); 3 | 4 | const [node, path, url] = process.argv; 5 | 6 | http 7 | .get(url, function(response) { 8 | response.setEncoding("utf8"); 9 | response.on("data", function(data) { 10 | console.log(data); 11 | }); 12 | response.on("error", console.error); 13 | }) 14 | .on("error", console.error); 15 | -------------------------------------------------------------------------------- /learnyounode/http-collect.js: -------------------------------------------------------------------------------- 1 | const http = require("http"); 2 | const [node, path, url] = process.argv; 3 | 4 | // docs for processing stream of data 5 | // https://nodejs.org/api/http.html#http_http_get_url_options_callback 6 | http 7 | .get(url, function(response) { 8 | response.setEncoding("utf8"); 9 | let data = ""; 10 | response.on("data", chunk => { 11 | data += chunk; 12 | }); 13 | response.on("error", console.error); 14 | response.on("end", () => { 15 | try { 16 | console.log(data.length); 17 | console.log(data); 18 | } catch (e) { 19 | console.error(e.message); 20 | } 21 | }); 22 | }) 23 | .on("error", console.error); 24 | -------------------------------------------------------------------------------- /learnyounode/make-it-modular.js: -------------------------------------------------------------------------------- 1 | const mymodule = require("./mymodule.js"); 2 | function processFile() { 3 | const [node, path, directory, extension] = process.argv; 4 | 5 | mymodule(directory, extension, function doneReading(err, files) { 6 | if (err) { 7 | return console.log(err); 8 | } 9 | 10 | const filteredFiles = files 11 | .filter(file => file.endsWith("." + extension)) 12 | .forEach(item => console.log(item)); 13 | }); 14 | } 15 | 16 | processFile(); 17 | -------------------------------------------------------------------------------- /learnyounode/my-first-async-io.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | 3 | function processFile() { 4 | const [node, path, file] = process.argv; 5 | 6 | fs.readFile(file, "utf-8", function doneReading(err, fileContent) { 7 | if (err) { 8 | return console.log(err); 9 | } 10 | const lines = fileContent.split("\n").length - 1; 11 | console.log(lines); 12 | }); 13 | } 14 | 15 | processFile(); 16 | -------------------------------------------------------------------------------- /learnyounode/my-first-io.js: -------------------------------------------------------------------------------- 1 | // const fs = require("fs"); 2 | 3 | // const [node, path, file] = process.argv; 4 | 5 | // const fileContent = fs.readFileSync(file).toString(); 6 | 7 | // console.log(fileContent.split("\n").length - 1); 8 | 9 | const fs = require("fs"); 10 | 11 | const [node, path, file] = process.argv; 12 | 13 | const fileContent = fs.readFileSync(file, "utf-8"); 14 | 15 | console.log(fileContent.split("\n").length - 1); 16 | -------------------------------------------------------------------------------- /learnyounode/mymodule.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | 3 | module.exports = function processFile(directory, extension, callback) { 4 | fs.readdir(directory, callback); 5 | }; 6 | -------------------------------------------------------------------------------- /lemonadeChange.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} bills 3 | * @return {boolean} 4 | */ 5 | 6 | // At a lemonade stand, each lemonade costs $5. 7 | 8 | // Customers are standing in a queue to buy from you, and order one at 9 | //a time(in the order specified by bills). 10 | 11 | // Each customer will only buy one lemonade and pay with either a $5, 12 | //$10, or $20 bill.You must provide the correct change to each customer, 13 | // so that the net transaction is that the customer pays $5. 14 | 15 | // Note that you don't have any change in hand at first. 16 | 17 | // Return true if and only if you can provide every customer with correct change. 18 | 19 | function lemonadeChange(bills) { 20 | // bill = 5, good to go 21 | // bill = 10, if 5 then good to go (deduct 5) 22 | // bill 20 ? if 10 deduct + 1 five, else deduct 5. 23 | 24 | //if any bills are negative return false 25 | 26 | let fives = 0; 27 | let tens = 0; 28 | let twenties = 0; 29 | 30 | for (bill of bills) { 31 | if (bill == 5) { 32 | fives++; 33 | } else if (bill == 10) { 34 | tens++; 35 | if (fives) { 36 | fives--; 37 | } else { 38 | return false; 39 | } 40 | } else if (bill == 20) { 41 | twenties++; 42 | if (tens && fives) { 43 | tens--; 44 | fives--; 45 | } else if (fives >= 3) { 46 | fives = fives - 3; 47 | } else { 48 | return false; 49 | } 50 | } 51 | } 52 | 53 | return true; 54 | } 55 | 56 | console.log(lemonadeChange([5, 5, 5, 10, 20])); // true 57 | console.log(lemonadeChange([10, 10])); // false 58 | console.log(lemonadeChange([5, 5, 10, 10, 20])); 59 | -------------------------------------------------------------------------------- /letter-count.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `letterCount` that accepts a string, and finds the number of times each letter 3 | occurs in the string. For example, given the word "apple", letterCount("apple") should count all 4 | occurrences of the letters "a", "p", "l" and "e" and then return the following output: 5 | ```javascript 6 | { 7 | "a": 1, 8 | "p": 2, 9 | "l": 1, 10 | "e": 1 11 | } 12 | ``` 13 | Bonuses 14 | - Make sure that lower case letters and upper case letters count for the same character. 15 | - Ignore spaces, special characters, and punctuation. 16 | - Instead of just counting letters, calculate their percent-based frequency. 17 | See: http://www.math.cornell.edu/~mec/2003-2004/cryptography/subs/frequencies.html 18 | ```javascript 19 | { 20 | "a": 0.2, // percent 21 | "p": 0.4, 22 | "l": 0.2, 23 | "e": 0.2 24 | } 25 | ``` 26 | */ 27 | 28 | // YOUR CODE HERE 29 | 30 | function letterCount(word) { 31 | let wordCount = {}; 32 | 33 | word = word.replace(/[^\w]/g, ""); 34 | 35 | for (letter of word) { 36 | letter = letter.toLowerCase(); 37 | wordCount[letter] = wordCount[letter] + 1 || 1; 38 | } 39 | return wordCount; 40 | } 41 | 42 | function letterFrequency(word) { 43 | let count = letterCount(word); 44 | Object.keys(count).forEach(letter => { 45 | count[letter] = count[letter] / word.length; 46 | }); 47 | return count; 48 | } 49 | 50 | // console.log(letterCount("Apple")); 51 | // console.log(letterCount("Appfffle")); 52 | // console.log(letterCount("apple")); 53 | // console.log(letterCount("Monic@!")); 54 | // console.log(letterFrequency("Apple")); 55 | -------------------------------------------------------------------------------- /letterOccurence.js: -------------------------------------------------------------------------------- 1 | // This week’s question: 2 | // Given a string s and a character c, return the number of occurrences of c in s. 3 | 4 | // Example: 5 | // $ numChars(‘oh heavens’, ‘h’) 6 | // $ 2 7 | // Source: Cassidoo https://buttondown.email/cassidoo/archive/if-you-want-to-look-good-in-front-of-thousands/ 8 | 9 | function numCharsReduce(word, letter) { 10 | return word.split("").reduce((acc, current) => { 11 | if (current == letter) acc++; 12 | return acc; 13 | }, 0); 14 | } 15 | 16 | function numChars(word, letter) { 17 | let count = 0; 18 | for (let character of word) { 19 | if (character === letter) { 20 | count++; 21 | } 22 | } 23 | 24 | return count; 25 | } 26 | 27 | console.log(numCharsReduce("oh heavens", "h")); 28 | console.log(numChars("oh heavens", "h")); 29 | -------------------------------------------------------------------------------- /linearSearch.js: -------------------------------------------------------------------------------- 1 | function linearSearch(items, targetValue) { 2 | // add whatever parameters you deem necessary - good luck! 3 | 4 | for (let item in items) { 5 | if (items[item] === targetValue) { 6 | return item; 7 | //for some reason udemy required parseInt(item) 🤔 8 | } 9 | } 10 | return -1; 11 | } 12 | 13 | console.log(linearSearch([100], 100)); //0 14 | console.log(linearSearch([1, 2, 3, 4, 5], 6)); // -1 15 | console.log(linearSearch([10, 15, 20, 25, 30], 15)); // 1 16 | console.log(linearSearch([9, 8, 7, 6, 5, 4, 3, 2, 1, 0], 4)); // 5 17 | -------------------------------------------------------------------------------- /linked-lists/README.md: -------------------------------------------------------------------------------- 1 | # Linked Lists 2 | Class Implementation of Linked List functionality 3 | 4 | ``` 5 | class Node { 6 | constructor(val) { 7 | this.val = val; 8 | this.next = null; 9 | } 10 | } 11 | 12 | class SinglyLinkedList { 13 | constructor() { 14 | this.head = null; 15 | this.tail = null; 16 | this.length = 0; 17 | } 18 | push(val){ 19 | /* code here */ 20 | } 21 | pop(){ 22 | /* code here */ 23 | } 24 | } 25 | ``` 26 | 27 | ``` 28 | var list = new SinglyLinkedList(); 29 | ``` 30 | 31 | - push(val) - create a new Node and add it to the end of a LinkedList. The head/tail and length++ values should be updated accordingly. 32 | - pop() - remove the Tail from LinkedList and update the head/tail and length-- values accordingly. 33 | - unshift() - add a new Node to the beginning of LinkedList, update the head/tail and length++ accordingly. 34 | - shift() - remove the head from Linked List and update length-- . 35 | - get(index) - return the value at a specific index in LinkedList. Requires traversing list to find the node. 36 | - set(index, val) - change the value at a specified index with the appropraite value. 37 | - insert(index, val) - insert new node at the specified index with the appropriate value, should shift the current value at the next index over one. 38 | - remove (index) - remove node at a specified index 39 | - print() - print every item in LinkedList 40 | - reverse() - reverse the items in a LinkedList 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /linked-lists/singlyLinkedListGet.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | } 6 | } 7 | 8 | class SinglyLinkedList { 9 | constructor() { 10 | this.head = null; 11 | this.tail = null; 12 | this.length = 0; 13 | } 14 | push(val) { 15 | var newNode = new Node(val); 16 | if (!this.head) { 17 | this.head = newNode; 18 | this.tail = this.head; 19 | } else { 20 | this.tail.next = newNode; 21 | this.tail = newNode; 22 | } 23 | this.length++; 24 | return this; 25 | } 26 | pop() { 27 | if (!this.head) return undefined; 28 | var current = this.head; 29 | var newTail = current; 30 | while (current.next) { 31 | newTail = current; 32 | current = current.next; 33 | } 34 | this.tail = newTail; 35 | this.tail.next = null; 36 | this.length--; 37 | if (this.length === 0) { 38 | this.head = null; 39 | this.tail = null; 40 | } 41 | return current; 42 | } 43 | 44 | unshift(val) { 45 | // have current head 46 | // set val.next = current head 47 | // set head to val 48 | // increase length 49 | // return val? 50 | 51 | var newNode = new Node(val); 52 | 53 | if (!this.head) { 54 | this.head = newNode; 55 | this.tail = newNode; 56 | } else { 57 | newNode.next = this.head; 58 | this.head = newNode; 59 | } 60 | 61 | this.length++; 62 | 63 | return this; 64 | } 65 | 66 | shift() { 67 | // have current head 68 | // set head to current head.next 69 | //make head.next = null 70 | //return original head 71 | 72 | // this is constant times always 73 | // regardless of how big the list is 74 | 75 | if (!this.head) { 76 | return undefined; 77 | } 78 | 79 | let oldHead = this.head; 80 | 81 | this.head = this.head.next; 82 | oldHead.next = null; 83 | this.length--; 84 | 85 | if (this.length == 0) { 86 | this.tail = null; 87 | } 88 | 89 | return oldHead; 90 | } 91 | 92 | get(index) { 93 | if (!this.head || index < 0 || index >= this.length) { 94 | return undefined; 95 | } 96 | 97 | let current = this.head; 98 | let count = 0; 99 | 100 | while (count != index) { 101 | current = current.next; 102 | count++; 103 | } 104 | return current; 105 | } 106 | } 107 | 108 | var list = new SinglyLinkedList(); 109 | 110 | list.push("HELLO"); 111 | list.push("GOODBYE"); 112 | list.push("!"); 113 | list.push("<3"); 114 | list.push(":)"); 115 | list.push("$"); 116 | console.log(list.get(5)); 117 | -------------------------------------------------------------------------------- /linked-lists/singlyLinkedListInsert.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | } 6 | } 7 | 8 | class SinglyLinkedList { 9 | constructor() { 10 | this.head = null; 11 | this.tail = null; 12 | this.length = 0; 13 | } 14 | push(val) { 15 | var newNode = new Node(val); 16 | if (!this.head) { 17 | this.head = newNode; 18 | this.tail = this.head; 19 | } else { 20 | this.tail.next = newNode; 21 | this.tail = newNode; 22 | } 23 | this.length++; 24 | return this; 25 | } 26 | pop() { 27 | if (!this.head) return undefined; 28 | var current = this.head; 29 | var newTail = current; 30 | while (current.next) { 31 | newTail = current; 32 | current = current.next; 33 | } 34 | this.tail = newTail; 35 | this.tail.next = null; 36 | this.length--; 37 | if (this.length === 0) { 38 | this.head = null; 39 | this.tail = null; 40 | } 41 | return current; 42 | } 43 | 44 | unshift(val) { 45 | // have current head 46 | // set val.next = current head 47 | // set head to val 48 | // increase length 49 | // return val? 50 | 51 | var newNode = new Node(val); 52 | 53 | if (!this.head) { 54 | this.head = newNode; 55 | this.tail = newNode; 56 | } else { 57 | newNode.next = this.head; 58 | this.head = newNode; 59 | } 60 | 61 | this.length++; 62 | 63 | return this; 64 | } 65 | 66 | shift() { 67 | // have current head 68 | // set head to current head.next 69 | //make head.next = null 70 | //return original head 71 | 72 | // this is constant times always 73 | // regardless of how big the list is 74 | 75 | if (!this.head) { 76 | return undefined; 77 | } 78 | 79 | let oldHead = this.head; 80 | 81 | this.head = this.head.next; 82 | oldHead.next = null; 83 | this.length--; 84 | 85 | if (this.length == 0) { 86 | this.tail = null; 87 | } 88 | 89 | return oldHead; 90 | } 91 | 92 | get(index) { 93 | if (!this.head || index < 0 || index >= this.length) { 94 | return undefined; 95 | } 96 | 97 | let current = this.head; 98 | let count = 0; 99 | 100 | while (count != index) { 101 | current = current.next; 102 | count++; 103 | } 104 | return current; 105 | } 106 | 107 | set(index, val) { 108 | // change the value of a node based on 109 | // its position in the linked list 110 | 111 | // get index 112 | // the set index.val to val 113 | 114 | let current = this.get(index); 115 | 116 | if (current) { 117 | current.val = val; 118 | return true; 119 | } 120 | 121 | return false; 122 | } 123 | 124 | insert(index, val) { 125 | //inserts a new node at specific position 126 | if (index > this.length || index < 0) { 127 | // not valid index!! 128 | return false; 129 | } 130 | 131 | if (index == this.length) { 132 | this.push(val); 133 | return true; 134 | } else if (index == 0) { 135 | this.unshift(val); 136 | return true; 137 | } 138 | 139 | const newNode = new Node(val); 140 | let prev = this.get(index - 1); 141 | let temp = prev.next; 142 | prev.next = newNode; 143 | newNode.next = temp; 144 | this.length++; 145 | return true; 146 | } 147 | } 148 | 149 | var list = new SinglyLinkedList(); 150 | 151 | list.push("HELLO"); 152 | list.push("GOODBYE"); 153 | list.push("!"); 154 | list.push("<3"); 155 | list.push(":)"); 156 | list.push("$"); 157 | //console.log(list); 158 | 159 | console.log(list.insert(6, "potatomonster")); 160 | 161 | console.log(list.insert(0, "MONICA")); 162 | console.log(list); 163 | -------------------------------------------------------------------------------- /linked-lists/singlyLinkedListPop.js: -------------------------------------------------------------------------------- 1 | // piece of data - val 2 | // reference to next node - next 3 | 4 | class Node { 5 | constructor(val) { 6 | this.val = val; 7 | this.next = null; 8 | } 9 | } 10 | 11 | class SinglyLinkedList { 12 | constructor() { 13 | this.head = null; 14 | this.tail = null; 15 | this.length = 0; 16 | } 17 | 18 | push(val) { 19 | var newNode = new Node(val); 20 | if (!this.head) { 21 | this.head = newNode; 22 | this.tail = this.head; 23 | } else { 24 | this.tail.next = newNode; 25 | this.tail = newNode; 26 | } 27 | this.length++; 28 | } 29 | 30 | // traverse() { 31 | // let current = this.head; 32 | // while (current) { 33 | // console.log(current.val); 34 | // current = current.next; 35 | // } 36 | // } 37 | 38 | pop() { 39 | // 1, go to head 40 | // 2. keep going until next node == tail 41 | // 3. set next to null instead of tail 42 | // 4. update tail to current node 43 | // 5. decrement length of linked list 44 | // 6. return value of node removed 45 | 46 | if (!this.head) return undefined; 47 | 48 | let current = this.head; 49 | while (current.next && current.next != this.tail) { 50 | current = current.next; 51 | } 52 | 53 | let removedNode = this.tail; 54 | 55 | current.next = null; 56 | this.tail = current; 57 | this.length--; 58 | 59 | if (this.length == 0) { 60 | this.head = null; 61 | this.tail = null; 62 | } 63 | 64 | return removedNode; 65 | } 66 | } 67 | 68 | var list = new SinglyLinkedList(); 69 | list.push("Hello"); 70 | list.push("Goodbye"); 71 | list.push("house"); 72 | list.push("hi"); 73 | list.push("hello, fresh"); 74 | list.push("goodbye"); 75 | // list.traverse(); 76 | list.pop(); 77 | list.pop(); 78 | list.pop(); 79 | list.pop(); 80 | list.pop(); 81 | list.pop(); 82 | console.log(list); 83 | -------------------------------------------------------------------------------- /linked-lists/singlyLinkedListPush.js: -------------------------------------------------------------------------------- 1 | // piece of data - val 2 | // reference to next node - next 3 | 4 | class Node { 5 | constructor(val) { 6 | this.val = val; 7 | this.next = null; 8 | } 9 | } 10 | 11 | class SinglyLinkedList { 12 | constructor() { 13 | this.head = null; 14 | this.tail = null; 15 | this.length = 0; 16 | } 17 | 18 | push(val) { 19 | var newNode = new Node(val); 20 | if (!this.head) { 21 | this.head = newNode; 22 | this.tail = this.head; 23 | } else { 24 | this.tail.next = newNode; 25 | this.tail = newNode; 26 | } 27 | this.length++; 28 | } 29 | } 30 | 31 | // var first = new Node("Hi"); 32 | // manual way of adding new nodes without .push() method 33 | // first.next = new Node("there"); 34 | // first.next.next = new Node("how"); 35 | // first.next.next.next = new Node("are"); 36 | // first.next.next.next = new Node("you"); 37 | 38 | var list = new SinglyLinkedList(); 39 | list.push("Hello"); 40 | list.push("Goodbye"); 41 | list.push("house"); 42 | list.push("hi"); 43 | console.log(list); 44 | 45 | // console.log(first); 46 | // console.log(first.next.next.next); 47 | -------------------------------------------------------------------------------- /linked-lists/singlyLinkedListRemove.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | } 6 | } 7 | 8 | class SinglyLinkedList { 9 | constructor() { 10 | this.head = null; 11 | this.tail = null; 12 | this.length = 0; 13 | } 14 | push(val) { 15 | var newNode = new Node(val); 16 | if (!this.head) { 17 | this.head = newNode; 18 | this.tail = this.head; 19 | } else { 20 | this.tail.next = newNode; 21 | this.tail = newNode; 22 | } 23 | this.length++; 24 | return this; 25 | } 26 | pop() { 27 | if (!this.head) return undefined; 28 | var current = this.head; 29 | var newTail = current; 30 | while (current.next) { 31 | newTail = current; 32 | current = current.next; 33 | } 34 | this.tail = newTail; 35 | this.tail.next = null; 36 | this.length--; 37 | if (this.length === 0) { 38 | this.head = null; 39 | this.tail = null; 40 | } 41 | return current; 42 | } 43 | 44 | unshift(val) { 45 | // have current head 46 | // set val.next = current head 47 | // set head to val 48 | // increase length 49 | // return val? 50 | 51 | var newNode = new Node(val); 52 | 53 | if (!this.head) { 54 | this.head = newNode; 55 | this.tail = newNode; 56 | } else { 57 | newNode.next = this.head; 58 | this.head = newNode; 59 | } 60 | 61 | this.length++; 62 | 63 | return this; 64 | } 65 | 66 | shift() { 67 | // have current head 68 | // set head to current head.next 69 | //make head.next = null 70 | //return original head 71 | 72 | // this is constant times always 73 | // regardless of how big the list is 74 | 75 | if (!this.head) { 76 | return undefined; 77 | } 78 | 79 | let oldHead = this.head; 80 | 81 | this.head = this.head.next; 82 | oldHead.next = null; 83 | this.length--; 84 | 85 | if (this.length == 0) { 86 | this.tail = null; 87 | } 88 | 89 | return oldHead; 90 | } 91 | 92 | get(index) { 93 | if (!this.head || index < 0 || index >= this.length) { 94 | return undefined; 95 | } 96 | 97 | let current = this.head; 98 | let count = 0; 99 | 100 | while (count != index) { 101 | current = current.next; 102 | count++; 103 | } 104 | return current; 105 | } 106 | 107 | set(index, val) { 108 | // change the value of a node based on 109 | // its position in the linked list 110 | 111 | // get index 112 | // the set index.val to val 113 | 114 | let current = this.get(index); 115 | 116 | if (current) { 117 | current.val = val; 118 | return true; 119 | } 120 | 121 | return false; 122 | } 123 | 124 | insert(index, val) { 125 | //inserts a new node at specific position 126 | if (index > this.length || index < 0) { 127 | // not valid index!! 128 | return false; 129 | } 130 | 131 | if (index == this.length) { 132 | this.push(val); 133 | return true; 134 | } else if (index == 0) { 135 | this.unshift(val); 136 | return true; 137 | } 138 | 139 | const newNode = new Node(val); 140 | let prev = this.get(index - 1); 141 | let temp = prev.next; 142 | prev.next = newNode; 143 | newNode.next = temp; 144 | this.length++; 145 | return true; 146 | } 147 | 148 | remove(index) { 149 | if (index < 0 || index >= this.length) { 150 | return false; 151 | } 152 | 153 | if (index === 0) { 154 | // let next = this.head.next; 155 | // this.head = next; 156 | // this.length--; 157 | this.shift(); 158 | return true; 159 | } else if (index === this.length - 1) { 160 | // let secondToLast = this.get(length - 2); 161 | // secondToLast.next = null; 162 | // this.length--; 163 | this.pop(); 164 | return true; 165 | } else { 166 | let prev = this.get(index - 1); 167 | prev.next = prev.next.next; 168 | this.length--; 169 | return true; 170 | } 171 | } 172 | } 173 | 174 | var list = new SinglyLinkedList(); 175 | 176 | list.push("HELLO"); 177 | list.push("GOODBYE"); 178 | list.push("!"); 179 | console.log(list); 180 | console.log(list.remove(2)); 181 | console.log(list.remove(0)); 182 | console.log(list); 183 | -------------------------------------------------------------------------------- /linked-lists/singlyLinkedListReverse.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | } 6 | } 7 | 8 | class SinglyLinkedList { 9 | constructor() { 10 | this.head = null; 11 | this.tail = null; 12 | this.length = 0; 13 | } 14 | push(val) { 15 | var newNode = new Node(val); 16 | if (!this.head) { 17 | this.head = newNode; 18 | this.tail = this.head; 19 | } else { 20 | this.tail.next = newNode; 21 | this.tail = newNode; 22 | } 23 | this.length++; 24 | return this; 25 | } 26 | 27 | pop() { 28 | if (!this.head) return undefined; 29 | var current = this.head; 30 | var newTail = current; 31 | while (current.next) { 32 | newTail = current; 33 | current = current.next; 34 | } 35 | this.tail = newTail; 36 | this.tail.next = null; 37 | this.length--; 38 | if (this.length === 0) { 39 | this.head = null; 40 | this.tail = null; 41 | } 42 | return current; 43 | } 44 | 45 | unshift(val) { 46 | // have current head 47 | // set val.next = current head 48 | // set head to val 49 | // increase length 50 | // return val? 51 | 52 | var newNode = new Node(val); 53 | 54 | if (!this.head) { 55 | this.head = newNode; 56 | this.tail = newNode; 57 | } else { 58 | newNode.next = this.head; 59 | this.head = newNode; 60 | } 61 | 62 | this.length++; 63 | 64 | return this; 65 | } 66 | 67 | shift() { 68 | // have current head 69 | // set head to current head.next 70 | //make head.next = null 71 | //return original head 72 | 73 | // this is constant times always 74 | // regardless of how big the list is 75 | 76 | if (!this.head) { 77 | return undefined; 78 | } 79 | 80 | let oldHead = this.head; 81 | 82 | this.head = this.head.next; 83 | oldHead.next = null; 84 | this.length--; 85 | 86 | if (this.length == 0) { 87 | this.tail = null; 88 | } 89 | 90 | return oldHead; 91 | } 92 | 93 | get(index) { 94 | if (!this.head || index < 0 || index >= this.length) { 95 | return undefined; 96 | } 97 | 98 | let current = this.head; 99 | let count = 0; 100 | 101 | while (count != index) { 102 | current = current.next; 103 | count++; 104 | } 105 | return current; 106 | } 107 | 108 | set(index, val) { 109 | // change the value of a node based on 110 | // its position in the linked list 111 | 112 | // get index 113 | // the set index.val to val 114 | 115 | let current = this.get(index); 116 | 117 | if (current) { 118 | current.val = val; 119 | return true; 120 | } 121 | 122 | return false; 123 | } 124 | 125 | insert(index, val) { 126 | //inserts a new node at specific position 127 | if (index > this.length || index < 0) { 128 | // not valid index!! 129 | return false; 130 | } 131 | 132 | if (index == this.length) { 133 | this.push(val); 134 | return true; 135 | } else if (index == 0) { 136 | this.unshift(val); 137 | return true; 138 | } 139 | 140 | const newNode = new Node(val); 141 | let prev = this.get(index - 1); 142 | let temp = prev.next; 143 | prev.next = newNode; 144 | newNode.next = temp; 145 | this.length++; 146 | return true; 147 | } 148 | 149 | remove(index) { 150 | if (index < 0 || index >= this.length) { 151 | return false; 152 | } 153 | 154 | if (index === 0) { 155 | // let next = this.head.next; 156 | // this.head = next; 157 | // this.length--; 158 | this.shift(); 159 | return true; 160 | } else if (index === this.length - 1) { 161 | // let secondToLast = this.get(length - 2); 162 | // secondToLast.next = null; 163 | // this.length--; 164 | this.pop(); 165 | return true; 166 | } else { 167 | let prev = this.get(index - 1); 168 | prev.next = prev.next.next; 169 | this.length--; 170 | return true; 171 | } 172 | } 173 | print() { 174 | let arr = []; 175 | let current = this.head; 176 | while (current) { 177 | arr.push(current.val); 178 | current = current.next; 179 | } 180 | console.log(arr); 181 | } 182 | 183 | reverse() { 184 | let currentNode = this.head; 185 | let previousNode = null; 186 | let nextNode = null; 187 | 188 | while (currentNode) { 189 | //set temp variable to hold pointer to next 190 | nextNode = currentNode.next; 191 | 192 | //set the next val to the previous value 193 | // initially is null as tail points to null. 194 | currentNode.next = previousNode; 195 | 196 | //then move the currentNode to previous 197 | // set the node next to the currentNode as the currentNode 198 | previousNode = currentNode; 199 | currentNode = nextNode; 200 | } 201 | 202 | [this.head, this.tail] = [this.tail, this.head]; 203 | 204 | return this; 205 | } 206 | 207 | // traverse() { 208 | // let current = this.head; 209 | // while (current) { 210 | // console.log(current.val); 211 | // current = current.next; 212 | // } 213 | // } 214 | } 215 | var list = new SinglyLinkedList(); 216 | 217 | list.push("HELLO"); 218 | list.push("GOODBYE"); 219 | list.push("!"); 220 | 221 | // console.log(list); 222 | console.log(list.print()); 223 | console.log(list.reverse()); 224 | console.log(list.print()); 225 | 226 | // console.log(list.traverse()); 227 | -------------------------------------------------------------------------------- /linked-lists/singlyLinkedListSet.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | } 6 | } 7 | 8 | class SinglyLinkedList { 9 | constructor() { 10 | this.head = null; 11 | this.tail = null; 12 | this.length = 0; 13 | } 14 | push(val) { 15 | var newNode = new Node(val); 16 | if (!this.head) { 17 | this.head = newNode; 18 | this.tail = this.head; 19 | } else { 20 | this.tail.next = newNode; 21 | this.tail = newNode; 22 | } 23 | this.length++; 24 | return this; 25 | } 26 | pop() { 27 | if (!this.head) return undefined; 28 | var current = this.head; 29 | var newTail = current; 30 | while (current.next) { 31 | newTail = current; 32 | current = current.next; 33 | } 34 | this.tail = newTail; 35 | this.tail.next = null; 36 | this.length--; 37 | if (this.length === 0) { 38 | this.head = null; 39 | this.tail = null; 40 | } 41 | return current; 42 | } 43 | 44 | unshift(val) { 45 | // have current head 46 | // set val.next = current head 47 | // set head to val 48 | // increase length 49 | // return val? 50 | 51 | var newNode = new Node(val); 52 | 53 | if (!this.head) { 54 | this.head = newNode; 55 | this.tail = newNode; 56 | } else { 57 | newNode.next = this.head; 58 | this.head = newNode; 59 | } 60 | 61 | this.length++; 62 | 63 | return this; 64 | } 65 | 66 | shift() { 67 | // have current head 68 | // set head to current head.next 69 | //make head.next = null 70 | //return original head 71 | 72 | // this is constant times always 73 | // regardless of how big the list is 74 | 75 | if (!this.head) { 76 | return undefined; 77 | } 78 | 79 | let oldHead = this.head; 80 | 81 | this.head = this.head.next; 82 | oldHead.next = null; 83 | this.length--; 84 | 85 | if (this.length == 0) { 86 | this.tail = null; 87 | } 88 | 89 | return oldHead; 90 | } 91 | 92 | get(index) { 93 | if (!this.head || index < 0 || index >= this.length) { 94 | return undefined; 95 | } 96 | 97 | let current = this.head; 98 | let count = 0; 99 | 100 | while (count != index) { 101 | current = current.next; 102 | count++; 103 | } 104 | return current; 105 | } 106 | 107 | set(index, val) { 108 | // change the value of a node based on 109 | // its position in the linked list 110 | 111 | // get index 112 | // the set index.val to val 113 | 114 | let current = this.get(index); 115 | 116 | if (current) { 117 | current.val = val; 118 | return true; 119 | } 120 | 121 | return false; 122 | } 123 | } 124 | 125 | var list = new SinglyLinkedList(); 126 | 127 | list.push("HELLO"); 128 | list.push("GOODBYE"); 129 | list.push("!"); 130 | list.push("<3"); 131 | list.push(":)"); 132 | list.push("$"); 133 | console.log(list.get(5)); 134 | console.log(list.set(5, "potatomonster")); 135 | // console.log(list); 136 | console.log(list.get(5)); 137 | -------------------------------------------------------------------------------- /linked-lists/singlyLinkedListShift.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | } 6 | } 7 | 8 | class SinglyLinkedList { 9 | constructor() { 10 | this.head = null; 11 | this.tail = null; 12 | this.length = 0; 13 | } 14 | push(val) { 15 | var newNode = new Node(val); 16 | if (!this.head) { 17 | this.head = newNode; 18 | this.tail = this.head; 19 | } else { 20 | this.tail.next = newNode; 21 | this.tail = newNode; 22 | } 23 | this.length++; 24 | return this; 25 | } 26 | pop() { 27 | if (!this.head) return undefined; 28 | var current = this.head; 29 | var newTail = current; 30 | while (current.next) { 31 | newTail = current; 32 | current = current.next; 33 | } 34 | this.tail = newTail; 35 | this.tail.next = null; 36 | this.length--; 37 | if (this.length === 0) { 38 | this.head = null; 39 | this.tail = null; 40 | } 41 | return current; 42 | } 43 | 44 | shift() { 45 | // have current head 46 | // set head to current head.next 47 | //make head.next = null 48 | //return original head 49 | 50 | // this is constant times always 51 | // regardless of how big the list is 52 | 53 | if (!this.head) { 54 | return undefined; 55 | } 56 | 57 | let oldHead = this.head; 58 | 59 | this.head = this.head.next; 60 | oldHead.next = null; 61 | this.length--; 62 | 63 | if (this.length == 0) { 64 | this.tail = null; 65 | } 66 | 67 | return oldHead; 68 | } 69 | } 70 | 71 | var list = new SinglyLinkedList(); 72 | list.push("HELLO"); 73 | list.push("GOODBYE"); 74 | list.push("!"); 75 | console.log(list); 76 | console.log(list.shift()); 77 | console.log(list); 78 | -------------------------------------------------------------------------------- /linked-lists/singlyLinkedListUnshift.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(val) { 3 | this.val = val; 4 | this.next = null; 5 | } 6 | } 7 | 8 | class SinglyLinkedList { 9 | constructor() { 10 | this.head = null; 11 | this.tail = null; 12 | this.length = 0; 13 | } 14 | push(val) { 15 | var newNode = new Node(val); 16 | if (!this.head) { 17 | this.head = newNode; 18 | this.tail = this.head; 19 | } else { 20 | this.tail.next = newNode; 21 | this.tail = newNode; 22 | } 23 | this.length++; 24 | return this; 25 | } 26 | pop() { 27 | if (!this.head) return undefined; 28 | var current = this.head; 29 | var newTail = current; 30 | while (current.next) { 31 | newTail = current; 32 | current = current.next; 33 | } 34 | this.tail = newTail; 35 | this.tail.next = null; 36 | this.length--; 37 | if (this.length === 0) { 38 | this.head = null; 39 | this.tail = null; 40 | } 41 | return current; 42 | } 43 | 44 | unshift(val) { 45 | // have current head 46 | // set val.next = current head 47 | // set head to val 48 | // increase length 49 | // return val? 50 | 51 | var newNode = new Node(val); 52 | 53 | if (!this.head) { 54 | this.head = newNode; 55 | this.tail = newNode; 56 | } else { 57 | newNode.next = this.head; 58 | this.head = newNode; 59 | } 60 | 61 | this.length++; 62 | 63 | return this; 64 | } 65 | 66 | shift() { 67 | // have current head 68 | // set head to current head.next 69 | //make head.next = null 70 | //return original head 71 | 72 | // this is constant times always 73 | // regardless of how big the list is 74 | 75 | if (!this.head) { 76 | return undefined; 77 | } 78 | 79 | let oldHead = this.head; 80 | 81 | this.head = this.head.next; 82 | oldHead.next = null; 83 | this.length--; 84 | 85 | if (this.length == 0) { 86 | this.tail = null; 87 | } 88 | 89 | return oldHead; 90 | } 91 | } 92 | 93 | var list = new SinglyLinkedList(); 94 | list.push("HELLO"); 95 | list.push("GOODBYE"); 96 | list.push("!"); 97 | console.log(list.unshift("YAHOO!")); 98 | -------------------------------------------------------------------------------- /mapExercises.js: -------------------------------------------------------------------------------- 1 | function doubleNumbers(arr) { 2 | return arr.map(item => item * 2); 3 | } 4 | 5 | console.log(doubleNumbers([2, 5, 100])); // [4, 10, 200] 6 | 7 | function stringItUp(arr) { 8 | return arr.map(item => item.toString()); 9 | } 10 | 11 | console.log(stringItUp([2, 5, 100])); // ["2", "5", "100"] 12 | 13 | function capitalizeNames(arr) { 14 | return arr.map(word => word.toUpperCase()); 15 | } 16 | 17 | console.log(capitalizeNames(["john", "JACOB", "jinGleHeimer", "schmidt"])); // ["John", "Jacob", "Jingleheimer", "Schmidt"] 18 | 19 | function namesOnly(arr) { 20 | return arr.map(word => word.name); 21 | } 22 | 23 | console.log( 24 | namesOnly([ 25 | { 26 | name: "Angelina Jolie", 27 | age: 80 28 | }, 29 | { 30 | name: "Eric Jones", 31 | age: 2 32 | }, 33 | { 34 | name: "Paris Hilton", 35 | age: 5 36 | }, 37 | { 38 | name: "Kayne West", 39 | age: 16 40 | }, 41 | { 42 | name: "Bob Ziroll", 43 | age: 100 44 | } 45 | ]) 46 | ); 47 | // ["Angelina Jolie", "Eric Jones", "Paris Hilton", "Kayne West", "Bob Ziroll"] 48 | 49 | function makeStrings(arr) { 50 | return arr.map(person => { 51 | if (person.age > 18) return `${person.name} can go to The Matrix`; 52 | return `${person.name} is under age`; 53 | }); 54 | } 55 | 56 | console.log( 57 | makeStrings([ 58 | { 59 | name: "Angelina Jolie", 60 | age: 80 61 | }, 62 | { 63 | name: "Eric Jones", 64 | age: 2 65 | }, 66 | { 67 | name: "Paris Hilton", 68 | age: 5 69 | }, 70 | { 71 | name: "Kayne West", 72 | age: 16 73 | }, 74 | { 75 | name: "Bob Ziroll", 76 | age: 100 77 | } 78 | ]) 79 | ); 80 | // ["Angelina Jolie can go to The Matrix", 81 | // "Eric Jones is under age!!", 82 | // "Paris Hilton is under age!!", 83 | // "Kayne West is under age!!", 84 | // "Bob Ziroll can go to The Matrix"] 85 | 86 | function readyToPutInTheDOM(arr) { 87 | return arr.map(person => `

${person.name}

${person.age}

`); 88 | } 89 | console.log( 90 | readyToPutInTheDOM([ 91 | { 92 | name: "Angelina Jolie", 93 | age: 80 94 | }, 95 | { 96 | name: "Eric Jones", 97 | age: 2 98 | }, 99 | { 100 | name: "Paris Hilton", 101 | age: 5 102 | }, 103 | { 104 | name: "Kayne West", 105 | age: 16 106 | }, 107 | { 108 | name: "Bob Ziroll", 109 | age: 100 110 | } 111 | ]) 112 | ); 113 | // ["

Angelina Jolie

80

", 114 | // "

Eric Jones

2

", 115 | // "

Paris Hilton

5

", 116 | // "

Kayne West

16

", 117 | // "

Bob Ziroll

100

"] 118 | -------------------------------------------------------------------------------- /max69.js: -------------------------------------------------------------------------------- 1 | // 1323. Maximum 69 Number 2 | // Easy 3 | 4 | // Given a positive integer num consisting only of digits 6 and 9. 5 | 6 | // Return the maximum number you can get by changing at most one digit(6 becomes 9, and 9 becomes 6). 7 | 8 | // Example 1: 9 | 10 | // Input: num = 9669 11 | // Output: 9969 12 | // Explanation: 13 | // Changing the first digit results in 6669. 14 | // Changing the second digit results in 9969. 15 | // Changing the third digit results in 9699. 16 | // Changing the fourth digit results in 9666. 17 | // The maximum number is 9969. 18 | // Example 2: 19 | 20 | // Input: num = 9996 21 | // Output: 9999 22 | // Explanation: Changing the last digit 6 to 9 results in the maximum number. 23 | // Example 3: 24 | 25 | // Input: num = 9999 26 | // Output: 9999 27 | // Explanation: It is better not to apply any change. 28 | 29 | // Constraints: 30 | 31 | // 1 <= num <= 10 ^ 4 32 | // num's digits are 6 or 9. 33 | 34 | // source: https://leetcode.com/problems/maximum-69-number/ 35 | 36 | /** 37 | * @param {number} num 38 | * @return {number} 39 | */ 40 | var maximum69Number = function(num) { 41 | const nums = num.toString().split(""); 42 | 43 | for (number in nums) { 44 | if (nums[number] == "6") { 45 | nums[number] = "9"; 46 | break; 47 | } 48 | } 49 | return parseInt(nums.join("")); 50 | }; 51 | 52 | // alternate solution with built-ins which takes more time: 53 | // return parseInt(num.toString().replace("6", "9")) 54 | -------------------------------------------------------------------------------- /maxProduct.js: -------------------------------------------------------------------------------- 1 | var maximumProduct = function(nums) { 2 | nums.sort((a, b) => 0 - b - (0 - a)); 3 | 4 | const lowerProduct = nums 5 | .slice(0, 2) 6 | .concat(nums.slice(-1)) 7 | .reduce((acc, val) => { 8 | return acc * val; 9 | }, 1); 10 | 11 | const upperProduct = nums.slice(-3).reduce((acc, val) => { 12 | return acc * val; 13 | }, 1); 14 | 15 | return lowerProduct > upperProduct ? lowerProduct : upperProduct; 16 | }; 17 | 18 | console.log(maximumProduct([29, -10, 400, 100])); 19 | console.log(maximumProduct([1, 2, 3, 4])); // 24 20 | console.log(maximumProduct([1, 2, 3])); // 6 21 | console.log(maximumProduct([-1, -2, 1, 2, 3])); //6 22 | console.log(maximumProduct([1000, 1000, 2, 1, 2, 5, 3, 1])); 23 | -------------------------------------------------------------------------------- /maxProfit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} prices 3 | * @return {number} 4 | */ 5 | var maxProfit = function (prices) { 6 | // use two pointers 7 | // if don't have stock and slow is greater than fast, buy slow 8 | // sell when you reach a point where it is no longer increasing there will be the greatest profit 9 | 10 | let slow = 0; 11 | let fast = 1; 12 | let total = 0; 13 | let haveStock = false; 14 | 15 | while (slow !== fast && fast < prices.length) { 16 | // console.log('initial total ', total) 17 | // console.log('slow', slow, 'fast', fast) 18 | if (prices[slow] < prices[fast] && !haveStock) { 19 | // buy slow 20 | total = total - prices[slow]; 21 | haveStock = true; 22 | // console.log('buying', 'new total is ', total) 23 | } else if ( 24 | prices[slow] > prices[fast] && 25 | total + prices[slow] > 0 && 26 | haveStock 27 | ) { 28 | //sell now 29 | haveStock = false; 30 | total = total + prices[slow]; 31 | 32 | // console.log('selling', 'new total is ', total) 33 | } 34 | 35 | fast++; 36 | slow++; 37 | } 38 | 39 | if (haveStock) { 40 | total = Math.max(total, total + prices[prices.length - 1]); 41 | } 42 | 43 | return Math.max(total, 0); 44 | }; 45 | 46 | console.log(maxProfit([7, 1, 5, 3, 6, 4])); // 7 47 | console.log(maxProfit([1, 2, 3, 4, 5])); // 4 48 | // total = 0 49 | // 1,2 - hasStock, total = -1 50 | // 2,3 - !hasStock, total = 51 | -------------------------------------------------------------------------------- /maxSubarraySum.js: -------------------------------------------------------------------------------- 1 | function maxSubarraySum(array, targetLength) { 2 | // should take in array 3 | // find the sum of the of first x elements (x is targetLength) 4 | // then go thropugh rest to see if there is a higher sum 5 | //within the array for x elements 6 | 7 | if (!array || array.length < targetLength) { 8 | return null; 9 | } 10 | 11 | let sum = 0; 12 | 13 | for (let i = 0; i < targetLength; i++) { 14 | sum = sum + array[i]; 15 | } 16 | 17 | let max = sum; 18 | let firstPointer = 0; 19 | let secondPointer = targetLength; 20 | 21 | while (secondPointer <= array.length - targetLength) { 22 | sum = sum - array[firstPointer] + array[secondPointer]; 23 | 24 | if (sum > max) { 25 | max = sum; 26 | } 27 | 28 | secondPointer++; 29 | firstPointer++; 30 | } 31 | sum = sum - array[firstPointer] + array[secondPointer]; 32 | return max > sum ? max : sum; 33 | u; 34 | } 35 | 36 | console.log(maxSubarraySum([100, 200, 300, 400], 2)); // 700 37 | console.log(maxSubarraySum([1, 4, 2, 10, 23, 3, 1, 0, 20], 4)); //39 38 | console.log(maxSubarraySum([-3, 4, 0, -2, 6, -1], 2)); // 5 39 | console.log(maxSubarraySum([3, -2, 7, -4, 1, -1, 4, -2, 1], 2)); //5 40 | console.log(maxSubarraySum([2, 3], 3)); // null 41 | 42 | // function maxSubarraySum(array, length) { 43 | // // should take in array 44 | // // find the total of first x elements 45 | // // then go thropugh rest to see if there is a higher total 46 | 47 | // if (array.length < length) { 48 | // return null; 49 | // } 50 | 51 | // let max = -Infinity; 52 | // let sum = 0; 53 | // let lowest = 0; 54 | // let highest = length; 55 | 56 | // for (let i = 0; i < length; i++) { 57 | // sum = sum + array[i]; 58 | // } 59 | 60 | // while (highest <= array.length - length) { 61 | // sum = sum - array[lowest] + array[highest]; 62 | 63 | // if (sum > max) { 64 | // max = sum; 65 | // } 66 | 67 | // lowest++; 68 | // highest++; 69 | // } 70 | 71 | // sum = sum - array[lowest] + array[highest]; 72 | 73 | // return sum > max ? sum : max; 74 | // } 75 | 76 | console.log(maxSubarraySum([100, 200, 300, 400], 2)); // 700 77 | console.log(maxSubarraySum([1, 4, 2, 10, 23, 3, 1, 0, 20], 4)); //39 78 | console.log(maxSubarraySum([-3, 4, 0, -2, 6, -1], 2)); // 5 79 | console.log(maxSubarraySum([3, -2, 7, -4, 1, -1, 4, -2, 1], 2)); //5 80 | console.log(maxSubarraySum([2, 3], 3)); // null 81 | -------------------------------------------------------------------------------- /maximumNumberOfBalloons.js: -------------------------------------------------------------------------------- 1 | // Given a string text, you want to use the characters of text to form as many instances of the word "balloon" as possible. 2 | 3 | // You can use each character in text at most once.Return the maximum number of instances that can be formed. 4 | 5 | /** 6 | * @param {string} text 7 | * @return {number} 8 | */ 9 | var maxNumberOfBalloons = function(text) { 10 | const letters = text.split(""); 11 | const letterCount = {}; 12 | for (letter of letters) { 13 | if (letterCount[letter]) { 14 | letterCount[letter] = letterCount[letter] + 1; 15 | } else { 16 | letterCount[letter] = 1; 17 | } 18 | } 19 | 20 | let balloonsCount = 21 | Math.floor( 22 | Math.min( 23 | letterCount["b"] / 1, 24 | letterCount["a"] / 1, 25 | letterCount["l"] / 2, 26 | letterCount["o"] / 2, 27 | letterCount["n"] / 1 28 | ) 29 | ) || 0; 30 | 31 | // let balloonsCount = 0; 32 | // let notFound = false; 33 | 34 | // while (!notFound) { 35 | // if ( 36 | // letterCount["b"] >= 1 && 37 | // letterCount["a"] >= 1 && 38 | // letterCount["l"] >= 2 && 39 | // letterCount["o"] >= 2 && 40 | // letterCount["n"] >= 1 41 | // ) { 42 | // letterCount["b"] = letterCount["b"] - 1; 43 | // letterCount["a"] = letterCount["a"] - 1; 44 | // letterCount["l"] = letterCount["l"] - 2; 45 | // letterCount["o"] = letterCount["o"] - 2; 46 | // letterCount["n"] = letterCount["n"] - 1; 47 | // balloonsCount++; 48 | // } else { 49 | // notFound = true; 50 | // } 51 | // } 52 | 53 | // return balloonsCount; 54 | return balloonsCount; 55 | }; 56 | 57 | console.log(maxNumberOfBalloons("nlaebolko")); // 1 58 | 59 | console.log(maxNumberOfBalloons("loonbalxballpoon")); //2 60 | 61 | console.log(maxNumberOfBalloons("leetcode")); // 0 62 | 63 | console.log(maxNumberOfBalloons("balon")); // 0 64 | -------------------------------------------------------------------------------- /maximumSubArray.js: -------------------------------------------------------------------------------- 1 | // Given an integer array nums, find the contiguous subarray(containing at least one number) which has the largest sum and return its sum. 2 | 3 | // Example: 4 | 5 | // Input: [-2, 1, -3, 4, -1, 2, 1, -5, 4], 6 | // Output: 6 7 | // Explanation: [4, -1, 2, 1] has the largest sum = 6. 8 | 9 | // Follow up: 10 | 11 | // If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle. 12 | 13 | // https://leetcode.com/explore/challenge/card/30-day-leetcoding-challenge/528/week-1/3285/ 14 | 15 | /** 16 | * @param {number[]} nums 17 | * @return {number} 18 | */ 19 | var maxSubArray = function (nums) { 20 | if (nums.length === 1) { 21 | return nums[0]; 22 | } 23 | 24 | let total = 0; 25 | let highestTotal = nums[0]; 26 | 27 | for (num in nums) { 28 | if (nums[num] > nums[num] + total || num == 0) { 29 | total = nums[num]; 30 | } else { 31 | total = nums[num] + total; 32 | } 33 | if (total > highestTotal) { 34 | highestTotal = total; 35 | } 36 | } 37 | return highestTotal; 38 | }; 39 | 40 | console.log(maxSubArray([-2, 1, -3, 4, -1, 2, 1, -5, 4])); // 6 41 | -------------------------------------------------------------------------------- /middleOfLinkedList.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * function ListNode(val) { 4 | * this.val = val; 5 | * this.next = null; 6 | * } 7 | */ 8 | /** 9 | * @param {ListNode} head 10 | * @return {ListNode} 11 | */ 12 | 13 | // var middleNode = function (head) { 14 | // let current = head; 15 | // let length = 0; 16 | 17 | // while (current.next !== null) { 18 | // length++; 19 | // current = current.next; 20 | // } 21 | 22 | // let count = 0; 23 | // current = head; 24 | // const mid = Math.ceil(length / 2); 25 | // while (count < mid) { 26 | // count++; 27 | // current = current.next; 28 | // } 29 | // return current; 30 | // }; 31 | 32 | var middleNode = function (head) { 33 | let fast = head; 34 | let slow = head; 35 | 36 | while (fast != null && fast.next != null) { 37 | slow = slow.next; 38 | fast = fast.next.next; 39 | } 40 | 41 | return slow; 42 | }; 43 | -------------------------------------------------------------------------------- /minSubArrayLen.js: -------------------------------------------------------------------------------- 1 | function minSubArrayLen(array, target) { 2 | //find the minimum length where sum > sum passed in 3 | 4 | let min = 0; 5 | let next = 1; 6 | 7 | while (min > next) { 8 | if(target[]) 9 | min++; 10 | next++; 11 | } 12 | } 13 | 14 | console.log(minSubArrayLen([2, 3, 1, 2, 4, 3]), 7); // 2 15 | console.log(minSubArrayLen([2, 1, 6, 5, 4], 9)); //2 16 | console.log(minSubArrayLen([3, 1, 7, 11, 2, 9, 8, 21, 62, 33, 19], 52)); //1 17 | console.log(minSubArrayLen([1, 4, 16, 22, 5, 7, 8, 9, 10]), 39); // 3 18 | console.log(minSubArrayLen([1, 4, 16, 22, 5, 7, 8, 9, 10]), 55); // 5 19 | console.log(minSubArrayLen([4, 3, 3, 8, 1, 2, 3]), 11); // 2 20 | console.log(minSubArrayLen([1, 4, 16, 22, 5, 7, 8, 9, 10]), 95); // 2 21 | -------------------------------------------------------------------------------- /minValueInStack.js: -------------------------------------------------------------------------------- 1 | /** 2 | * initialize your data structure here. 3 | */ 4 | var MinStack = function () { 5 | this.items = [{ item: null, min: null }]; 6 | this.lastItem = function () { 7 | return this.items[this.items.length - 1]; 8 | }; 9 | }; 10 | 11 | /** 12 | * @param {number} x 13 | * @return {void} 14 | */ 15 | MinStack.prototype.push = function (x) { 16 | const lastMin = this.lastItem()["min"]; 17 | const min = lastMin == null ? x : Math.min(lastMin, x); 18 | 19 | return this.items.push({ item: x, min: min }); 20 | }; 21 | 22 | /** 23 | * @return {void} 24 | */ 25 | MinStack.prototype.pop = function () { 26 | return this.items.pop(); 27 | }; 28 | 29 | /** 30 | * @return {number} 31 | */ 32 | MinStack.prototype.top = function () { 33 | return this.lastItem()["item"]; 34 | }; 35 | 36 | /** 37 | * @return {number} 38 | */ 39 | MinStack.prototype.getMin = function () { 40 | return this.lastItem()["min"]; 41 | }; 42 | 43 | /** 44 | * Your MinStack object will be instantiated and called as such: 45 | * var obj = new MinStack() 46 | * obj.push(x) 47 | * obj.pop() 48 | * var param_3 = obj.top() 49 | * var param_4 = obj.getMin() 50 | */ 51 | -------------------------------------------------------------------------------- /mostCommonWord.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} paragraph 3 | * @param {string[]} banned 4 | * @return {string} 5 | */ 6 | var mostCommonWord = function(paragraph, banned) { 7 | let words = paragraph.toLowerCase().split(/[ ,.!?';]+/); 8 | 9 | const wordCount = new Map(); 10 | 11 | let mostCommon = { value: 0, word: "" }; 12 | for (word of words) { 13 | if (banned.includes(word)) { 14 | // do nothing 15 | } else if (wordCount.get(word)) { 16 | wordCount.set(word, wordCount.get(word) + 1); 17 | } else { 18 | wordCount.set(word, 1); 19 | } 20 | 21 | if (wordCount.get(word) > mostCommon.value) { 22 | mostCommon = { value: wordCount.get(word), word }; 23 | } 24 | } 25 | 26 | return mostCommon.word; 27 | }; 28 | 29 | const paragraph = "Bob hit a ball, the hit BALL flew far after it was hit."; 30 | const banned = ["hit"]; 31 | 32 | console.log(mostCommonWord(paragraph, banned)); // "ball" 33 | console.log(mostCommonWord("a, a, a, a, b,b,b,c, c", ["a"])); 34 | -------------------------------------------------------------------------------- /moveZeroes.js: -------------------------------------------------------------------------------- 1 | // Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements. 2 | 3 | // Example: 4 | 5 | // Input: [0, 1, 0, 3, 12] 6 | // Output: [1, 3, 12, 0, 0] 7 | // Note: 8 | 9 | // You must do this in -place without making a copy of the array. 10 | // Minimize the total number of operations. 11 | 12 | /** 13 | * @param {number[]} nums 14 | * @return {void} Do not return anything, modify nums in-place instead. 15 | */ 16 | var moveZeroes = function (nums) { 17 | // let's look at every num 18 | // if num = 0 19 | // remove it and push it to the end of nums 20 | // once we have reached the end of non-zeros the iterations should stop 21 | // we determine that with `nums.length - 1 - zeroCount` 22 | 23 | let zeroCount = 0; 24 | for (let i = 0; i < nums.length - 1 - zeroCount; i++) { 25 | if (nums[i] == 0) { 26 | nums.splice(i, 1); 27 | nums.push(0); 28 | zeroCount++; 29 | i--; 30 | } 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /numberComplement.js: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/explore/challenge/card/may-leetcoding-challenge/534/week-1-may-1st-may-7th/3319/ 2 | 3 | // Given a positive integer, output its complement number.The complement strategy is to flip the bits of its binary representation. 4 | 5 | // Example 1: 6 | 7 | // Input: 5 8 | // Output: 2 9 | // Explanation: The binary representation of 5 is 101(no leading zero bits), and its complement is 010.So you need to output 2. 10 | 11 | // Example 2: 12 | 13 | // Input: 1 14 | // Output: 0 15 | // Explanation: The binary representation of 1 is 1(no leading zero bits), and its complement is 0. So you need to output 0. 16 | 17 | // Note: 18 | 19 | // The given integer is guaranteed to fit within the range of a 32 - bit signed integer. 20 | // You could assume no leading zero bit in the integer’s binary representation. 21 | // This question is the same as 1009: https://leetcode.com/problems/complement-of-base-10-integer/ 22 | 23 | /** 24 | * @param {number} num 25 | * @return {number} 26 | */ 27 | var findComplement = function (num) { 28 | let binary = num.toString(2); 29 | let inverseBinary = binary 30 | .split("") 31 | .reduce((acc, val) => { 32 | val == 1 ? acc.push("0") : acc.push("1"); 33 | return acc; 34 | }, []) 35 | .join(""); 36 | 37 | return Number.parseInt(inverseBinary, 2); 38 | }; 39 | 40 | console.log(findComplement(5)); // 2 41 | console.log(findComplement(1)); // 0 42 | -------------------------------------------------------------------------------- /oneAway.js: -------------------------------------------------------------------------------- 1 | // One Away: There are three types of edits that can be performed on strings: 2 | // insert a character, remove a character, or replace a character.Given two 3 | // strings, write a function to check if they are one edit(or zero edits) away. 4 | 5 | function oneAway(first, second) { 6 | if (first.length - second.length > 1) { 7 | console.log("false"); 8 | return false; 9 | } 10 | 11 | const firstArray = first.split(""); 12 | const secondArray = second.split(""); 13 | 14 | if (firstArray.length > secondArray.length) { 15 | console.log("first string is longer than second string"); 16 | var j; 17 | for (j = 0; j < firstArray.length - 1; j++) { 18 | if ( 19 | firstArray[j] != secondArray[j] && 20 | firstArray[j] != secondArray[j + 1] 21 | ) { 22 | firstArray.splice(j, 1); 23 | 24 | console.log(firstArray.join("") == secondArray.join("")); 25 | return firstArray.join("") == secondArray.join(""); 26 | } 27 | } 28 | } else if (secondArray.length > firstArray.length) { 29 | var k; 30 | for (k = 0; k < secondArray.length - 1; k++) { 31 | if ( 32 | secondArray[k] != firstArray[k] && 33 | secondArray[k] != firstArray[k + 1] 34 | ) { 35 | secondArray.splice(k, 1); 36 | console.log(firstArray.join("") == secondArray.join("")); 37 | return firstArray.join("") == secondArray.join(""); 38 | } 39 | } 40 | } else if (first.length == second.length) { 41 | console.log("first string is the same length as second string"); 42 | 43 | var i; 44 | for (i = 0; i < firstArray.length - 1; i++) { 45 | if (firstArray[i] != secondArray[i]) { 46 | firstArray[i] = secondArray[i]; 47 | console.log(firstArray.join("") == secondArray.join("")); 48 | return firstArray.join("") == secondArray.join(""); 49 | } 50 | } 51 | } 52 | 53 | console.log(firstArray.join("") == secondArray.join("")); 54 | return firstArray.join("") == secondArray.join(""); 55 | } 56 | 57 | oneAway("pale", "ple"); 58 | oneAway("pales", "pale"); 59 | oneAway("pale", "bale"); 60 | oneAway("pale", "bake"); 61 | -------------------------------------------------------------------------------- /oneAwayTakeTwo.js: -------------------------------------------------------------------------------- 1 | // One Away: There are three types of edits that can be performed on strings: 2 | // insert a character, remove a character, or replace a character.Given two 3 | // strings, write a function to check if they are one edit(or zero edits) away. 4 | 5 | // function oneAway(first, second) { 6 | // if (Math.abs(first.length - second.length) > 1) { 7 | // return false; 8 | // } 9 | // } 10 | -------------------------------------------------------------------------------- /overlappingMeetings.js: -------------------------------------------------------------------------------- 1 | function mergeRanges(meetings) { 2 | // Merge overlapping meeting time reanges into one entry 3 | 4 | // appraoch: 5 | // sort the object by startTime so that the meetings are in an order 6 | // for each range in the meetings arraay 7 | // see if the next item has a start time that is less than or equal to this end time 8 | // if so combine by using splice to update the two entries in the object 9 | // the lowest start time should be the start time 10 | // theh highest end time should be the end time 11 | // then decrement the counter :tada: 12 | 13 | meetings = meetings.sort((a, b) => a.startTime - b.startTime); 14 | 15 | var i; 16 | 17 | for (i = 0; i < meetings.length - 1; i++) { 18 | thisEndTime = meetings[i].endTime; 19 | thisStartTime = meetings[i].startTime; 20 | nextStartTime = meetings[i + 1].startTime; 21 | nextEndTime = meetings[i + 1].endTime; 22 | 23 | if (thisEndTime >= nextStartTime) { 24 | const startTime = 25 | thisStartTime < nextStartTime ? thisStartTime : nextStartTime; // returns the earlier start time 26 | const endTime = thisEndTime > nextEndTime ? thisEndTime : nextEndTime; // returns the later end time 27 | meetings.splice(i, 2, { startTime, endTime }); 28 | 29 | i--; 30 | } 31 | } 32 | return meetings; 33 | } 34 | 35 | // Tests 36 | 37 | // let desc = "meetings overlap"; 38 | // let actual = mergeRanges([ 39 | // { startTime: 1, endTime: 3 }, 40 | // { startTime: 2, endTime: 4 } 41 | // ]); 42 | // let expected = [{ startTime: 1, endTime: 4 }]; 43 | // assertArrayEquals(actual, expected, desc); 44 | 45 | // desc = "meetings touch"; 46 | // actual = mergeRanges([ 47 | // { startTime: 5, endTime: 6 }, 48 | // { startTime: 6, endTime: 8 } 49 | // ]); 50 | // expected = [{ startTime: 5, endTime: 8 }]; 51 | // assertArrayEquals(actual, expected, desc); 52 | 53 | // desc = "meeting contains other meeting"; 54 | // actual = mergeRanges([ 55 | // { startTime: 1, endTime: 8 }, 56 | // { startTime: 2, endTime: 5 } 57 | // ]); 58 | // expected = [{ startTime: 1, endTime: 8 }]; 59 | // assertArrayEquals(actual, expected, desc); 60 | 61 | // desc = "meetings stay separate"; 62 | // actual = mergeRanges([ 63 | // { startTime: 1, endTime: 3 }, 64 | // { startTime: 4, endTime: 8 } 65 | // ]); 66 | // expected = [{ startTime: 1, endTime: 3 }, { startTime: 4, endTime: 8 }]; 67 | // assertArrayEquals(actual, expected, desc); 68 | 69 | // desc = "multiple merged meetings"; 70 | // actual = mergeRanges([ 71 | // { startTime: 1, endTime: 4 }, 72 | // { startTime: 2, endTime: 5 }, 73 | // { startTime: 5, endTime: 8 } 74 | // ]); 75 | // expected = [{ startTime: 1, endTime: 8 }]; 76 | // assertArrayEquals(actual, expected, desc); 77 | 78 | // desc = "meetings not sorted"; 79 | // actual = mergeRanges([ 80 | // { startTime: 5, endTime: 8 }, 81 | // { startTime: 1, endTime: 4 }, 82 | // { startTime: 6, endTime: 8 } 83 | // ]); 84 | // expected = [{ startTime: 1, endTime: 4 }, { startTime: 5, endTime: 8 }]; 85 | // assertArrayEquals(actual, expected, desc); 86 | 87 | // desc = "oneLongMeetingContainsSmallerMeetings"; 88 | // actual = mergeRanges([ 89 | // { startTime: 1, endTime: 10 }, 90 | // { startTime: 2, endTime: 5 }, 91 | // { startTime: 6, endTime: 8 }, 92 | // { startTime: 9, endTime: 10 }, 93 | // { startTime: 10, endTime: 12 } 94 | // ]); 95 | // expected = [{ startTime: 1, endTime: 12 }]; 96 | // assertArrayEquals(actual, expected, desc); 97 | 98 | // desc = "sample input"; 99 | // actual = mergeRanges([ 100 | // { startTime: 0, endTime: 1 }, 101 | // { startTime: 3, endTime: 5 }, 102 | // { startTime: 4, endTime: 8 }, 103 | // { startTime: 10, endTime: 12 }, 104 | // { startTime: 9, endTime: 10 } 105 | // ]); 106 | // expected = [ 107 | // { startTime: 0, endTime: 1 }, 108 | // { startTime: 3, endTime: 8 }, 109 | // { startTime: 9, endTime: 12 } 110 | // ]; 111 | // assertArrayEquals(actual, expected, desc); 112 | 113 | // function assertArrayEquals(a, b, desc) { 114 | // // Sort the keys in each meeting to avoid 115 | // // failing based on differences in key order. 116 | // orderedA = a.map(function(meeting) { 117 | // return JSON.stringify(meeting, Object.keys(meeting).sort()); 118 | // }); 119 | // orderedB = b.map(function(meeting) { 120 | // return JSON.stringify(meeting, Object.keys(meeting).sort()); 121 | // }); 122 | // const arrayA = JSON.stringify(orderedA); 123 | // const arrayB = JSON.stringify(orderedB); 124 | // if (arrayA !== arrayB) { 125 | // console.log( 126 | // `${desc} ... FAIL: ${JSON.stringify(a)} != ${JSON.stringify(b)}` 127 | // ); 128 | // } else { 129 | // console.log(`${desc} ... PASS`); 130 | // } 131 | // } 132 | -------------------------------------------------------------------------------- /pairSum.js: -------------------------------------------------------------------------------- 1 | function pairSum(array, target) { 2 | let low = 0; 3 | let high = array.length - 1; 4 | 5 | if (array.length == 0) { 6 | return false; 7 | } 8 | 9 | while (low !== high) { 10 | if (array[low] + array[high] === target) { 11 | return true; 12 | } else if (array[low] + array[high] < target) { 13 | low++; 14 | } else { 15 | high--; 16 | } 17 | } 18 | 19 | return false; 20 | } 21 | 22 | console.log(pairSum([1, 3, 5], 8)); 23 | 24 | console.log(pairSum([1, 4, 5], 8)); 25 | 26 | console.log(pairSum([], 8)); 27 | -------------------------------------------------------------------------------- /palindromePermutation.js: -------------------------------------------------------------------------------- 1 | /// Palindrome Permutation: Given a string, write a function to 2 | /// check if it is a permutation of a palin - drome.A palindrome 3 | /// is a word or phrase that is the same forwards and backwards.A 4 | /// permutation is a rearrangement of letters.The palindrome does not 5 | /// need to be limited to just dictionary words. 6 | 7 | function checkPalindromPermutation2(word) { 8 | const letterCount = new Map(); 9 | for (let letter of word) { 10 | if (letterCount.has(letter)) { 11 | letterCount.set(letter, letterCount.get(letter) + 1); 12 | } else { 13 | letterCount.set(letter, 1); 14 | } 15 | } 16 | 17 | let oddCount = 0; 18 | letterCount.forEach((value, key) => { 19 | if (value % 2 != 0) { 20 | oddCount++; 21 | } 22 | }); 23 | 24 | return oddCount <= 1; 25 | } 26 | 27 | function checkPalindromPermutation(word) { 28 | const letters = word.split(""); 29 | const mappedLetters = new Map(); 30 | 31 | for (var letter of letters) { 32 | if (letter != "" && mappedLetters.has(letter)) { 33 | mappedLetters.set(letter, mappedLetters.get(letter) + 1); 34 | } else { 35 | mappedLetters.set(letter, 1); 36 | } 37 | } 38 | 39 | let odd = 0; 40 | 41 | for (var mappedLetter of mappedLetters) { 42 | if (letter != "" && mappedLetters.get(letter) % 2 != 0) { 43 | odd++; 44 | } 45 | 46 | if (odd > 1) { 47 | return false; 48 | } 49 | } 50 | 51 | return true; 52 | } 53 | 54 | console.log(checkPalindromPermutation2("tot")); 55 | console.log(checkPalindromPermutation2("car")); 56 | -------------------------------------------------------------------------------- /palindromePermutation2.js: -------------------------------------------------------------------------------- 1 | function hasPalindromePermutation(theString) { 2 | // Check if any permutation of the input is a palindrome 3 | const letterMap = new Map(); 4 | 5 | for (letter of theString) { 6 | if (letterMap.has(letter)) { 7 | // this letter is the seconf of a pair so reset to 0 8 | letterMap.set(letter, 0); 9 | } else { 10 | // this letter is odd so set to 1 11 | letterMap.set(letter, 1); 12 | } 13 | } 14 | 15 | let oddLetterCount = 0; 16 | 17 | letterMap.forEach(letter => letter != 0 && oddLetterCount++); 18 | 19 | return oddLetterCount <= 1; 20 | } 21 | -------------------------------------------------------------------------------- /perfectNumber.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | A perfect number is a positive integer that is equal to the sum of all its positive divisors except itself. 4 | Now, given an integer n, write a function that returns true when it is a perfect number and false when it is not. 5 | 6 | Example: 7 | Input: 6 8 | Output: True 9 | Explanation: 6 = 1 + 2 + 3 10 | 11 | Example: 12 | Input: 28 13 | Output: True 14 | Explanation: 28 = 1 +2 + 4 + 7 + 14 15 | 16 | */ 17 | 18 | // what are this numbers divisors 19 | // sum up the divisors 20 | // does that sum = the number 21 | // if not return false 22 | // if so return true 23 | 24 | function getDivisors(number) { 25 | let i; 26 | let divisors = []; 27 | for (i = 1; i < number; i++) { 28 | if (number % i == 0) { 29 | divisors.push(i); 30 | } 31 | } 32 | return divisors; 33 | } 34 | 35 | function isPerfectNumber(number) { 36 | const divisors = getDivisors(number); 37 | let sumOfDivisors = 0; 38 | 39 | for (divisor of divisors) { 40 | sumOfDivisors = sumOfDivisors + divisor; 41 | } 42 | 43 | return number == sumOfDivisors; 44 | } 45 | 46 | console.log(isPerfectNumber(495)); 47 | -------------------------------------------------------------------------------- /perfectNumbers2.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | A perfect number is a positive integer that is equal to the sum of all its positive divisors except itself. 4 | Now, given an integer n, write a function that returns true when it is a perfect number and false when it is not. 5 | 6 | Example: 7 | Input: 6 8 | Output: True 9 | Explanation: 6 = 1 + 2 + 3 10 | 11 | Example: 12 | Input: 28 13 | Output: True 14 | Explanation: 28 = 1 +2 + 4 + 7 + 14 15 | 16 | */ 17 | 18 | // for each number, determine its divisors 19 | // sum up the divisors 20 | // return whether or not the divisors equal that number 21 | 22 | function getDivisors(number) { 23 | let divisors = []; 24 | let i = 0; 25 | for (i; i < Math.sqrt(number); i++) { 26 | if (number % i == 0) { 27 | divisors.push(i); 28 | if (i != 1) { 29 | divisors.push(number / i); 30 | } 31 | } 32 | } 33 | 34 | return divisors; 35 | } 36 | 37 | function isPerfectNumber(number) { 38 | const divisors = getDivisors(number); 39 | // without reduce 40 | // let sumOfDivisors = 0; 41 | 42 | // for (divisor of divisors) { 43 | // sumOfDivisors = sumOfDivisors + divisor; 44 | // } 45 | 46 | // with reduce 47 | const sumOfDivisors = divisors.reduce((total, current) => total + current, 0); 48 | return sumOfDivisors == number; 49 | } 50 | 51 | console.log(getDivisors(28)); 52 | console.log(isPerfectNumber(28)); 53 | -------------------------------------------------------------------------------- /permutations.js: -------------------------------------------------------------------------------- 1 | // Check Permutation: Given two strings, write a method to decide if one is a 2 | // permutation of the other. 3 | 4 | function isPermutation(first, second) { 5 | const firstSorted = first 6 | .split("") 7 | .sort() 8 | .join("") 9 | .toLowerCase(); 10 | 11 | const secondSorted = second 12 | .split("") 13 | .sort() 14 | .join("") 15 | .toLowerCase(); 16 | 17 | return firstSorted == secondSorted; 18 | } 19 | 20 | console.log(isPermutation("hot", "toh")); 21 | console.log(isPermutation("applee", "apple")); 22 | 23 | function ifPermutation(first, second) { 24 | letterMap = new Map(); 25 | for (let letter in first) { 26 | if (letterMap.has(letter)) { 27 | letterMap.set(letter, letterMap.get(letter)); 28 | } else { 29 | letterMap.set(letter, 1); 30 | } 31 | } 32 | 33 | 34 | const mismatchLetters = false; 35 | letterMap.forEach((value, key) => ) 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /power.js: -------------------------------------------------------------------------------- 1 | // except base and exponent 2 | // should return the power of the base of the exponent 3 | // don't worry about negative bases and exponents 4 | 5 | console.log(power(2, 0)); //1 6 | console.log(power(2, 2)); //4 7 | console.log(power(2, 4)); //16 8 | 9 | function power(base, exponent) { 10 | if (exponent === 0) { 11 | return 1; 12 | } else { 13 | return base * power(base, exponent - 1); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /productOfArray.js: -------------------------------------------------------------------------------- 1 | console.log(productOfArray([1, 2, 3])); // 6 2 | console.log(productOfArray([1, 2, 3, 10])); // 60 3 | 4 | // function productOfArray(array) { 5 | // if (array.length == 1) { 6 | // return array[0]; 7 | // } else { 8 | // const lastItemPosition = array.length - 1; 9 | // const lastItem = array[lastItemPosition]; 10 | // array.splice(lastItemPosition, 1); 11 | // return lastItem * productOfArray(array); 12 | // } 13 | // } 14 | 15 | function productOfArray(array) { 16 | return array.reduce((acc, number) => acc * number, 1); 17 | } 18 | -------------------------------------------------------------------------------- /query-string-parser.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `parseQueryString` that accepts a query string parameter as an argument, and 3 | converts it into an object, using the following rules: 4 | * An equals sign (`=`) separates a *key* on the left from a *value* on the right. 5 | * An ampersand (`&`) separates key-value pairs from each other. 6 | * All keys and values should be parsed as Strings. 7 | * The query string will not contain spaces. 8 | Here are some example inputs and outputs (mind the edge cases!): 9 | ```javascript 10 | parseQueryString(""); 11 | //=> {} 12 | parseQueryString("a=1"); 13 | //=> { 14 | // "a": "1", 15 | // } 16 | parseQueryString("first=alpha&last=omega"); 17 | //=> { 18 | // "first": "alpha", 19 | // "last": "omega" 20 | // } 21 | parseQueryString("a=apple&b=beet&b=blueberry&c=&d=10"); 22 | //=> { 23 | // "a": "apple", 24 | // "b": "blueberry", // "blueberry" overwrites "beet"! 25 | // "c": "", // empty string (missing value) 26 | // "d": "10" // "10" is a String! 27 | // } 28 | ``` 29 | Mega Bonus 30 | - Can you create the reverse function? Given an object, output a Query Parameter String: 31 | ``` javascript 32 | var o = {first: "alpha", last: "omega"}; 33 | convertToQueryParameter(o); // "first=alpha&last=omega"; 34 | ``` 35 | */ 36 | 37 | function convertToQueryParameter(string) { 38 | let queryString = ""; 39 | 40 | Object.keys(string).forEach(key => { 41 | if (queryString.length) { 42 | queryString = `${queryString}&`; 43 | } 44 | queryString = `${queryString}${key}=${string[key]}`; 45 | }); 46 | 47 | return queryString; 48 | } 49 | 50 | function parseQueryString(string) { 51 | let queryStringParams = {}; 52 | 53 | if (!string.length) { 54 | return queryStringParams; 55 | } 56 | 57 | const queryStrings = string.split("&"); 58 | queryStrings 59 | .map(parameter => parameter.split("=")) 60 | .forEach(([key, value]) => { 61 | queryStringParams[key] = value; 62 | }); 63 | 64 | return queryStringParams; 65 | } 66 | 67 | console.log(parseQueryString("")); 68 | //=> {} 69 | console.log(parseQueryString("a=1")); 70 | //=> { 71 | // "a": "1", 72 | // } 73 | console.log(parseQueryString("first=alpha&last=omega")); 74 | //=> { 75 | // "first": "alpha", 76 | // "last": "omega" 77 | // } 78 | console.log(parseQueryString("a=apple&b=beet&b=blueberry&c=&d=10")); 79 | //=> { 80 | // "a": "apple", 81 | // "b": "blueberry", // "blueberry" overwrites "beet"! 82 | // "c": "", // empty string (missing value) 83 | // "d": "10" // "10" is a String! 84 | // } 85 | 86 | var o = { first: "alpha", last: "omega" }; 87 | console.log(convertToQueryParameter(o)); // "first=alpha&last=omega"; 88 | -------------------------------------------------------------------------------- /queue/queue.js: -------------------------------------------------------------------------------- 1 | class Queue { 2 | constructor() { 3 | this.first = null; 4 | this.last = null; 5 | this.size = 0; 6 | } 7 | 8 | enqueue(val) { 9 | // add to the end, similar to push 10 | const newNode = new Node(val); 11 | 12 | if (!this.first) { 13 | this.first = newNode; 14 | this.last = newNode; 15 | } else { 16 | this.last.next = newNode; 17 | this.last = newNode; 18 | } 19 | 20 | return ++this.size; 21 | } 22 | 23 | deqeueue() { 24 | //similar to shift, 25 | //remove items from list 26 | 27 | if (!this.first) { 28 | return null; 29 | } 30 | 31 | if (this.first === this.last) { 32 | this.last = null; 33 | } 34 | let temp = this.first; 35 | 36 | this.first = this.first.next; 37 | 38 | this.size--; 39 | 40 | return temp.value; 41 | } 42 | } 43 | 44 | class Node { 45 | constructor(value) { 46 | this.value = value; 47 | this.next = null; 48 | } 49 | } 50 | 51 | let queue = new Queue(); 52 | 53 | console.log(queue.enqueue("hello")); 54 | console.log(queue.enqueue("bye")); 55 | console.log(queue.deqeueue()); 56 | console.log(queue.deqeueue()); 57 | 58 | console.log(queue.deqeueue()); 59 | -------------------------------------------------------------------------------- /ransomNote.js: -------------------------------------------------------------------------------- 1 | // Ransom Note 2 | // Given an arbitrary ransom note string and another string containing letters from all the magazines, write a function that will return true if the ransom note can be constructed from the magazines; otherwise, it will return false. 3 | 4 | // Each letter in the magazine string can only be used once in your ransom note. 5 | 6 | // Note: 7 | // You may assume that both strings contain only lowercase letters. 8 | 9 | // canConstruct("a", "b") -> false 10 | // canConstruct("aa", "ab") -> false 11 | // canConstruct("aa", "aab") -> true 12 | 13 | // https://leetcode.com/explore/challenge/card/may-leetcoding-challenge/534/week-1-may-1st-may-7th/3318/ 14 | 15 | /** 16 | * @param {string} ransomNote 17 | * @param {string} magazine 18 | * @return {boolean} 19 | */ 20 | var canConstruct = function (ransomNote, magazine) { 21 | let ransomLetters = {}; 22 | for (let letter of magazine) { 23 | ransomLetters[letter] = ransomLetters[letter] 24 | ? ransomLetters[letter] + 1 25 | : 1; 26 | } 27 | 28 | for (let letter of ransomNote) { 29 | if (ransomLetters[letter] && ransomLetters[letter] > 0) { 30 | ransomLetters[letter] = ransomLetters[letter] - 1; 31 | } else { 32 | return false; 33 | } 34 | } 35 | 36 | return true; 37 | }; 38 | 39 | console.log(canConstruct("a", "b")); //false 40 | console.log(canConstruct("aa", "ab")); //false 41 | console.log(canConstruct("aa", "aab")); //true 42 | -------------------------------------------------------------------------------- /recursive/recursiveCapitalizeWords.js: -------------------------------------------------------------------------------- 1 | function capitalizeWords(words) { 2 | // add whatever parameters you deem necessary - good luck! 3 | 4 | // iterative solution 5 | // for (word in words) { 6 | // words[word] = words[word].toUpperCase(); 7 | // } 8 | // return words; 9 | 10 | if (words.length == 1) { 11 | return words[0].toUpperCase(); 12 | } else { 13 | let [firstWord, ...rest] = words; 14 | let formatted = firstWord.toUpperCase() + "," + capitalizeWords(rest); 15 | return formatted.split(","); 16 | } 17 | } 18 | 19 | let words = ["i", "am", "learning", "recursion"]; 20 | console.log(capitalizeWords(words)); // ['I', 'AM', 'LEARNING', 'RECURSION'] 21 | -------------------------------------------------------------------------------- /recursive/recursiveFibonnaci.js: -------------------------------------------------------------------------------- 1 | // 0, 1, 1, 2, 3, 5, 8, 13, 21, 34; 2 | 3 | function fibonnaci(number) { 4 | if (number <= 1) { 5 | return number; 6 | } else { 7 | return fibonnaci(number - 1) + fibonnaci(number - 2); 8 | } 9 | } 10 | console.log(fibonnaci(0)); // 0 11 | console.log(fibonnaci(1)); //1 12 | console.log(fibonnaci(2)); // 1 13 | console.log(fibonnaci(3)); // 2 14 | console.log(fibonnaci(8)); // 21 15 | console.log(fibonnaci(11)); //89 16 | -------------------------------------------------------------------------------- /recursive/recursivePalindrome.js: -------------------------------------------------------------------------------- 1 | console.log(isPalindrome("awesome")); // false 2 | console.log(isPalindrome("foobar")); // false 3 | console.log(isPalindrome("tacocat")); // true 4 | console.log(isPalindrome("amanaplanacanalpanama")); // true 5 | console.log(isPalindrome("amanaplanacanalpandemonium")); // false 6 | 7 | function isPalindrome(word, index) { 8 | if (!index) { 9 | return isPalindrome(word, word.length - 1); 10 | } else if (index < (word.length - 1) / 2) { 11 | return true; 12 | } else { 13 | let oppositeIndex = word.length - 1 - index; 14 | if (word[oppositeIndex] == word[index]) { 15 | return isPalindrome(word, index - 1); 16 | } else { 17 | return false; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /recursive/recursiveRange.js: -------------------------------------------------------------------------------- 1 | //add up all the numbers from 0 to the number passed to the function 2 | 3 | console.log(recursiveRange(6)); //21 4 | console.log(recursiveRange(10)); //55 5 | 6 | function recursiveRange(number) { 7 | if (number == 1) { 8 | return 1; 9 | } else { 10 | return number + recursiveRange(number - 1); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /recursive/recursiveReverseString.js: -------------------------------------------------------------------------------- 1 | function reverse(word, index) { 2 | if (!index) { 3 | return reverse(word, word.length - 1); 4 | } else if (index <= (word.length - 1) / 2) { 5 | return word; 6 | } else { 7 | let letters = word.split(""); 8 | let startIndex = word.length - 1 - index; 9 | let temp = letters[index]; 10 | letters[index] = letters[startIndex]; 11 | letters[startIndex] = temp; 12 | 13 | return reverse(letters.join(""), index - 1); 14 | } 15 | } 16 | 17 | console.log(reverse("awesome")); // 'emosewa' 18 | console.log(reverse("rithmschool")); // 'loohcsmhtir' 19 | 20 | //BROKEN AT THE MOMENT 21 | -------------------------------------------------------------------------------- /recursive/someRecursive.js: -------------------------------------------------------------------------------- 1 | // SAMPLE INPUT / OUTPUT 2 | const isOdd = val => val % 2 !== 0; 3 | 4 | console.log(someRecursive([1, 2, 3, 4], isOdd)); // true 5 | console.log(someRecursive([4, 6, 8, 9], isOdd)); // true 6 | console.log(someRecursive([4, 6, 8], isOdd)); // false 7 | console.log(someRecursive([4, 6, 8], val => val > 10)); // false 8 | 9 | //returns true if a single value in the array returns true from the callback 10 | 11 | function someRecursive(array, callback, index) { 12 | if (!index) { 13 | return someRecursive(array, callback, array.length - 1); 14 | } else if (index <= 1) { 15 | return callback(array[0]) || callback(array[1]); 16 | } else { 17 | if (callback(array[index])) { 18 | return true; 19 | } else { 20 | return someRecursive(array, callback, index - 1); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /reduceExercises.js: -------------------------------------------------------------------------------- 1 | // https://coursework.vschool.io/array-reduce-exercises/ 2 | function total(arr) { 3 | return arr.reduce((acc, value) => acc + value, 0); 4 | } 5 | 6 | console.log(total([1, 2, 3])); // 6 7 | 8 | function stringConcat(arr) { 9 | return arr.reduce((acc, value) => acc + value, ""); 10 | } 11 | 12 | console.log(stringConcat([1, 2, 3])); // "123" 13 | 14 | function totalVotes(arr) { 15 | return arr.reduce((acc, person) => { 16 | if (person.voted) { 17 | acc++; 18 | } 19 | return acc; 20 | }, 0); 21 | } 22 | // solved without using reduce: 23 | // function totalVotes(arr) { 24 | // return arr.filter(person => person.voted).length; 25 | // } 26 | 27 | var voters = [ 28 | { name: "Bob", age: 30, voted: true }, 29 | { name: "Jake", age: 32, voted: true }, 30 | { name: "Kate", age: 25, voted: false }, 31 | { name: "Sam", age: 20, voted: false }, 32 | { name: "Phil", age: 21, voted: true }, 33 | { name: "Ed", age: 55, voted: true }, 34 | { name: "Tami", age: 54, voted: true }, 35 | { name: "Mary", age: 31, voted: false }, 36 | { name: "Becky", age: 43, voted: false }, 37 | { name: "Joey", age: 41, voted: true }, 38 | { name: "Jeff", age: 30, voted: true }, 39 | { name: "Zack", age: 19, voted: false } 40 | ]; 41 | console.log(totalVotes(voters)); // 7 42 | 43 | function shoppingSpree(arr) { 44 | return arr.reduce((acc, item) => acc + item.price, 0); 45 | } 46 | 47 | var wishlist = [ 48 | { title: "Tesla Model S", price: 90000 }, 49 | { title: "4 carat diamond ring", price: 45000 }, 50 | { title: "Fancy hacky Sack", price: 5 }, 51 | { title: "Gold fidgit spinner", price: 2000 }, 52 | { title: "A second Tesla Model S", price: 90000 } 53 | ]; 54 | 55 | console.log(shoppingSpree(wishlist)); // 227005 56 | 57 | function flatten(arr) { 58 | return arr.reduce((acc, item) => acc.concat(item), []); 59 | } 60 | 61 | var arrays = [["1", "2", "3"], [true], [4, 5, 6]]; 62 | 63 | console.log(flatten(arrays)); // ["1", "2", "3", true, 4, 5, 6]; 64 | 65 | var voters = [ 66 | { name: "Bob", age: 30, voted: true }, 67 | { name: "Jake", age: 32, voted: true }, 68 | { name: "Kate", age: 25, voted: false }, 69 | { name: "Sam", age: 20, voted: false }, 70 | { name: "Phil", age: 21, voted: true }, 71 | { name: "Ed", age: 55, voted: true }, 72 | { name: "Tami", age: 54, voted: true }, 73 | { name: "Mary", age: 31, voted: false }, 74 | { name: "Becky", age: 43, voted: false }, 75 | { name: "Joey", age: 41, voted: true }, 76 | { name: "Jeff", age: 30, voted: true }, 77 | { name: "Zack", age: 19, voted: false } 78 | ]; 79 | 80 | function voterResults(arr) { 81 | // Include how many of the potential voters were in the ages 18-25, 82 | // how many from 26-35, how many from 36-55, 83 | //and how many of each of those age ranges actually voted. 84 | //The resulting object containing this data should have 6 properties. 85 | // See the example output at the bottom. 86 | 87 | const initialVotes = { 88 | youngVotes: 0, 89 | youth: 0, 90 | midVotes: 0, 91 | mids: 0, 92 | oldVotes: 0, 93 | olds: 0 94 | }; 95 | 96 | const peersToVotePeers = { 97 | youth: "youngVotes", 98 | mids: "midVotes", 99 | olds: "oldVotes" 100 | }; 101 | 102 | return arr.reduce((acc, voter) => { 103 | let peers; 104 | if (voter.age < 26) { 105 | peers = "youth"; 106 | } else if (voter.age < 36) { 107 | peers = "mids"; 108 | } else { 109 | peers = "olds"; 110 | } 111 | // console.log(acc); 112 | if (!voter.voted) { 113 | return { ...acc, [peers]: acc[peers] + 1 }; 114 | } else { 115 | const votePeers = peersToVotePeers[peers]; 116 | // if (peers === "youth") { 117 | // votePeers = "youngVotes"; 118 | // } else if (peers === "mids") { 119 | // votePeers = "midVotes"; 120 | // } else { 121 | // votePeers = "oldVotes"; 122 | // } 123 | return { 124 | ...acc, 125 | [peers]: acc[peers] + 1, 126 | [votePeers]: acc[votePeers] + 1 127 | }; 128 | } 129 | }, initialVotes); 130 | } 131 | 132 | console.log(voterResults(voters)); // Returned value shown below: 133 | /* 134 | { youngVotes: 1, 135 | youth: 4, 136 | midVotes: 3, 137 | mids: 4, 138 | oldVotes: 3, 139 | olds: 4 140 | } 141 | */ 142 | 143 | /* calculator exercise*/ 144 | 145 | function calculator(operations, initialValue) { 146 | return operations.reduce((acc, { type, value }) => { 147 | // if (type == "Add") { 148 | // return acc + value; 149 | // } else if (type == "Multiply") { 150 | // return acc * value; 151 | // } else if (type == "Divide") { 152 | // return acc / value; 153 | // } else if (type == "Subtract") { 154 | // return acc - value; 155 | // } 156 | 157 | switch (type) { 158 | case "Add": 159 | return acc + value; 160 | case "Multiply": 161 | return acc * value; 162 | case "Subtract": 163 | return acc - value; 164 | case "Divide": 165 | return acc / value; 166 | default: 167 | return acc; 168 | } 169 | }, initialValue); 170 | } 171 | let operations = [ 172 | { type: "Add", value: 4 }, 173 | { type: "Multiply", value: 3 }, 174 | { type: "Divide", value: 2 }, 175 | { type: "Subtract", value: 3 } 176 | ]; 177 | console.log(calculator(operations, 6)); // 12 178 | -------------------------------------------------------------------------------- /reduceReuseRecycle.js: -------------------------------------------------------------------------------- 1 | // https://egghead.io/lessons/javascript-transform-an-array-into-a-single-value-using-reduce 2 | 3 | var votes = [ 4 | "angular", 5 | "angular", 6 | "react", 7 | "react", 8 | "react", 9 | "angular", 10 | "ember", 11 | "react", 12 | "vanilla" 13 | ]; 14 | 15 | function tallyVotes(array) { 16 | const totalVotes = {}; 17 | 18 | return array.reduce((tally, vote) => { 19 | if (!tally[vote]) { 20 | tally[vote] = 1; 21 | } else { 22 | tally[vote] = tally[vote] + 1; 23 | } 24 | return tally; 25 | }, totalVotes); 26 | } 27 | console.log(tallyVotes(votes)); // { angular: 3, react: 4, ember: 1, vanilla: 1 } 28 | 29 | var data = [1, 2, 3]; 30 | function doubledArray(array) { 31 | return array.reduce((acc, item) => { 32 | acc.push(item * 2); 33 | return acc; 34 | }, []); 35 | } 36 | console.log(data.map(item => item * 2)); // [2,4,6] 37 | console.log(doubledArray(data)); // [2,4,6] 38 | 39 | var longData = [1, 2, 3, 4, 5, 6]; 40 | function onlyEven() { 41 | return longData.reduce((acc, item) => { 42 | if (item % 2 == 0) { 43 | acc.push(item); 44 | } 45 | return acc; 46 | }, []); 47 | } 48 | console.log(longData.filter(item => item % 2 === 0)); // [2,4,6] 49 | console.log(onlyEven(longData)); // [2,4,6] 50 | 51 | var bigData = []; 52 | for (var i = 0; i < 1000000; i++) { 53 | bigData[i] = i; 54 | } 55 | -------------------------------------------------------------------------------- /removeDuplicatesFromString.js: -------------------------------------------------------------------------------- 1 | // can also convert string to array -> Set -> array 2 | // in order to solve in one-line 3 | 4 | function removeDuplicates(str) { 5 | let words = str.split(" "); 6 | let uniqueWords = {}; 7 | 8 | for (word of words) { 9 | uniqueWords[word] = true; 10 | } 11 | 12 | return words 13 | .reduce((acc, word) => { 14 | if (uniqueWords[word]) { 15 | acc.push(word); 16 | uniqueWords[word] = false; 17 | } 18 | return acc; 19 | }, []) 20 | .join(" "); 21 | } 22 | 23 | const str = "this is is a test string"; 24 | console.log(removeDuplicates(str)); 25 | -------------------------------------------------------------------------------- /reverseStringInPlace.js: -------------------------------------------------------------------------------- 1 | function reverse(arrayOfChars) { 2 | // Reverse the input array of characters in place 3 | // hot 4 | // toh 5 | 6 | // 012 7 | // 210 8 | 9 | // SMART 10 | // 0123 11 | // 3210 12 | 13 | let i; 14 | for (i = 0; i < arrayOfChars.length / 2; i++) { 15 | const originalItem = arrayOfChars[i]; 16 | const inverseIndex = arrayOfChars.length - 1 - i; 17 | const inverseItem = arrayOfChars[inverseIndex]; 18 | 19 | [originalItem, inverseItem] = [inverseItem, originalItem]; 20 | } 21 | 22 | return arrayOfChars; 23 | } 24 | 25 | // function reverse(arrayOfChars) { 26 | // // Reverse the input array of characters in place 27 | // // hot 28 | // // toh 29 | 30 | // // 012 31 | // // 210 32 | 33 | // // SMART 34 | // // 0123 35 | // // 3210 36 | 37 | // let i; 38 | // for (i = 0; i < arrayOfChars.length / 2; i++) { 39 | // const temp = arrayOfChars[i]; 40 | // arrayOfChars[i] = arrayOfChars[arrayOfChars.length - 1 - i]; 41 | // arrayOfChars[arrayOfChars.length - 1 - i] = temp; 42 | // } 43 | 44 | // return arrayOfChars; 45 | // } 46 | -------------------------------------------------------------------------------- /reverseWords.js: -------------------------------------------------------------------------------- 1 | function reverseWords(message) { 2 | message = message.join("").split(" "); 3 | 4 | let start = 0; 5 | let end = message.length - 1; 6 | 7 | while (start < end) { 8 | let temp = message[start]; 9 | 10 | message[start] = message[end]; 11 | message[end] = temp; 12 | start++; 13 | end--; 14 | } 15 | 16 | return message; 17 | } 18 | 19 | const message = [ 20 | "c", 21 | "a", 22 | "k", 23 | "e", 24 | " ", 25 | "p", 26 | "o", 27 | "u", 28 | "n", 29 | "d", 30 | " ", 31 | "s", 32 | "t", 33 | "e", 34 | "a", 35 | "l" 36 | ]; 37 | 38 | console.log(reverseWords(message)); // Prints: ['steal', 'pound', 'cake'] 39 | console.log(reverseWords("thief cake".split(""))); 40 | -------------------------------------------------------------------------------- /roundBasedOnValue/index.js: -------------------------------------------------------------------------------- 1 | const conciseRound = (num) => ~~num; 2 | const round = (num) => (num > 0 ? Math.floor(num) : Math.ceil(num)); 3 | 4 | [1.7, -2.1, 500.4, -369.5, 150, -350].forEach((num) => { 5 | console.log(conciseRound(num)); 6 | console.log(round(num)); 7 | }); 8 | -------------------------------------------------------------------------------- /roundBasedOnValue/readme.md: -------------------------------------------------------------------------------- 1 | # Rounding up or down based on value 2 | 3 | Given a positive or negative real number, round it to the next whole integer closer to zero. This means if it’s positive, round down, and if it’s negative, round up. Try to do this in as few characters possible! 4 | 5 | Test cases: 6 | 7 | ``` 8 | 1.7 => 1 9 | -2.1 => -2 10 | 500.4 => 500 11 | -369.5 => -369 12 | 150 => 150 13 | -350 => -350 14 | ``` 15 | 16 | Source: Issue #194 of rendezvous with cassidoo. https://cassidoo.co/newsletter/ -------------------------------------------------------------------------------- /sameFrequency.js: -------------------------------------------------------------------------------- 1 | // find out if two numbers have the same frequency of digits 2 | // https://www.udemy.com/course/js-algorithms-and-data-structures-masterclass/learn/quiz/4410598#overview 3 | 4 | function sameFrequency(first, second) { 5 | first = first.toString(); 6 | second = second.toString(); 7 | 8 | if (first.length !== second.length) { 9 | return false; 10 | } 11 | const frequencies = {}; 12 | //for each digit in number, convert to string and then add to object 13 | for (let digit of first) { 14 | frequencies[digit] = frequencies[digit]++ || 1; 15 | } 16 | // then for second determine if the frequencies are same 17 | 18 | for (let digit of second) { 19 | if (frequencies[digit]) { 20 | frequencies[digit] - 1; 21 | } else { 22 | return false; 23 | } 24 | } 25 | 26 | return true; 27 | } 28 | 29 | console.log(sameFrequency(182, 281)); // true 30 | console.log(sameFrequency(34, 14)); // false 31 | console.log(sameFrequency(3589578, 5879385)); // true 32 | console.log(sameFrequency(22, 222)); // false 33 | -------------------------------------------------------------------------------- /scrambles.js: -------------------------------------------------------------------------------- 1 | // Group Anagrams: Write a method to sort an array of strings 2 | // so that all the anagrams are next to each other. 3 | 4 | // ['abc', 'frog', 'cba', 'grof'] 5 | 6 | // look to see if we have anagram (sorted version in dict already) 7 | // if not then add this current item's index to dict 8 | 9 | // then loop through dict to add all of the items in a sorted way 10 | 11 | function groupAnagrams(words) { 12 | const wordTracker = new Map(); 13 | for (index in words) { 14 | const sortedWord = words[index] 15 | .split("") 16 | .sort() 17 | .join(); 18 | 19 | if (wordTracker.has(sortedWord)) { 20 | wordTracker.set( 21 | sortedWord, 22 | wordTracker.get(sortedWord).concat(words[index]) 23 | ); 24 | } else { 25 | wordTracker.set(sortedWord, new Array(words[index])); 26 | } 27 | } 28 | 29 | const sortedAnagrams = []; 30 | 31 | // is there a way to convert javascript map into an array automagically? 32 | wordTracker.forEach(word => sortedAnagrams.push(word)); 33 | 34 | return sortedAnagrams; 35 | } 36 | 37 | console.log(groupAnagrams(["abc", "frog", "cba", "grof"])); 38 | -------------------------------------------------------------------------------- /shiftString.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @param {number[][]} shift 4 | * @return {string} 5 | */ 6 | var stringShift = function (s, shift) { 7 | s = s.split(""); 8 | 9 | for (const instruction of shift) { 10 | const [direction, number] = instruction; 11 | 12 | let rounds = 0; 13 | while (rounds != number) { 14 | direction == 0 ? s.push(s.shift()) : s.splice(0, 0, s.pop()); 15 | rounds++; 16 | } 17 | } 18 | 19 | return s.join(""); 20 | }; 21 | 22 | console.log( 23 | stringShift("abc", [ 24 | [0, 1], 25 | [1, 2], 26 | ]) 27 | ); //"cab" 28 | console.log( 29 | stringShift("abcdefg", [ 30 | [1, 1], 31 | [1, 1], 32 | [0, 2], 33 | [1, 3], 34 | ]) 35 | ); //"efgabcd" 36 | -------------------------------------------------------------------------------- /singleNumber.js: -------------------------------------------------------------------------------- 1 | // /** 2 | // * @param {number[]} nums 3 | // * @return {number} 4 | // */ 5 | 6 | // Given a non - empty array of integers, every element appears twice except for one.Find that single one. 7 | 8 | // Note: 9 | 10 | // Your algorithm should have a linear runtime complexity.Could you implement it without using extra memory ? 11 | 12 | // Example 1: 13 | 14 | // Input: [2, 2, 1] 15 | // Output: 1 16 | 17 | // Example 2: 18 | 19 | // Input: [4, 1, 2, 1, 2] 20 | // Output: 4 21 | 22 | // var singleNumber = function(nums) { 23 | // let i = 0; 24 | 25 | // nums.sort((a, b) => a - b); 26 | 27 | // for (i; i < nums.length; i++) { 28 | // if (nums[i - 1] != nums[i] && nums[i] != nums[i + 1]) { 29 | // return nums[i]; 30 | // } 31 | // } 32 | // }; 33 | 34 | var singleNumber = function(nums) { 35 | let count = new Map(); 36 | for (num of nums) { 37 | if (count.get(num)) { 38 | count.set(num, count.get(num) + 1); 39 | } else { 40 | count.set(num, 1); 41 | } 42 | } 43 | 44 | let singleNum; 45 | 46 | count.forEach((value, key) => { 47 | if (value == 1) { 48 | singleNum = key; 49 | } 50 | }); 51 | 52 | return singleNum; 53 | }; 54 | console.log(singleNumber([4, 1, 2, 1, 2])); 55 | -------------------------------------------------------------------------------- /sortExercises.js: -------------------------------------------------------------------------------- 1 | function leastToGreatest(arr) { 2 | return arr.sort((a, b) => a - b); 3 | } 4 | 5 | console.log(leastToGreatest([1, 3, 5, 2, 90, 20])); // [1, 2, 3, 5, 20, 90] 6 | 7 | function greatestToLeast(arr) { 8 | return arr.sort((a, b) => b - a); 9 | } 10 | 11 | console.log(greatestToLeast([1, 3, 5, 2, 90, 20])); // [90, 20, 5, 3, 2, 1] 12 | 13 | function lengthSort(arr) { 14 | return arr.sort((a, b) => a.length - b.length); 15 | } 16 | 17 | console.log(lengthSort(["dog", "wolf", "by", "family", "eaten"])); // ["by", "dog", "wolf", "eaten", "family"] 18 | 19 | function alphabetical(arr) { 20 | return arr.sort(); 21 | } 22 | 23 | console.log(alphabetical(["dog", "wolf", "by", "family", "eaten"])); // ["by", "dog", "eaten", "family", "wolf"] 24 | 25 | function byAge(arr) { 26 | return arr.sort((a, b) => a.age - b.age); 27 | } 28 | 29 | console.log( 30 | byAge([ 31 | { name: "Quiet Samurai", age: 22 }, 32 | { name: "Arrogant Ambassador", age: 100 }, 33 | { name: "Misunderstood Observer", age: 2 }, 34 | { name: "Unlucky Swami", age: 77 } 35 | ]) 36 | ); 37 | // => [ { name: 'Misunderstood Observer', age: 2 }, 38 | // { name: 'Quiet Samurai', age: 22 }, 39 | // { name: 'Unlucky Swami', age: 77 }, 40 | // { name: 'Arrogant Ambassador', age: 100 } ] 41 | -------------------------------------------------------------------------------- /squaredValuesMatch.js: -------------------------------------------------------------------------------- 1 | //takes in two arrays 2 | function isThisSquared(original, squared) { 3 | // add each number (squared) to object, increment count 4 | // and then check for second array that the frequencies are the same 5 | 6 | const frequencies = {}; 7 | 8 | if (original.length != squared.length) { 9 | return false; 10 | } 11 | 12 | for (number of original) { 13 | const square = number * number; 14 | frequencies[square] = frequencies[square]++ || 1; 15 | } 16 | 17 | for (square of squared) { 18 | if (frequencies[square]) { 19 | frequencies[square] = frequencies[square] - 1; 20 | } else { 21 | return false; 22 | } 23 | } 24 | 25 | return true; 26 | } 27 | 28 | console.log(isThisSquared([1, 2, 3], [4, 9, 1])); // true 29 | console.log(isThisSquared([1, 2, 3], [9, 1])); // false 30 | console.log(isThisSquared([1, 2, 1], [4, 4, 1])); // false 31 | -------------------------------------------------------------------------------- /stacks/stack.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(value) { 3 | this.value = value; 4 | this.next = null; 5 | } 6 | } 7 | class Stack { 8 | constructor() { 9 | this.size = 0; 10 | this.first = null; 11 | this.last = null; 12 | } 13 | 14 | push(val) { 15 | const newNode = new Node(val); 16 | if (this.size === 0) { 17 | this.first = newNode; 18 | this.last = newNode; 19 | } else { 20 | let temp = this.first; 21 | this.first = newNode; 22 | this.first.next = temp; 23 | } 24 | this.size++; 25 | return this.size; 26 | } 27 | pop() { 28 | if (this.size == 0) { 29 | return null; 30 | } 31 | 32 | let temp = this.first; 33 | if (this.first === this.last) { 34 | this.last = null; 35 | } 36 | this.first = this.first.next; 37 | this.size--; 38 | 39 | return temp.value; 40 | } 41 | } 42 | 43 | const stack = new Stack(); 44 | 45 | console.log(stack.push("2")); 46 | console.log(stack.push(1000)); 47 | console.log(stack.pop()); 48 | 49 | console.log(stack.pop()); 50 | 51 | console.log(stack.pop()); 52 | -------------------------------------------------------------------------------- /stringCompression.js: -------------------------------------------------------------------------------- 1 | // String Compression: Implement a method to perform basic string 2 | // compression using the counts of repeated characters.For example, 3 | // the string aabcccccaaa would become a2b1c5a3.If the "compressed" 4 | // string would not become smaller than the original string, your method 5 | // should return the original string.You can assume the string has only 6 | // uppercase and lowercase letters(a - z). 7 | 8 | function compression(string) { 9 | const letters = string.split(""); 10 | const letterCountMap = new Map(); 11 | 12 | for (letter of letters) { 13 | if (letterCountMap.has(letter)) { 14 | letterCountMap.set(letter, letterCountMap.get(letter) + 1); 15 | } else { 16 | letterCountMap.set(letter, 1); 17 | } 18 | } 19 | 20 | let compressedString = ""; 21 | 22 | for (let [key, value] of letterCountMap) { 23 | compressedString = compressedString + key + value; 24 | } 25 | 26 | console.log(compressedString); 27 | 28 | return compressedString.length < string.length ? compressedString : string; 29 | } 30 | 31 | compression("aabcccccaaa"); 32 | -------------------------------------------------------------------------------- /transform-practice.js: -------------------------------------------------------------------------------- 1 | function formatSeatData(data) { 2 | const seatsByRoom = {}; 3 | data.map(ticket => { 4 | const { room, table, seat } = ticket; 5 | 6 | if (!seatsByRoom[room]) { 7 | seatsByRoom[room] = {}; 8 | } 9 | 10 | if (!seatsByRoom[room][table]) { 11 | seatsByRoom[room][table] = []; 12 | } 13 | seatsByRoom[room][table].push(seat); 14 | }); 15 | 16 | const formattedSeats = []; 17 | 18 | Object.keys(seatsByRoom).map(rooms => 19 | Object.keys(rooms) 20 | .map(seats => seatsByRoom[rooms]) 21 | .map(tables => { 22 | for (let [table, seats] of Object.entries(tables)) { 23 | formattedSeats.push( 24 | `Room ${rooms}, Table ${table}, ${ 25 | seats.length > 1 ? "Seats" : "Seat" 26 | } ${seats.join(", ")}` 27 | ); 28 | } 29 | }) 30 | ); 31 | 32 | return formattedSeats; 33 | } 34 | 35 | const data = [ 36 | { room: "A", table: "B", seat: 2 }, 37 | { room: "A", table: "B", seat: 6 }, 38 | { room: "A", table: "B", seat: 10 }, 39 | { room: "B", table: "B", seat: 2 }, 40 | { room: "B", table: "C", seat: 3 } 41 | ]; 42 | 43 | console.log(formatSeatData(data)); 44 | // Output should be formatted as: 45 | // ['room A, Table B, Seats, 2, 6, 10', 46 | // 'room B, Table B, Seat 2', 47 | // 'room B', Table B, Seat 3'] 48 | -------------------------------------------------------------------------------- /trees/BinarySearchTree.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(value) { 3 | this.value = value; 4 | this.left = null; 5 | this.right = null; 6 | } 7 | } 8 | 9 | class BinarySearchTree { 10 | constructor() { 11 | this.root = null; 12 | } 13 | 14 | insert(value) { 15 | const newNode = new Node(value); 16 | 17 | if (this.root == null) { 18 | this.root = newNode; 19 | return this; 20 | } else { 21 | let current = this.root; 22 | while (true) { 23 | if (value == current.value) return undefined; 24 | 25 | if (value < current.value) { 26 | if (current.left == null) { 27 | current.left = newNode; 28 | return this; 29 | } else { 30 | current = current.left; 31 | } 32 | } else { 33 | if (current.right == null) { 34 | current.right = newNode; 35 | return this; 36 | } else { 37 | current = current.right; 38 | } 39 | } 40 | } 41 | } 42 | 43 | // create a new node 44 | // starting at the root 45 | // if there is no root then make the new node the root 46 | // is the value greater than or less than the root? 47 | // keep checking if it's greater than or less than 48 | // once you hit null value in the "right" place put it there! 49 | 50 | // return this - the entire tree at the end/ 51 | } 52 | } 53 | 54 | var tree = new BinarySearchTree(); 55 | console.log(tree.insert(5)); 56 | console.log(tree.insert(19)); 57 | console.log(tree.insert(3)); 58 | console.log(tree.insert(5)); 59 | 60 | // tree.root = new Node(10); 61 | // tree.root.right = new Node(15); 62 | // tree.root.left = new Node(7); 63 | // tree.root.left.right = new Node(9); 64 | -------------------------------------------------------------------------------- /trees/BinarySearchTreeFind.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(value) { 3 | this.value = value; 4 | this.left = null; 5 | this.right = null; 6 | } 7 | } 8 | 9 | class BinarySearchTree { 10 | constructor() { 11 | this.root = null; 12 | } 13 | 14 | find(value) { 15 | if (this.root == null) return false; 16 | 17 | let current = this.root; 18 | let found = false; 19 | 20 | while (current && !found) { 21 | if (current.value === value) { 22 | found = true; 23 | } else if (current.value > value) { 24 | current = current.left; 25 | } else { 26 | current = current.right; 27 | } 28 | } 29 | return current ? current : undefined; 30 | // if (current.value > value) { 31 | // if (current.left) { 32 | // current = current.left; 33 | // } else { 34 | // return false; 35 | // } 36 | // } else if (current.value < value) { 37 | // if (current.right) { 38 | // current = current.right; 39 | // } else { 40 | // return false; 41 | // } 42 | // } 43 | // } 44 | } 45 | 46 | insert(value) { 47 | const newNode = new Node(value); 48 | 49 | if (this.root == null) { 50 | this.root = newNode; 51 | return this; 52 | } else { 53 | let current = this.root; 54 | 55 | while (true) { 56 | if (value == current.value) return undefined; 57 | 58 | if (value < current.value) { 59 | if (current.left == null) { 60 | current.left = newNode; 61 | return this; 62 | } else { 63 | current = current.left; 64 | } 65 | } else { 66 | if (current.right == null) { 67 | current.right = newNode; 68 | return this; 69 | } else { 70 | current = current.right; 71 | } 72 | } 73 | } 74 | } 75 | 76 | // create a new node 77 | // starting at the root 78 | // if there is no root then make the new node the root 79 | // is the value greater than or less than the root? 80 | // keep checking if it's greater than or less than 81 | // once you hit null value in the "right" place put it there! 82 | 83 | // return this - the entire tree at the end/ 84 | } 85 | } 86 | 87 | var tree = new BinarySearchTree(); 88 | console.log(tree.insert(5)); 89 | console.log(tree.insert(19)); 90 | console.log(tree.insert(3)); 91 | console.log(tree.find(19)); 92 | console.log(tree.find(1)); 93 | 94 | // tree.root = new Node(10); 95 | // tree.root.right = new Node(15); 96 | // tree.root.left = new Node(7); 97 | // tree.root.left.right = new Node(9); 98 | -------------------------------------------------------------------------------- /twoSum.js: -------------------------------------------------------------------------------- 1 | // Given an array of integers, return indices of the two numbers such that they add up to a specific target. 2 | 3 | // You may assume that each input would have exactly one solution, and you may not use the same element twice. 4 | 5 | // Example: 6 | 7 | // Given nums = [2, 7, 11, 15], target = 9, 8 | 9 | // Because nums[0] + nums[1] = 2 + 7 = 9, 10 | // return [0, 1]. 11 | 12 | function twoSum(nums, target) { 13 | // add each num to a map with its index 14 | // for each one determine if its counterpart exists 15 | // ifso return those two numbers 16 | 17 | const numMap = new Map(); 18 | 19 | for (index in nums) { 20 | const value = nums[index]; 21 | const inverseNumber = target - value; 22 | 23 | if (numMap.has(value)) { 24 | numMap.set(value, numMap.get(value).concat(index)); 25 | } else { 26 | numMap.set(value, [index]); 27 | } 28 | 29 | if (numMap.has(inverseNumber)) { 30 | if ( 31 | (inverseNumber == value && numMap.get(value).length >= 2) || 32 | inverseNumber != value 33 | ) { 34 | return [numMap.get(inverseNumber)[0], index]; 35 | } 36 | } 37 | } 38 | } 39 | 40 | console.log(twoSum([2, 7, 11, 15], 9)); // EXPECT to equal [O,1 ]] 41 | console.log(twoSum([3, 3], 6)); 42 | -------------------------------------------------------------------------------- /uncommonWordsFromTwoSentences.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} A 3 | * @param {string} B 4 | * @return {string[]} 5 | * source: LeetCode: https://leetcode.com/problems/uncommon-words-from-two-sentences/ 6 | */ 7 | 8 | var addWordsToMap = function(map, sentence) { 9 | const words = sentence.split(" "); 10 | for (word of words) { 11 | if (!map.has(word)) { 12 | map.set(word, 1); 13 | } else { 14 | map.set(word, map.get(word) + 1); 15 | } 16 | } 17 | }; 18 | 19 | var uncommonFromSentences = function(A, B) { 20 | const seenWords = new Map(); 21 | 22 | addWordsToMap(seenWords, A); 23 | addWordsToMap(seenWords, B); 24 | 25 | const uniqueWords = []; 26 | 27 | seenWords.forEach((value, key) => { 28 | if (value === 1) { 29 | uniqueWords.push(key); 30 | } 31 | }); 32 | 33 | return uniqueWords; 34 | }; 35 | 36 | const A = "this apple is sweet"; 37 | const B = "this apple is sour"; 38 | 39 | console.log(uncommonFromSentences(A, B)); 40 | -------------------------------------------------------------------------------- /urlify.js: -------------------------------------------------------------------------------- 1 | // URLify: Write a method to replace all spaces in a string with 2 | // '%20: You may assume that the string has sufficient space at the 3 | // end to hold the additional characters, and that you are given the 4 | // "true" length of the string. (Note: If implementing in Java, 5 | // please use a character array so that you can perform this operation 6 | // in place.) 7 | 8 | function urlify(input) { 9 | const formattedUrl = input.trim().replace(/ /g, "%20"); 10 | console.log(formattedUrl); 11 | return formattedUrl; 12 | } 13 | 14 | urlify("he llo "); 15 | urlify("Mr John Smith "); 16 | -------------------------------------------------------------------------------- /validAnagram.js: -------------------------------------------------------------------------------- 1 | function validAnagram(first, second) { 2 | if (first.length != second.length) { 3 | return false; 4 | } 5 | 6 | const frequencies = {}; 7 | 8 | for (let letter of first) { 9 | frequencies[letter] = frequencies[letter] + 1 || 1; 10 | } 11 | 12 | for (let letter of second) { 13 | if (frequencies[letter]) { 14 | frequencies[letter] = frequencies[letter] - 1; 15 | } else { 16 | return false; 17 | } 18 | } 19 | 20 | return true; 21 | // takei n two words 22 | // add each lettr of word to an object 23 | //then check if each letter exists in same frequency in the second object. 24 | // add whatever parameters you deem necessary - good luck! 25 | } 26 | -------------------------------------------------------------------------------- /writeSafeGet.js: -------------------------------------------------------------------------------- 1 | function safeGet(obj, selectors, defaultValue) { 2 | if (typeof selectors === "string") { 3 | selectors = selectors.split("."); 4 | } 5 | 6 | const selector = selectors.reduce((acc, value) => { 7 | return acc[value]; 8 | }, obj); 9 | 10 | if (typeof selector !== "undefined") { 11 | return selector; 12 | } 13 | 14 | return defaultValue; 15 | } 16 | 17 | let obj = { 18 | location: { 19 | state: { 20 | city: false 21 | } 22 | }, 23 | hello: { 24 | firstName: "Monica" 25 | } 26 | }; 27 | 28 | console.log(safeGet(obj, ["location", "state", "city"])); //false 29 | console.log(safeGet(obj, "location.state.city")); //false 30 | console.log(safeGet(obj, "name.firstName")); //"Monica" 31 | console.log(safeGet(obj, "name.world", "World")); // "World" 32 | console.log(safeGet(obj, "name.world")); // undefined 33 | --------------------------------------------------------------------------------