├── .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 => `