├── .gitignore ├── README.md ├── curriculum ├── 01-big-o │ └── anagrams.js ├── 02-stacks │ ├── balancedPairings.js │ └── convertToBinary.js ├── 03-queues │ └── hotPotato.js ├── 04-deque │ └── palindrome.js ├── algorithms-2018-08-outline.pdf ├── questions │ └── grep.js └── readme.md ├── interviewcake ├── arrays │ ├── 05-makeChange.js │ ├── 12-orderedSet.js │ ├── 13-rotateWords.js │ ├── 26-reverse-in-place.js │ ├── mergeRanges.js │ ├── mergeSortedArrays.js │ ├── reverseWords.js │ └── shuffledDeck.js ├── greedy │ ├── appleStock.js │ ├── highestProductOf3.js │ └── productOfOtherNumbers.js ├── hashTables │ ├── checkPalindrome.js │ ├── duplicateFiles.js │ ├── inflight-entertainment.js │ ├── inflightEntertainment.js │ ├── topScores.js │ └── wordCloud.js ├── readme.md ├── recursion │ └── allPermutations.js ├── searchingSortingLogarithms │ ├── findRepeat.js │ └── findRotationPoint.js └── treesGraphs │ ├── balancedBinaryTree.js │ └── validateBST.js ├── rithmschool ├── algorithms │ ├── binarySearch.js │ ├── insertionSort.js │ └── selectionSort.js ├── data_structures │ ├── Dictionary.js │ ├── HashTable.js │ ├── LinkedList.js │ └── Set.js ├── dynamic-programming.js ├── exercises.js ├── readme.md ├── recursion.js └── searching-algorithms.js ├── sql ├── khan-academ-sql │ ├── 01-sql-queries.sql │ └── 02-relational-queries.sql └── udemy-mysql-bootcamp │ ├── 01-firstActivity.sql │ ├── 02-creating-databases.sql │ ├── 03-inserting-data.sql │ ├── 04-crud.sql │ ├── 05-crud-challenges.sql │ └── 06-string-functions.sql └── udemy-interview-bootcamp-course ├── 01_string_reversal.js ├── 02_palindromes.js ├── 03_integer_reversal.js ├── 04_max_chars.js ├── 05_fizzbuzz.js ├── 06_array_chunking.js ├── 07_anagrams.js ├── 08_capitalize.js ├── 09_steps.js ├── 10_pyramids.js ├── 11_vowels.js ├── 12_spiral_matrix.js ├── 13_fib.js ├── 14_weave.js ├── 15_qfroms.js ├── 16_midpoint.js ├── 17_circular.js ├── 18_from_last.js ├── 19_level_width.js ├── 20_validate_bst.js ├── 21_eventing_system.js ├── README.md ├── data_structures ├── binary_search_tree.js ├── linked_list.js ├── queue.js ├── stack.js └── trees.js └── sorting_algorithms.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Coding Interviews 2 | 3 | - [**The 2 types of software engineering interviews and how to prepare for them**](https://employbl.com/blog/2-types-of-software-engineer-interviews) 4 | 5 | ## Side Projects 6 | 7 | - [Indie Hackers](https://www.indiehackers.com/) 8 | 9 | - [How to build a startup — without quitting your day job](https://www.indiehackers.com/@aytekin/how-to-build-a-startup-without-quitting-your-day-job-d9d1176709) 10 | 11 | - [How to Talk About Your Side Projects](https://medium.freecodecamp.org/how-to-talk-about-your-side-projects-18b96f192817) 12 | 13 | ## Data Structures 14 | 15 | - Array 16 | 17 | - Hash Table 18 | 19 | - Linked List 20 | 21 | - Tree / Binary Tree 22 | 23 | - Graph 24 | 25 | - Stack 26 | 27 | - Queue 28 | 29 | - :octocat: **thejameskyle/itsy-bitsy-data-structures** - All the things you didn't know you wanted to know about data structures - https://github.com/thejameskyle/itsy-bitsy-data-structures 30 | 31 | ## Searching and Sorting 32 | 33 | - Binary Search 34 | 35 | - Breadth First Search (BFS) 36 | 37 | - Depth First Search (DFS) 38 | 39 | - Counting Sort 40 | 41 | - Quicksort 42 | 43 | - Merge Sort 44 | 45 | ## Concepts 46 | 47 | - Recursion: [JS interview prep: Recursion](https://tech.io/playgrounds/5422/js-interview-prep-recursion) (has runnable code examples) 48 | 49 | - Dynamic Programming: [Dynamic Programming - Rithm School](https://www.rithmschool.com/courses/javascript-computer-science-fundamentals/dynamic-programming), [video](https://www.youtube.com/watch?v=W2ote4jCuYw) 50 | 51 | - Greedy Algorithm 52 | 53 | - Sliding Window 54 | 55 | - Divide and Conquer 56 | 57 | - Big-O Analysis (time complexity, space complexity): [Khan Academy](https://www.khanacademy.org/computing/computer-science/algorithms/asymptotic-notation/a/big-o-notation), [video](https://www.youtube.com/watch?v=D6xkbGLQesk), [MIT](http://web.mit.edu/16.070/www/lecture/big_o.pdf) 58 | 59 | ## Learning Guides 60 | 61 | - [Grokking Algorithms](https://livebook.manning.com/book/grokking-algorithms/) - Free book designed to be easy to follow explaining common computer science algorithms. 62 | 63 | - **Pathrise** - https://www.pathrise.com/guides/tags/swe/ - Compiled list of guides to help you find a software engineering job. 64 | 65 | - **HackerRank Interview Prep Kit** - https://www.hackerrank.com/interview/interview-preparation-kit - Curated list of exercises from the HackerRank team organized around key concepts you'll need to know. 66 | 67 | - **Rithm School Computer Science Fundamentals with JavaScript** - https://www.rithmschool.com/courses/javascript-computer-science-fundamentals - I've been following along with some of this as I don't have a comp sci degree. They explain the concepts and then point you to additional resources for learning the material (like youtub videos and specific codewars problems) Very helpful. 68 | 69 | - **Coderbyte** - https://coderbyte.com/challenges/?a=true - Lots of programming challenges, access 10 for free otherwise $30 per month 70 | 71 | - :octocat: **yangshun/tech-interview-handbook** - https://github.com/yangshun/tech-interview-handbook 4k+ ⭐ repo with helpful non-technical tips. Additionally has section covering Algorithm, Front End and System Design questions 72 | 73 | - :octocat: **mr-mig/every-programmer-should-know** - https://github.com/mr-mig/every-programmer-should-know - Don't let the title scare you. This repo covers at a high level things ranging from *Career Tips* to *Data Structures*, *Security*, *Architecture* and *Algorithms*. It's a lot but can be helpful to overview concepts and find new things to learn 74 | 75 | - :octocat: **jwasham/google-interview-university** - https://github.com/jwasham/google-interview-university#final-review - One man's somewhat crazy task to become a google software engineer. 48k+ stars. I believe he ended up working at Amazon. go figure 76 | 77 | - **30 second interview questions** - https://github.com/fejes713/30-seconds-of-interviews - A list and website of common interview questions you're bound to encounter during tricky JS interviews. 78 | 79 | ## Finding companies to apply to 80 | 81 | - **https://employbl.com/companies** - Employbl is a directory of tech companies and startups in the Bay Area. Find companies by type or location, upload your resume and find a company right for you :) 82 | 83 | - **https://whoishiring.io/** - Most impressive job site aggregator I've ever seen in my life. Scrapes all the boards and has a map of where every company is located. 84 | 85 | - **https://huntr.co/** - Tool for keeping your applications and search organized on a Trello-style board. they also have a chrome extension for quickly adding jobs from various sources. 86 | 87 | - **https://breezy.hr** - I used this one as a recruiter. It is actually built for HR departments but has a chrome extension and can be helpful for adding people and specific individuals you're reaching out to. This way you remember to follow up and can find like-minded people. One catch is that you need a custom email address like @your-domain.com. Signing up with your gmail account won't work. 88 | 89 | - **https://betalist.com/jobs/collections** - companies and jobs grouped by category like *female led startup* or *decentralize all the things* for blockchain related jobs. 90 | 91 | - :octocat: **https://github.com/connor11528/sf-companies** - shameless plug here. I've got another repo going with companies located in downtown San Francisco. The data is available as a CSV file and includes company addresses. 92 | 93 | ## Services 94 | 95 | - **Interview Cake** - https://www.interviewcake.com/ - Interview Cake is a thoroughly documented site on programming interviews and concepts. It can be expensive for the year membership but if you're serious about buckling down to learn the fundamentals can be worth it. They also offer a money-back gaurantee. 96 | 97 | - **Daily Coding Questions** - https://dailycodingproblem.com/ - Coding question emailed to you everyday for free. If you want the answer emailed to you the following day it's $8/month. 98 | 99 | - **exercism** - https://exercism.io/ - Level up your programming skills with 2,629 exercises across 48 languages, and insightful discussion with our dedicated team of welcoming mentors. Exercism is 100% free forever. 100 | 101 | - **codewars** - https://www.codewars.com/ - Codewars has thousands of questions generated by the community. You'll never run out of practice problems. They're organized by difficulty, concept and programming language. 102 | 103 | - **codesignal** - https://codesignal.com/ - Really great user interface and user experience. I like the gamification and points system they have going on. 104 | 105 | - **Irfan Baqui: ace coding interviews** - https://www.irfanbaqui.com/coding-interview-prep/ - get one free problem to practice each week and get the solution next week 106 | 107 | - **interviewing.io** - https://interviewing.io/ - Anonymously practice coding interviews with engineers from prominent tech companies. 108 | 109 | - **Pramp** - https://www.pramp.com/ref/gt7 - Real practice with *actual* engineers. Book a time and practice interviewing with real human beings 110 | 111 | - **LeetCode** - https://leetcode.com/ - Pick from an expanding library of more than 190 questions, code and submit your solution to see if you have solved it correctly. 112 | 113 | - **Coderbyte** - https://coderbyte.com/challenges/?a=true - Lots of programming challenges, access 10 for free otherwise $30 per month 114 | 115 | - **HackerRank** - https://www.hackerrank.com/domains - Very popular platform for practicing coding questions. HackerRank is used by companies to evaluate candidates also 116 | 117 | - **InterviewBit** - https://www.interviewbit.com/ - Practice Coding Interview Questions. Give us time and we get you the job you deserve. 118 | 119 | - **Codility** - https://codility.com/programmers/ - Become a better programmer. Develop your coding skills with our lessons. Take part in our challenges. 120 | 121 | - **Codility Solutions** - https://www.martinkysel.com/codility-solutions/ - One engineer's solutions to the codility.com problem sets. 122 | 123 | - **Testdome** - https://www.testdome.com/Tests - Get certified and prove your knowledge 124 | to potential employers. Score well on one of our public tests, and you will get a free certificate of achievement. 125 | 126 | - **CodeEval** - https://www.codeeval.com/ - Find out how you rate against top coders. Unlock awesome startup jobs and hacker deals. 127 | 128 | - **Outco.io** - https://outco.io/ - 1 month interview prep bootcamp in San Francisco 129 | 130 | - **Meetapro** - https://meetapro.com/utm_source=gitcsfundamentals - an Airbnb-style mock interview platform. Mock interviews with top FAANG engineers. 131 | 132 | - **Codemia** - https://codemia.io/?utm_source=gitcsfundamentals - A platform for practicing system design problems like the way you practice algorithms and data structure on Leetcode. 133 | 134 | ## Javascript 135 | 136 | - :octocat: **amilajack/js-algorithms** - https://github.com/amilajack/js-algorithms - A collection of algorithms written in javascript 137 | 138 | - :octocat: **benoitvallon/computer-science-in-javascript** - https://github.com/benoitvallon/computer-science-in-javascript - Computer science reimplemented in JavaScript 139 | 140 | - :octocat: **lukehoban/es6features** - https://github.com/lukehoban/es6features - Overview of ECMAScript 6 features (21k+ stars) 141 | 142 | - **Khan Academy Algorithm Course** - https://www.khanacademy.org/computing/computer-science/algorithms 143 | 144 | - :octocat: **romyilano/Learning-JavaScript-Data-Structures-and-Algorithms** - https://github.com/romyilano/Learning-JavaScript-Data-Structures-and-Algorithms - Solutions to Learning JavaScript Data Structures and Algorithms by Loiane Groner ([book pdf](https://www.packtpub.com/application-development/learning-javascript-data-structures-and-algorithms)) 145 | 146 | - :octocat: **nzakas/computer-science-in-javascript** - https://github.com/nzakas/computer-science-in-javascript - Collection of classic computer science paradigms, algorithms, and approaches written in JavaScript. 147 | 148 | - :octocat: **JacopoDaeli/algorithmic-challenges** - https://github.com/JacopoDaeli/algorithmic-challenges - Solutions to algorithmic challenges written in C, Python, Java and JavaScript. 149 | 150 | - **Hack Reactor Prep** - http://www.hackreactor.com/prep-programs/ - free course and practice problems from Hack Reactor 151 | 152 | - **JS: Interview Algorithm** - http://www.thatjsdude.com/interview/js1.html - JS: Interview Algorithms questions and solutions 153 | 154 | ## PHP 155 | 156 | - **Efficient data structures for PHP 7** - https://medium.com/@rtheunissen/efficient-data-structures-for-php-7-9dda7af674cd - Medium article about implementing data structures with modern PHP 157 | 158 | - **30-seconds-of-php-code** - https://github.com/appzcoder/30-seconds-of-php-code - A curated collection of useful PHP snippets that you can understand in 30 seconds or less. 159 | 160 | - **SOLID Principles in PHP** - https://laracasts.com/series/solid-principles-in-php - SOLID represents a series of guidelines that developers can use to, if done well, simplify and clarify their code. 161 | 162 | - **Object Oriented Bootcamp in PHP** - https://laracasts.com/series/object-oriented-bootcamp-in-php - covers fundamentals of OOP in PHP, including tricky concepts like difference between Interfaces and Abstract Classes 163 | 164 | ## SQL 165 | 166 | - **Khan Academy SQL course** - https://www.khanacademy.org/computing/computer-programming/sql - Great course covering SQL principles. Highly recommend. 167 | 168 | - **Udemy MySQL Bootcamp** - https://www.udemy.com/the-ultimate-mysql-bootcamp-go-from-sql-beginner-to-expert/ - Course by ex-Galvanize instructor. beginner to expert. 169 | 170 | ## Laravel 171 | 172 | - **Diving Laravel** - https://divinglaravel.com/ - A deep dive into laravel core, packages, and technologies by [@themsaid](https://github.com/themsaid) 173 | 174 | - **Advanced Eloquent** - https://laracasts.com/series/advanced-eloquent - Sure, you've learned the essentials of using Eloquent in your applications, but do you really understand what's going on under the hood? 175 | 176 | - :octocat: **unicodeveloper/laravel-exam** - https://github.com/unicodeveloper/laravel-exam - A Laravel exam with questions from beginner to expert curated by [@unicodeveloper](https://github.com/unicodeveloper) 177 | 178 | ## Git 179 | 180 | - **Git flow** - https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow - a git workflow that some companies follow to manage their deployments. 181 | 182 | - **Git Game** - https://www.git-game.com/ - The git-game is a terminal based game that teaches both new and advances users some pretty cool features of the git scm (source control management) system. 183 | 184 | ## Webpack 185 | 186 | - **webpack: The Core Concepts** - https://webpack.academy/p/the-core-concepts - less than an hour long course on webpack fundamentals from core team member 187 | 188 | ## Python 189 | 190 | - Algosaurus: http://algosaur.us/data-structures-basics/ 191 | - Programiz PRO: https://programiz.pro/learn/master-dsa-with-python - offers a complete roadmap of DSA using Python 192 | 193 | 194 | ## Ruby 195 | 196 | - :octocat: **Haseeb-Qureshi/Algorithms-Study-Group** - https://github.com/Haseeb-Qureshi/Algorithms-Study-Group 197 | 198 | ## Books 199 | 200 | - **Learning JavaScript Data Structures and Algorithms** - https://github.com/loiane/javascript-datastructures-algorithms 201 | 202 | - **Cracking the Coding Interview** ([pdf](https://inspirit.net.in/books/placements/Cracking%20the%20Coding%20Interview.pdf), [pdf alt](https://github.com/navyifanr/Cracking_the_coding_interview/blob/master/Cracking%20the%20coding%20interview-ctci.pdf)) 203 | 204 | - :octocat: **amilajack/reading** - list of computer science readings with book pdfs - https://github.com/amilajack/reading - Reading List: 205 | 206 | ## Algorithm visualization 207 | 208 | - Visualgo: https://visualgo.net/en 209 | 210 | ## Articles 211 | 212 | - I just got a developer job at Facebook. Here’s how I prepped for my interviews: https://medium.freecodecamp.org/software-engineering-interviews-744380f4f2af 213 | 214 | - How to write a great résumé for software engineers: https://medium.freecodecamp.org/how-to-write-a-great-resume-for-software-engineers-75d514dd8322 215 | 216 | - Why You Don’t Deserve That Dream Developer Job: https://codeburst.io/why-you-dont-deserve-that-dream-developer-job-60d5e5adb8d7 217 | 218 | - Top 8 Mistakes to avoid in Technical Interviews According to Data: https://blog.pramp.com/top-8-mistakes-in-technical-interviews-according-to-data-27d2572bda1f 219 | 220 | - Resource List: Getting hired at technology startups: https://notes.breakoutlist.com/resource-list-getting-hired-at-technology-startups-9f981518a0d9 221 | 222 | - Resource List: Figuring out what you want / your “purpose”: https://notes.breakoutlist.com/resource-list-figuring-out-what-you-want-your-purpose-b7af89e2ba7 223 | 224 | - Triplebyte blog, How to pass a programming interview: http://blog.triplebyte.com/how-to-pass-a-programming-interview 225 | 226 | - Jeff Atwood, How to Hire a Programmer: https://blog.codinghorror.com/how-to-hire-a-programmer/ 227 | 228 | - Joel On Software, The Guerrilla Guide to Interviewing (version 3.0): https://www.joelonsoftware.com/2006/10/25/the-guerrilla-guide-to-interviewing-version-30/ 229 | 230 | - Coding Interview Tips, How to get better at technical interviews without practicing: https://www.interviewcake.com/coding-interview-tips 231 | 232 | - software engineer resume template: https://notes.breakoutlist.com/best-engineer-resume-template-uses-latex-14380b4a239f 233 | 234 | - Guide to interviewing your future manager before deciding where to work: https://notes.breakoutlist.com/guide-to-interviewing-your-future-manager-before-deciding-where-to-work-3b2eb3326793 235 | 236 | ## More Questions 237 | 238 | - **50 Coding Interview Questions** - https://www.byte-by-byte.com/wp-content/uploads/2019/01/50-Coding-Interview-Questions.pdf - "In this guide, I’ve organized all of the interview questions we’ve ever covered on Byte by Byte into a convenient PDF for you to reference whenever you like. Over the years, I’ve been careful to select only problems that are directly relevant to your interviews. This guide combines them all in one place and is completely free for you to download." 239 | 240 | - **500 Data Structures and Algorithms practice problems and their solutions** - https://techiedelight.quora.com/500-Data-Structures-and-Algorithms-practice-problems-and-their-solutions - these are good because they are grouped by topic such as array, BST, Dynamic Programming etc 241 | 242 | - **Project Euler** - https://projecteuler.net/archives - The classic 243 | 244 | - **Epic List of Interview Questions** - http://katemats.com/interview-questions/ - a list of software engineer skills or areas that can be tested and evaluated in an interview context 245 | 246 | - :octocat: **MaximAbramchuck/awesome-interview-questions** - https://github.com/MaximAbramchuck/awesome-interview-questions - A curated awesome list of lists of interview questions. 247 | 248 | ## Technical blogs 💸 249 | 250 | This is tangentially related to interviews. Below is a list of companies that feature blog posts from guest authors. Blogging and teaching others can be a powerful way to comprehend new material, fine tune your writing skills, gain exposure and potentially even make money! If you have a technical blog open to new contributors please [submit a PR](https://github.com/connor11528/coding-interviews/pulls) 251 | 252 | - [Scotch.io](https://scotch.io/write-for-us) - this has been my go to source for web development tutorials for years. Code on the rocks 253 | 254 | - [Snipcart](https://snipcart.com/guest-posting) - company interested in Vue.js, eCommerce, Javascript and the JAMstack. There is some really great writing and code samples on here 255 | 256 | - [JScrambler](https://blog.jscrambler.com/) - company interested in Javascript tutorials. I wrote a post for them on using Vue.js and Vuelog to make a static blogging app. Check out the full article [here](https://blog.jscrambler.com/generate-a-static-markdown-blog-using-vuelog/) 257 | 258 | ## Words of wisdom 259 | 260 | [Charlie Munger](https://www.cnbc.com/2017/08/16/warren-buffetts-partner-charlie-munger-has-3-rules-for-a-career.html), Warren Buffett’s partner, has three rules for a career: 261 | 262 | 1) Don’t sell anything you wouldn’t buy yourself 263 | 2) Don’t work for anyone you don’t respect and admire 264 | 3) Work only with people you enjoy 265 | 266 | -------------------------------------------------------------------------------- /curriculum/01-big-o/anagrams.js: -------------------------------------------------------------------------------- 1 | // Wite a program to detect if a string is an anagram. 2 | 3 | // anagram: a word, phrase, or name formed by rearranging the letters of another, such as cinema, formed from iceman 4 | 5 | // Problem source: https://bradfieldcs.com/algos/analysis/an-anagram-detection-example/ 6 | 7 | 8 | // (On^2) solution 9 | function anagramCheckingOff (string1, string2) { 10 | if (string1.length !== string2.length) return false 11 | 12 | const string2ToCheckOff = string2.split('') 13 | 14 | for (let i = 0; i < string1.length; i++) { 15 | let letterFound = false 16 | for (let j = 0; j < string2ToCheckOff.length; j++) { 17 | if (string1[i] === string2ToCheckOff[j]) { 18 | string2ToCheckOff[j] = null 19 | letterFound = true 20 | break 21 | } 22 | } 23 | if (!letterFound) return false 24 | } 25 | 26 | return true 27 | } 28 | 29 | // either O(n^2) or O(n log n) depending on the sorting algorithm 30 | // most likely O(n log n), depends on browser 31 | function anagramSortAndCompare (string1, string2) { 32 | if (string1.length !== string2.length) return false 33 | 34 | const sortedString1 = string1.split('').sort() 35 | const sortedString2 = string2.split('').sort() 36 | 37 | for (let i = 0; i < sortedString1.length; i++) { 38 | if (sortedString1[i] !== sortedString2[i]) return false 39 | } 40 | 41 | return true 42 | } 43 | 44 | // O(n) solution 45 | function anagramCountCompare (string1, string2) { 46 | 47 | function getLetterPosition (letter) { 48 | return letter.charCodeAt() - 'a'.charCodeAt() 49 | } 50 | 51 | const string1LetterCounts = new Array(26).fill(0) 52 | const string2LetterCounts = new Array(26).fill(0) 53 | 54 | for (let i = 0; i < string1.length; i++) { 55 | const letterPosition = getLetterPosition(string1[i]) 56 | string1LetterCounts[letterPosition]++ 57 | } 58 | 59 | for (let i = 0; i < string2.length; i++) { 60 | const letterPosition = getLetterPosition(string2[i]) 61 | string2LetterCounts[letterPosition]++ 62 | } 63 | 64 | for (let i = 0; i < string1LetterCounts.length; i++) { 65 | if (string1LetterCounts[i] !== string2LetterCounts[i]) { 66 | return false 67 | } 68 | } 69 | 70 | return true 71 | } 72 | 73 | // O(n) solution 74 | // would need to understand time complexity of Array.reduce method 75 | // this solution does take up more space to store the 26 character alphabet 76 | function anagramCountCompareWithReduce (string1, string2) { 77 | 78 | function letterCountReducer (letterCounts, letter) { 79 | if (letterCounts[letter]) { 80 | letterCounts[letter]++ 81 | } else { 82 | letterCounts[letter] = 1 83 | } 84 | return letterCounts 85 | } 86 | 87 | const string1LetterCounts = string1.split('').reduce(letterCountReducer, {}) 88 | const string2LetterCounts = string2.split('').reduce(letterCountReducer, {}) 89 | 90 | 91 | for (let letter in string1LetterCounts) { 92 | if (string1LetterCounts[letter] !== string2LetterCounts[letter]) { 93 | return false 94 | } 95 | } 96 | 97 | return string1.length === string2.length 98 | } 99 | 100 | 101 | -------------------------------------------------------------------------------- /curriculum/02-stacks/balancedPairings.js: -------------------------------------------------------------------------------- 1 | // write an algorithm that will read a string of parentheses from left to right and decide whether the symbols are balanced 2 | 3 | function balancedParentheses(str) { 4 | let stack = []; 5 | const OPENING = '('; 6 | const CLOSING = ')'; 7 | 8 | for(let char of str){ 9 | if(char === OPENING) { 10 | stack.push(char); 11 | } else if(char === CLOSING) { 12 | const removedChar = stack.pop(); 13 | 14 | if(typeof removedChar === 'undefined'){ 15 | return false; 16 | } 17 | } 18 | } 19 | 20 | return (stack.length === 0); 21 | } 22 | 23 | // console.log(balancedParentheses('(()()()())')); // true 24 | // console.log(balancedParentheses('((((((())')); // false 25 | // console.log(balancedParentheses('((((((())')); // false 26 | // console.log(balancedParentheses('()))')); // false 27 | // console.log(balancedParentheses('(()()(()')); // false 28 | 29 | const PAIRINGS = { 30 | '(' : ')', 31 | '[' : ']', 32 | '{' : '}' 33 | }; 34 | 35 | function isBalanced(str) { 36 | let stack = []; 37 | const openings = Object.keys(PAIRINGS); 38 | const endings = Object.values(PAIRINGS); 39 | 40 | for(let char of str) { 41 | if(openings.includes(char)) { 42 | stack.push(char); 43 | } 44 | 45 | if(endings.includes(char)) { 46 | const removedChar = stack.pop(); 47 | 48 | if(typeof removedChar === 'undefined'){ 49 | return false; 50 | } 51 | 52 | if(char !== PAIRINGS[removedChar]){ 53 | return false; 54 | } 55 | } 56 | 57 | } 58 | 59 | return stack.length === 0; 60 | } 61 | 62 | console.log(isBalanced('{ { ( [ ] [ ] ) } ( ) }')); // true 63 | console.log(isBalanced('[ [ { { ( ( ) ) } } ] ]')); // true 64 | console.log(isBalanced('[ ] [ ] [ ] ( ) { }')); // true 65 | console.log(isBalanced('( [ ) ]')); // false 66 | console.log(isBalanced('( ( ( ) ] ) )')); // false 67 | console.log(isBalanced('[ { ( ) ]')); // false 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /curriculum/02-stacks/convertToBinary.js: -------------------------------------------------------------------------------- 1 | // todo 2 | // https://github.com/connor11528/binToDecAndHex 3 | // https://bradfieldcs.com/algos/stacks/converting-number-bases/ 4 | 5 | function convertToBinary(decimal) { 6 | 7 | } 8 | 9 | function convertToBase(decimal, base) { 10 | 11 | } -------------------------------------------------------------------------------- /curriculum/03-queues/hotPotato.js: -------------------------------------------------------------------------------- 1 | // Each person is eliminated when they get the potato. 2 | // Last person left is winner. 3 | // If num is greater than people in list, start at front. 4 | 5 | function hotPotato(nameList, num) { 6 | // todo 7 | 8 | } 9 | 10 | 11 | console.log(hotPotato(['Bill', 'David', 'Susan', 'Jane', 'Kent', 'Brad'], 9)); // 'David' -------------------------------------------------------------------------------- /curriculum/04-deque/palindrome.js: -------------------------------------------------------------------------------- 1 | 2 | // Palindrome is string that reads same forwards and backwards 3 | // radar, toot and madam are palindromes. 4 | 5 | function palindromeCheck(str) { 6 | let deque = str.split(''); 7 | 8 | while(deque.length > 1) { 9 | const last = deque.pop(); 10 | const first = deque.shift(); 11 | 12 | if(first !== last) { 13 | return false; 14 | } 15 | } 16 | 17 | return true; 18 | } 19 | 20 | console.log(palindromeCheck('radar')); // true 21 | console.log(palindromeCheck('toot')); // true 22 | console.log(palindromeCheck('madam')); // true 23 | console.log(palindromeCheck('madams')); // false 24 | console.log(palindromeCheck('palindrome')); // false -------------------------------------------------------------------------------- /curriculum/algorithms-2018-08-outline.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connor11528/cs-fundamentals/c4a4bb0e11813702b82f2eedd710299187b69428/curriculum/algorithms-2018-08-outline.pdf -------------------------------------------------------------------------------- /curriculum/questions/grep.js: -------------------------------------------------------------------------------- 1 | /* 2 | function int[] grep(string haystack, string needle) 3 | haystack = "aaabbbccccbbccbbbbbcdef" 4 | needle = "bbb" 5 | [3,14,15,16] 6 | */ 7 | 8 | // Time complexity: m O(n*m) 9 | // where n is haystack length and m is needle length 10 | function grep(haystack, needle) { 11 | const haystackArr = haystack.split(''); 12 | let needleLength = needle.length; 13 | let result = []; 14 | 15 | for(let i = 0; i < haystackArr.length; i++) { 16 | let testNeedle = haystack.substr(i, needleLength); 17 | 18 | if(testNeedle === needle){ 19 | result.push(i); 20 | } 21 | } 22 | 23 | return result; 24 | } 25 | 26 | console.log(grep("aaabbbccccbbccbbbbbcdef", "bbb")) -------------------------------------------------------------------------------- /curriculum/readme.md: -------------------------------------------------------------------------------- 1 | # Interview Prep Curriculum 2 | 3 | This is meant to shore up computer science fundamentals for the self taught programmer. 4 | 5 | ## 0. Resources 6 | 7 | - Bradfield School of Computer Science [Practical Algorithms and Data Structures](https://bradfieldcs.com/algos/) 8 | 9 | - Stephen Grider's [Coding Interview Bootcamp on Udemy](https://www.udemy.com/coding-interview-bootcamp-algorithms-and-data-structure/) 10 | 11 | - Rithm School [Computer Science Fundamentals with Javascript](https://www.rithmschool.com/courses/javascript-computer-science-fundamentals) 12 | 13 | - Khan Academy [Algorithms course](https://www.khanacademy.org/computing/computer-science/algorithms) 14 | 15 | ## 1. Time and space complexity: Big O Notation 16 | 17 | **Courses and Reading** 18 | 19 | - Read "Analysis" section of **Practical Algorithms and Data Structures** 20 | 21 | ![constant, logarithmic, linear, log linear, quadratic, cubic, exponential](https://i.imgur.com/Y8UqTmX.png) 22 | 23 | ![graph of algo performance](https://i.imgur.com/jhsvwNF.png) 24 | 25 | - Review time complexity of [anagram solutions](01-big-o/anagrams.js) 26 | 27 | - (todo) Complete "Introduction to Big O Notation" from **Computer Science Fundamentals with Javascript** 28 | 29 | - (todo) Complete "Asymptotic notation" section of **Algorithms course** 30 | 31 | ## 2. Data Structures I 32 | 33 | ### Stacks 34 | 35 | - "Stack 'Em Up With Stacks" section of **Udemy course** ([stack implementation](../udemy-interview-bootcamp-course/data_structures/stack.js)) 36 | 37 | - Read "Stacks" section of **Practical Algorithms and Data Structures** 38 | 39 | ``` 40 | Abstract Data Type of a Stack: 41 | 42 | - Stack() creates a new, empty stack 43 | - push(item) adds the given item to the top of the stack and returns nothing 44 | - pop() removes and returns the top item from the stack 45 | - peek() returns the top item from the stack but doesn’t remove it (the stack isn’t modified) 46 | - is_empty() returns a boolean representing whether the stack is empty 47 | - size() returns the number of items on the stack as an integer 48 | ``` 49 | 50 | - Review [balancedPairings](02-stacks/balancedPairings.js) and [convertToBinary](02-stacks/convertToBinary.js). 51 | 52 | ### Queues 53 | 54 | - Read "Queues" section of **Practical Algorithms and Data Structures** 55 | 56 | - "The Queue" and "Underwater Queue Weaving" section of **Udemy course** ([queue implementation](../udemy-interview-bootcamp-course/data_structures/queue.js)) 57 | 58 | ``` 59 | Abstract Data Type of a Queue: 60 | 61 | - Queue() creates a new queue that is empty. It needs no parameters and returns an empty queue. 62 | - enqueue(item) adds a new item to the rear of the queue. It needs the item and returns nothing. 63 | - dequeue() removes the front item from the queue. It needs no parameters and returns the item. The queue is modified. 64 | - is_empty() tests to see whether the queue is empty. It needs no parameters and returns a boolean value. 65 | - size() returns the number of items in the queue. It needs no parameters and returns an integer. 66 | ``` 67 | 68 | - Review [hot potato](03-queues/hotPotato.js) 69 | 70 | ### Deques 71 | 72 | - Read "Deques" section of **Practical Algorithms and Data Structures** 73 | 74 | > New items can be added at either the front or the rear. Likewise, existing items can be removed from either end. In a sense, this hybrid linear structure provides all the capabilities of stacks and queues in a single data structure. 75 | 76 | ![](https://bradfieldcs.com/algos/deques/introduction/figures/basic-deque.png) 77 | 78 | - Review [palindrome checker](04-deques/palindrome.js) 79 | 80 | ### Lists 81 | 82 | - Read "Lists" section of **Practical Algorithms and Data Structures** 83 | 84 | > When discussing the list abstract data type, we consider a list to be a collection of items where each item holds a relative position with respect to the others. 85 | 86 | > The members of a list are commonly refered to as nodes. When each node holds a reference to the next node in the list, we call this a **singly linked list**. When each node holds a reference to both the next and previous nodes in the list, we call this a **doubly linked list**. 87 | 88 | > **Linked list traversal** refers to the process of systematically visiting each node in a linked list. 89 | 90 | - "Linked List" section of **Udemy course** ([linked list implementation](../udemy-interview-bootcamp-course/data_structures/linked_list.js)) 91 | 92 | - Review [midpoint](../udemy-interview-bootcamp-course/16_midpoint.js) from **Udemy course** 93 | 94 | ## 3. Recursion 95 | 96 | - Bradfield CS: [Recursion](https://bradfieldcs.com/algos/recursion/introduction/) 97 | 98 | - Rithm School: [Recursion](https://www.rithmschool.com/courses/javascript-computer-science-fundamentals/introduction-to-recursion) 99 | 100 | 101 | ## 4. Searching and Sorting 102 | 103 | - Bradfield CS: [Searching](https://bradfieldcs.com/algos/searching/searching/) 104 | 105 | - Rithm School: [Searching](https://www.rithmschool.com/courses/javascript-computer-science-fundamentals/searching-algorithms), [Sorting](https://www.rithmschool.com/courses/javascript-computer-science-fundamentals/basic-sorting-algorithms), [Intermediate Sorting](https://www.rithmschool.com/courses/javascript-computer-science-fundamentals/intermediate-sorting-algorithms) 106 | 107 | 108 | ## 5. Data Structures II 109 | 110 | ### Trees 111 | 112 | - Bradfield CS: [Trees](https://bradfieldcs.com/algos/trees/introduction/) 113 | 114 | ### Graphs 115 | 116 | - Bradfield CS: [Graphs](https://bradfieldcs.com/algos/graphs/introduction/) 117 | 118 | - Rithm School: [Graphs](https://www.rithmschool.com/courses/javascript-computer-science-fundamentals/introduction-to-graphs) 119 | 120 | ### Hash Map 121 | 122 | - Rithm School: [Hash Map / Hash Table](https://www.rithmschool.com/courses/javascript-computer-science-fundamentals/introduction-to-hash-tables) 123 | 124 | ## 6. Dynamic Programming 125 | 126 | - Rithm School: [Dynamic Programming](https://www.rithmschool.com/courses/javascript-computer-science-fundamentals/dynamic-programming) 127 | 128 | 129 | -------------------------------------------------------------------------------- /interviewcake/arrays/05-makeChange.js: -------------------------------------------------------------------------------- 1 | // dynamic programming question. 2 | 3 | 4 | 5 | // Write a function that, given: 6 | 7 | // an amount of money 8 | // an array of coin denominations 9 | 10 | // computes the number of ways to make the amount of money with coins of the available denominations. 11 | 12 | var amount1 = 4; 13 | var denominations1 = [1,2,3]; 14 | 15 | console.log(makeChange(amount1, denominations1)); 16 | 17 | function makeChange(amount, denominations){ 18 | 19 | 20 | } 21 | 22 | // brute force approach is to see if we can get to amount with repeatedly doing e -------------------------------------------------------------------------------- /interviewcake/arrays/12-orderedSet.js: -------------------------------------------------------------------------------- 1 | 2 | var sorted = [1,2,3,4,5,6,7,8,400]; 3 | console.log(findInOrderedSet(sorted, 69)); 4 | 5 | // binary search 6 | function findInOrderedSet(sorted, num){ 7 | var min = 0; 8 | var max = sorted.length - 1; 9 | var guess; 10 | 11 | while(max >= min){ 12 | guess = Math.floor((max+min)/2); 13 | 14 | if(sorted[guess] == num) return true; 15 | 16 | if(sorted[guess] > num){ 17 | max = guess - 1; 18 | } else if (sorted[guess] < num) { 19 | min = guess + 1; 20 | } 21 | } 22 | 23 | return false; 24 | } 25 | 26 | // brute force would be loop through array 27 | // and check if # is current -------------------------------------------------------------------------------- /interviewcake/arrays/13-rotateWords.js: -------------------------------------------------------------------------------- 1 | var words = [ 2 | 'ptolemaic', 3 | 'retrograde', 4 | 'supplant', 5 | 'undulate', 6 | 'xenoepist', 7 | 'asymptote', // <-- rotates here! 8 | 'babka', 9 | 'banoffee', 10 | 'engender', 11 | 'karpatka', 12 | 'othellolagkage', 13 | ]; 14 | 15 | console.log(rotateWords(words)); 16 | 17 | function rotateWords(wordList){ 18 | var max = wordList.length - 1; 19 | var min = 0; 20 | var guess; 21 | 22 | while(max >= min){ 23 | guess = Math.floor((max+min)/2); 24 | 25 | if(wordList[guess] >wordList[max]) ){ 26 | console.log() 27 | } 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /interviewcake/arrays/26-reverse-in-place.js: -------------------------------------------------------------------------------- 1 | // Write a function to reverse a string in-place 2 | 3 | var string = 'hello'; 4 | console.log(reverseString(string)); // olleh 5 | 6 | // in es6 we can also do [b,a] = [a,b]; 7 | 8 | function reverseString(str){ 9 | var startIndex = 0; 10 | var endIndex = str.length - 1; 11 | var stringArray = str.split(''); 12 | 13 | while(startIndex < endIndex){ 14 | var temp = stringArray[endIndex]; 15 | stringArray[endIndex] = stringArray[startIndex]; 16 | stringArray[startIndex] = temp; 17 | 18 | // ES6 Method: Destructuring 19 | // [stringArray[endIndex], stringArray[startIndex]] = [stringArray[startIndex], stringArray[endIndex]] 20 | 21 | startIndex++; 22 | endIndex--; 23 | } 24 | 25 | return stringArray.join(''); 26 | } -------------------------------------------------------------------------------- /interviewcake/arrays/mergeRanges.js: -------------------------------------------------------------------------------- 1 | // Write a function mergeRanges() that takes an array of multiple meeting time ranges 2 | // and returns an array of condensed ranges. 3 | 4 | const input = [ 5 | { startTime: 0, endTime: 1 }, 6 | { startTime: 3, endTime: 5 }, 7 | { startTime: 4, endTime: 8 }, 8 | { startTime: 10, endTime: 12 }, 9 | { startTime: 9, endTime: 10 }, 10 | ]; 11 | 12 | // Expected output: 13 | // [ 14 | // { startTime: 0, endTime: 1 }, 15 | // { startTime: 3, endTime: 8 }, 16 | // { startTime: 9, endTime: 12 }, 17 | // ] 18 | 19 | 20 | const input2 = [{ startTime: 2, endTime: 4 }, { startTime: 1, endTime: 3 }] 21 | // Expected output2: 22 | //[{ startTime: 1, endTime: 4 }] 23 | 24 | 25 | // Complexity: O(nlgn) time and O(n) space. 26 | function mergeRanges(meetings) { 27 | 28 | 29 | // sorting takes O(nlgn) time 30 | const sortedMeetings = meetings.sort(function(a, b){ 31 | return a.startTime - b.startTime; 32 | }); 33 | 34 | let mergedMeetings = [sortedMeetings[0]]; 35 | 36 | for(let i = 1; i < sortedMeetings.length; i++){ 37 | 38 | const currentMeeting = sortedMeetings[i]; 39 | const lastMergedMeeting = mergedMeetings[mergedMeetings.length - 1]; 40 | 41 | // if meetings overlap use the later of the two as endTime 42 | if(currentMeeting.startTime <= lastMergedMeeting.endTime){ 43 | lastMergedMeeting.endTime = Math.max(lastMergedMeeting.endTime, currentMeeting.endTime); 44 | } else { 45 | // add the current meeting since it doesn't overlap 46 | mergedMeetings.push(currentMeeting); 47 | } 48 | } 49 | 50 | // in the worst case no meetings overlap so we'd take up O(n) space 51 | return mergedMeetings; 52 | } 53 | 54 | console.log(mergeRanges(input)); -------------------------------------------------------------------------------- /interviewcake/arrays/mergeSortedArrays.js: -------------------------------------------------------------------------------- 1 | // Your task is to create a function mergeArrays which take 2 sorted arrays as arguments 2 | // and returns a single array containing all elements from previous 2 arrays including 3 | // repeated elements arranged in a sorted order 4 | 5 | const myArray = [3, 4, 6, 10, 11, 12, 15, 22]; 6 | const alicesArray = [1, 5, 8, 12, 12, 14, 19]; 7 | 8 | console.log(mergeArrays(myArray, alicesArray)); 9 | // logs [1, 3, 4, 5, 6, 8, 10, 11, 12, 14, 15, 19] 10 | 11 | 12 | // O(n) solution 13 | function mergeArrays(array1, array2){ 14 | let result = []; 15 | let index1 = 0; 16 | let index2 = 0; 17 | let resultIndex = 0; 18 | 19 | while(resultIndex < (array1.length + array2.length)){ 20 | 21 | const array1Empty = index1 >= array1.length; 22 | const array2Empty = index2 >= array2.length; 23 | 24 | // check if arrays are empty 25 | if(array1Empty){ 26 | result[resultIndex] = array2[index2]; 27 | index2++; 28 | } else if(array2Empty){ 29 | result[resultIndex] = array1[index1]; 30 | index1++; 31 | 32 | // if not empty push in the smallest element 33 | } else if(array1[index1] < array2[index2]){ 34 | result[resultIndex] = array1[index1]; 35 | index1++; 36 | } else { 37 | result[resultIndex] = array2[index2]; 38 | index2++ 39 | } 40 | 41 | resultIndex++; 42 | 43 | } 44 | 45 | return result; 46 | } 47 | 48 | 49 | // O(n log n) 50 | // Does not take advantage of fact that arrays are already sorted 51 | function mergeInefficient(array1, array2){ 52 | return array1.concat(array2).sort((a, b)=>{ 53 | return a - b; 54 | }) 55 | } 56 | -------------------------------------------------------------------------------- /interviewcake/arrays/reverseWords.js: -------------------------------------------------------------------------------- 1 | // Write a function reverseWords() that takes a message as an array of 2 | // characters and reverses the order of the words in place 3 | 4 | 5 | // O(n) time and O(1) space! 6 | function reverseWords(message){ 7 | let leftIndex = 0; 8 | let rightIndex = message.length - 1; 9 | 10 | // reverse the whole array so we get "laets dnuop ekac" 11 | reverse(message, leftIndex, rightIndex); 12 | 13 | // first word starts at the beginning 14 | let currentWordStart = 0; 15 | 16 | for(let i = 0; i <= message.length; i++){ 17 | 18 | if(i == message.length || message[i] === ' '){ 19 | // reverse the word 20 | reverse(message, currentWordStart, i - 1); 21 | 22 | // move on to the next word 23 | currentWordStart = i + 1; 24 | } 25 | } 26 | } 27 | 28 | // helper function to reverse elements in an array 29 | function reverse(message, leftIndex, rightIndex){ 30 | while (leftIndex < rightIndex) { 31 | 32 | const temp = message[leftIndex]; 33 | message[leftIndex] = message[rightIndex]; 34 | message[rightIndex] = temp; 35 | leftIndex++; 36 | rightIndex--; 37 | } 38 | } 39 | 40 | const message = [ 'c', 'a', 'k', 'e', ' ', 41 | 'p', 'o', 'u', 'n', 'd', ' ', 42 | 's', 't', 'e', 'a', 'l' ]; 43 | 44 | reverseWords(message); 45 | 46 | console.log(message.join('')); // 'steal pound cake' 47 | 48 | 49 | // Lesson: 50 | 51 | // Solve a simpler version of the problem (in this case, reversing the characters instead of the words), 52 | // and see if that gets us closer to a solution for the original problem. 53 | -------------------------------------------------------------------------------- /interviewcake/arrays/shuffledDeck.js: -------------------------------------------------------------------------------- 1 | // To prove this, let's write a function to tell us if a full deck of cards 2 | // shuffledDeck is a single riffle of two other halves half1 and half2. 3 | 4 | // We'll represent a stack of cards as an array of integers in the range 5 | // 1..52 (since there are 52 distinct cards in a deck). 6 | 7 | // O(n^2) 8 | function isSingleRiffle(shuffledDeck, half1, half2){ 9 | if(shuffledDeck.length === 0){ 10 | return true; 11 | } 12 | 13 | if(half1.length && shuffledDeck[0] === half1[0]){ 14 | return isSingleRiffle(shuffledDeck.slice(1), half1.slice(1), half2); 15 | } else if (half2.length && shuffledDeck[0] === half2[0]){ 16 | return isSingleRiffle(shuffledDeck.slice(1), half1, half2.slice(1)); 17 | } else { 18 | return isSingleRiffle([], [], []); 19 | } 20 | 21 | } 22 | 23 | // O(n) time and O(1) space 24 | function isSingleRiffle(shuffledDeck, half1, half2){ 25 | let half1Index = 0; 26 | let half2Index = 0; 27 | 28 | for (let i = 0; i < shuffledDeck.length; i++){ 29 | if(half1Index < half1.length && shuffledDeck[i] === half1[half1Index]){ 30 | half1Index++; 31 | } else if(half2Index < half2.length && shuffledDeck[i] === half2[half2Index]){ 32 | half2Index++; 33 | } else { 34 | return false; 35 | } 36 | } 37 | 38 | return true; 39 | } -------------------------------------------------------------------------------- /interviewcake/greedy/appleStock.js: -------------------------------------------------------------------------------- 1 | // stockPrices: indices are time in minutes past trade open time. 2 | // Values are price in dollars 3 | 4 | // Most profit from one purchase and one sale. 5 | 6 | 7 | const stockPrices = [10, 7, 5, 8, 11, 9]; 8 | 9 | console.log(getMaxProfit(stockPrices)); // Returns 6 (buying for $5 and selling for $11) 10 | 11 | function getMaxProfit(stockPrices){ 12 | if(stockPrices.length < 2){ 13 | return null; 14 | } 15 | 16 | let minPrice = stockPrices[0]; 17 | 18 | let maxProfit = stockPrices[1] - stockPrices[0]; 19 | 20 | for(let i = 1; i < stockPrices.length; i++){ 21 | let currentPrice = stockPrices[i]; 22 | let potentialProfit = currentPrice - minPrice; 23 | 24 | maxProfit = Math.max(maxProfit, potentialProfit); 25 | 26 | minPrice = Math.min(minPrice, currentPrice); 27 | } 28 | 29 | return maxProfit; 30 | } 31 | 32 | 33 | // O(n) time complexity, O(1) space. -------------------------------------------------------------------------------- /interviewcake/greedy/highestProductOf3.js: -------------------------------------------------------------------------------- 1 | // Given an array of integers, find the highest product you can get from three of the integers. 2 | // The input arrayOfInts will always have at least three integers. 3 | 4 | var integers = [40, 1, 3, 2, 22, 39, 1, -12]; // 34320 5 | var negatives = [ 2, -10, -10, 1, 3]; // 300 6 | 7 | console.log(highetProductOfThree1(integers)); 8 | 9 | 10 | // O(n) time, O(1) space 11 | function highetProductOfThree1(integers){ 12 | let first = 0; 13 | let second = 1; 14 | let third = 2; 15 | 16 | let highestProductOfThree = integers[0] * integers[1] * integers[2]; 17 | 18 | for(let i = 3; i < integers.length; i++){ 19 | const current = integers[i]; 20 | 21 | const test1 = current * integers[first] * integers[second]; 22 | const test2 = current * integers[second] * integers[third]; 23 | const test3 = current * integers[first] * integers[third]; 24 | 25 | highestProductOfThree = Math.max(test1, test2, highestProductOfThree); 26 | 27 | if(highestProductOfThree === test1){ 28 | [first, second, third] = [i, first, second]; 29 | } else if(highestProductOfThree === test2){ 30 | [first, second, third] = [i, second, third]; 31 | } else if(highestProductOfThree === test3){ 32 | [first, second, third] = [i, first, third] 33 | } 34 | } 35 | 36 | return highestProductOfThree; 37 | } 38 | 39 | 40 | 41 | 42 | 43 | 44 | function highetProductOfThree(integers){ 45 | var highestOf3 = integers[0] * integers[1] * integers[2]; 46 | 47 | var highestOf2 = integers[0] * integers[1]; 48 | var lowestOf2 = integers[0] * integers[1]; 49 | 50 | var highest = Math.max(integers[0], integers[1]); 51 | var lowest = Math.min(integers[0], integers[1]); 52 | 53 | for(var i = 2; i < integers.length; i++){ 54 | var current = integers[i]; 55 | 56 | // do we have new highest of 3? 57 | highestOf3 = Math.max( 58 | highestOf3, 59 | current * highestOf2, 60 | current * lowestOf2 61 | ); 62 | 63 | // new highest of 2? 64 | highestOf2 = Math.max( 65 | highestOf2, 66 | current * highest, 67 | current * lowest 68 | ); 69 | 70 | // new lowest of 2? 71 | lowestOf2 = Math.max( 72 | lowestOf2, 73 | current * highest, 74 | current * lowest 75 | ); 76 | 77 | // new highest? 78 | highest = Math.max(highest, current); 79 | 80 | // new lowest? 81 | lowest = Math.max(lowest, current); 82 | } 83 | 84 | return highestOf3; 85 | } 86 | 87 | 88 | -------------------------------------------------------------------------------- /interviewcake/greedy/productOfOtherNumbers.js: -------------------------------------------------------------------------------- 1 | // You have an array of integers, and for each index you want 2 | // to find the product of every integer except the integer at that index. 3 | // given [1, 7, 3, 4] 4 | // returns [84, 12, 28, 21] 5 | 6 | // it is product of all other values 7 | // so [ 7*3*4, 1*3*4, 1*7*4, 1*7*3] 8 | 9 | // Do not use division in your solution. 10 | 11 | var nums = [1, 7, 3, 4]; // [84, 12, 28, 21] 12 | var nums2 = [2, 4, 10]; // 13 | 14 | var output = getProductsOfAllIntsExceptAtIndex1(nums); 15 | console.log(output); 16 | 17 | // O(n) time and O(n) space 18 | function getProductsOfAllIntsExceptAtIndex1(integers){ 19 | const result = []; 20 | let beforeProduct = 1; 21 | let afterProduct = 1; 22 | 23 | for(let i = 0; i < integers.length; i++){ 24 | result[i] = beforeProduct; 25 | beforeProduct *= integers[i]; 26 | } 27 | 28 | for(let j = integers.length - 1; j >= 0; j--){ 29 | result[j] *= afterProduct; 30 | afterProduct *= integers[j]; 31 | } 32 | 33 | return result; 34 | } 35 | 36 | 37 | 38 | function getProductsOfAllIntsExceptAtIndex(intArray){ 39 | 40 | var beforeIndexValues = []; 41 | 42 | var accumulator = 1; 43 | 44 | for (var i = 0; i < intArray.length; i++) { 45 | beforeIndexValues[i] = accumulator; 46 | accumulator *= intArray[i]; 47 | } 48 | 49 | var afterIndexValues = []; 50 | accumulator = 1; 51 | 52 | for(var i = intArray.length - 1; i >= 0; i--){ 53 | afterIndexValues[i] = accumulator; 54 | accumulator *= intArray[i]; 55 | } 56 | 57 | return beforeIndexValues.map((num, i) => { 58 | return num * afterIndexValues[i]; 59 | }); 60 | } 61 | 62 | -------------------------------------------------------------------------------- /interviewcake/hashTables/checkPalindrome.js: -------------------------------------------------------------------------------- 1 | // Write an efficient function that checks whether any permutation 2 | // of an input string is a palindrome 3 | 4 | // "civic" should return true 5 | // "ivicc" should return true 6 | // "civil" should return false 7 | // "livci" should return false 8 | 9 | // console.log(checkPalindrome("civic")); 10 | // console.log(checkPalindrome("ivicc")); 11 | // console.log(checkPalindrome("civil")); 12 | // console.log(checkPalindrome("livci")); 13 | 14 | function checkPalindrome(str){ 15 | var hashMap = {}; 16 | 17 | for(var i = 0; i< str.length; i++){ 18 | (hashMap[str[i]]) ? hashMap[str[i]] += 1 : hashMap[str[i]] = 1; 19 | } 20 | 21 | var countsGreaterThanOne = 0; 22 | var oneCounts = 0; 23 | 24 | for(var k in hashMap){ 25 | var count = hashMap[k]; 26 | if(count == 1) oneCounts += 1; 27 | } 28 | 29 | return (oneCounts >= 2 ) ? false : true; 30 | 31 | 32 | } 33 | 34 | 35 | // Write an efficient function that checks whether any permutation 36 | // of an input string is a palindrome. 37 | 38 | console.log(checkPalindrome2("civic")); // true 39 | console.log(checkPalindrome2("ivicc")); // true 40 | console.log(checkPalindrome2("civil")); // false 41 | console.log(checkPalindrome2("livci")); // false 42 | console.log(checkPalindrome2("aabbbccccaccccbbbaa")); // true 43 | 44 | // O(2 * n) time, O(2 * n) space 45 | function checkPalindrome2(str){ 46 | let hashMap = {}; 47 | let splitted = str.split(''); 48 | let oddCount = 0; 49 | 50 | for(let i = 0; i < splitted.length; i++){ 51 | if(hashMap[splitted[i]]){ 52 | hashMap[splitted[i]] += 1; 53 | } else { 54 | hashMap[splitted[i]] = 1; 55 | } 56 | } 57 | 58 | for(let letter in hashMap){ 59 | if(hashMap[letter] % 2 !== 0){ 60 | oddCount += 1; 61 | } 62 | } 63 | 64 | return (oddCount <= 1); 65 | } 66 | 67 | // O(n) time, O(n) space 68 | function checkPalindromeFimal(str){ 69 | let unmatchedChar = new Set(); 70 | 71 | for(let char of str){ 72 | if(unmatchedChar.has(char)){ 73 | unmatchedChar.delete(char); 74 | } else { 75 | unmatchedChar.add(char); 76 | } 77 | } 78 | 79 | return (unmatchedChar.size <= 1); 80 | } 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /interviewcake/hashTables/duplicateFiles.js: -------------------------------------------------------------------------------- 1 | // Try writing something that just walks through a file system and prints all the file names. 2 | 3 | const fs = require('fs'); 4 | 5 | function printFileNames(dirpath){ 6 | let file; 7 | const fileNames = fs.readdirSync(dirpath); 8 | const fileObj = {}; 9 | let duplicates = []; 10 | 11 | for(let i = 0; i < fileNames.length; i++){ 12 | 13 | try { 14 | file = fs.readFileSync(`${dirpath}/${fileNames[i]}`, 'utf8'); 15 | } catch(e){ 16 | // trying to read a directory 17 | continue; 18 | } 19 | 20 | if(!fileObj[file]){ 21 | fileObj[file] = fileNames[i]; 22 | } else { 23 | console.log('found duplicate file!'); 24 | 25 | duplicates.push([fileNames[i], fileObj[file]]) 26 | 27 | } 28 | 29 | 30 | } 31 | 32 | return duplicates; 33 | } 34 | 35 | 36 | console.log(printFileNames('.')); -------------------------------------------------------------------------------- /interviewcake/hashTables/inflight-entertainment.js: -------------------------------------------------------------------------------- 1 | // https://www.interviewcake.com/question/python/inflight-entertainment 2 | 3 | // Write a function that takes an integer flight_length (in minutes) and a list of 4 | // integers movie_lengths (in minutes) and returns a boolean indicating whether there 5 | // are two numbers in movie_lengths whose sum equals flight_length. 6 | 7 | // When building your function: 8 | 9 | // Assume your users will watch exactly two movies 10 | // Don't make your users watch the same movie twice 11 | // Optimize for runtime over memory 12 | 13 | 14 | // Brute force O(n^2) 15 | function twoMoviesInFlight(flight_length, movie_lengths) { 16 | 17 | for(var i = 0; i < movie_lengths.length; i++){ 18 | for(var j = 0; j < movie_lengths.length; j++){ 19 | if (j === i){ continue; } 20 | 21 | if(movie_lengths[i] + movie_lengths[j] === 100){ 22 | return true; 23 | } 24 | } 25 | } 26 | 27 | return false; 28 | } 29 | 30 | // Optimal solution O(n) 31 | function twoMoviesInFlight(flight_length, movie_lengths){ 32 | 33 | const moviesSet = new Set(); 34 | 35 | for(var i = 0; i < movie_lengths.length; i++){ 36 | 37 | const secondMovieLength = flight_length - movie_lengths[i]; 38 | 39 | if(moviesSet.has(secondMovieLength)){ 40 | return true; 41 | } 42 | 43 | moviesSet.add(movie_lengths[i]); 44 | } 45 | 46 | return false; 47 | } 48 | 49 | console.log(twoMoviesInFlight(100, [101, 49, 51, 12, 3])); 50 | console.log(twoMoviesInFlight(100, [101, 50, 50, 12, 3])); 51 | console.log(twoMoviesInFlight(100, [101, 60, 32, 12, 9])); -------------------------------------------------------------------------------- /interviewcake/hashTables/inflightEntertainment.js: -------------------------------------------------------------------------------- 1 | // var flightTime = 240; 2 | // var movies = [60, 117, 121, 54, 239, 62, 120, 120, 58]; 3 | 4 | // console.log(chooseMovies(flightTime, movies)); 5 | 6 | 7 | function chooseMovies(flightLength, movieLengths){ 8 | var hashMap = {}; 9 | 10 | for(var i = 0; i < movieLengths.length; i++){ 11 | (hashMap[movieLengths[i]]) ? hashMap[movieLengths[i]]+=1 : hashMap[movieLengths[i]] = 1; 12 | } 13 | 14 | for(var i = 0; i < movieLengths.length; i++){ 15 | var difference = flightTime - movieLengths[i]; 16 | 17 | if(hashMap[difference] && difference !== movieLengths[i]){ 18 | return true; 19 | } 20 | 21 | if(difference == movieLengths[i] && hashMap[difference] >= 2){ 22 | return true; 23 | } 24 | 25 | } 26 | 27 | return false; 28 | } 29 | 30 | 31 | // you're building a feature for choosing two 32 | // movies whose total runtimes will equal the exact 33 | // flight length 34 | 35 | const flightLength = 100; 36 | const movieLengths = [ 12, 13, 49, 49, 50, 75 ]; 37 | 38 | console.log(chooseMovies2(flightLength, movieLengths)); 39 | 40 | // O(n) time, and O(n) space 41 | function chooseMovies2(flightLength, movieLengths){ 42 | let movies = new Set(); 43 | 44 | for(let i = 0; i < movieLengths.length; i++){ 45 | const requiredLength = flightLength - movieLengths[i]; 46 | 47 | if(movies.has(requiredLength)){ 48 | return true; 49 | } else { 50 | movies.add(movieLengths[i]); 51 | } 52 | } 53 | 54 | return false; 55 | } 56 | 57 | 58 | -------------------------------------------------------------------------------- /interviewcake/hashTables/topScores.js: -------------------------------------------------------------------------------- 1 | // Write a function that takes: 2 | 3 | // 1. an array of unsortedScores 4 | // 2. the highestPossibleScore in the game 5 | 6 | // and returns a sorted array of scores in less than O(n log n) time. 7 | 8 | const unsortedScores = [37, 89, 41, 65, 91, 53]; 9 | const HIGHEST_POSSIBLE_SCORE = 100; 10 | 11 | console.log(sortScores(unsortedScores, HIGHEST_POSSIBLE_SCORE)); 12 | 13 | function sortScores(unsortedScores, highestPossibleScore){ 14 | let scoreCounts = new Array(highestPossibleScore + 1).fill(0); 15 | 16 | unsortedScores.forEach((score)=>{ 17 | scoreCounts[score]++; 18 | }); 19 | 20 | const sortedScores = []; 21 | 22 | for (let score = highestPossibleScore; score >= 0; score--) { 23 | const count = scoreCounts[score]; 24 | 25 | for (let time = 0; time < count; time++) { 26 | sortedScores.push(score); 27 | } 28 | } 29 | 30 | return sortedScores; 31 | } 32 | 33 | 34 | // Ways to get O(n) runtime: 35 | // - Greedy Algorithm: good for grabbing specific value, not rendering whole set. 36 | // - Counting: Build an object or array with the scores and how many times they appear. 37 | 38 | 39 | // Fun fact: Object.keys() will sort in O(n) time 40 | -------------------------------------------------------------------------------- /interviewcake/hashTables/wordCloud.js: -------------------------------------------------------------------------------- 1 | console.log(wordCloud("After the beating the eggs step, Dana read the next step:")); 2 | console.log(wordCloud("Add milk and eggs, then add flour and sugar.")); 3 | 4 | 5 | // todo: make improvements to runtime and space 6 | function wordCloud(str){ 7 | let splitted = stripPunctuation(str).split(' '); 8 | let hashMap = {}; 9 | 10 | for(word of splitted){ 11 | const lowered = word.toLowerCase(); 12 | 13 | if(hashMap[lowered]){ 14 | hashMap[lowered] += 1; 15 | } else { 16 | hashMap[lowered] = 1; 17 | } 18 | } 19 | 20 | return hashMap; 21 | } 22 | 23 | 24 | function stripPunctuation(str){ 25 | let result = ''; 26 | 27 | for(char of str){ 28 | if(char == ':' || char == ',' || char == '.' || char == ';'){ 29 | 30 | } else { 31 | result += char; 32 | } 33 | } 34 | 35 | return result; 36 | 37 | } -------------------------------------------------------------------------------- /interviewcake/readme.md: -------------------------------------------------------------------------------- 1 | 2 | A **greedy algorithm** iterates through the problem space taking the optimal solution "so far" 3 | until it reaches the end. 4 | 5 | Greedy approaches are great because they are fast (usually one pass through the input). 6 | 7 | Ask yourself, suppose we could come up with the answer for one pass through the input by 8 | updating the 'best answer so far' as we went. What additional values would we need to keep 9 | updated as we looked at each item in our set, in order to be able to update the 'best answer 10 | so far'? -------------------------------------------------------------------------------- /interviewcake/recursion/allPermutations.js: -------------------------------------------------------------------------------- 1 | // Write a recursive function for generating all permutations of an input string. 2 | // Return them as a set. 3 | 4 | const input = 'abc'; 5 | 6 | const expected = new Set([ 7 | 'abc', 8 | 'acb', 9 | 'bac', 10 | 'bca', 11 | 'cab', 12 | 'cba' 13 | ]); 14 | 15 | console.log(getPermutations(input)); 16 | 17 | function getPermutations(string) { 18 | 19 | // Base case 20 | if (string.length <= 1) { 21 | return new Set([string]); 22 | } 23 | 24 | const allCharsExceptLast = string.slice(0, -1); 25 | const lastChar = string[string.length - 1]; 26 | 27 | // Recursive call: get all possible permutations for all chars except last 28 | const permutationsOfAllCharsExceptLast = getPermutations(allCharsExceptLast); 29 | 30 | // Put the last char in all possible positions for each of the above permutations 31 | const permutations = new Set(); 32 | permutationsOfAllCharsExceptLast.forEach(permutationOfAllCharsExceptLast => { 33 | for (let position = 0; position <= allCharsExceptLast.length; position++) { 34 | const permutation = permutationOfAllCharsExceptLast.slice(0, position) + lastChar + permutationOfAllCharsExceptLast.slice(position); 35 | permutations.add(permutation); 36 | } 37 | }); 38 | 39 | return permutations; 40 | } -------------------------------------------------------------------------------- /interviewcake/searchingSortingLogarithms/findRepeat.js: -------------------------------------------------------------------------------- 1 | // The integers are in the range 1..n 2 | // The array has a length of n+1 3 | // our array has at least one integer which appears at least twice 4 | 5 | // Write a function which finds an integer that appears more than once in our array 6 | 7 | const integers = [1,1,2,3,2,2]; 8 | console.log(findRepeats1(integers)); 9 | 10 | // optimized for space 11 | // O(1) space. O(n log n) for time 12 | function findRepeats1(integers){ 13 | // sort array in place. Takes O(n log n) time and O(1) space 14 | integers.sort((a, b) => { 15 | return a - b; 16 | }); 17 | 18 | for(let i = 0; i < integers.length; i++){ 19 | if(integers[i] === integers[i - 1]){ 20 | return integers[i]; 21 | } 22 | } 23 | 24 | return 'Error no duplicates'; 25 | } 26 | 27 | // O(n) for space. O(n) for time 28 | // This returns all duplicates 29 | function findRepeats(integers){ 30 | 31 | const set = new Set(); 32 | const duplicates = new Set(); 33 | 34 | for(let i = 0; i < integers.length; i++){ 35 | if(set.has(integers[i])){ 36 | duplicates.add(integers[i]) 37 | } 38 | 39 | set.add(integers[i]); 40 | } 41 | 42 | return duplicates; 43 | } -------------------------------------------------------------------------------- /interviewcake/searchingSortingLogarithms/findRotationPoint.js: -------------------------------------------------------------------------------- 1 | // Write a function for finding the index of the "rotation point," 2 | // which is where I started working from the beginning of the dictionary. 3 | 4 | // This array is huge (there are lots of words I don't know) so we want 5 | // to be efficient here. 6 | 7 | const words = [ 8 | 'ptolemaic', 9 | 'retrograde', 10 | 'supplant', 11 | 'undulate', 12 | 'xenoepist', 13 | 'asymptote', // <-- rotates here! 5 14 | 'babka', 15 | 'banoffee', 16 | 'engender', 17 | 'endgame', 18 | 'ester', 19 | 'entello', 20 | 'karpatka', 21 | 'othellolagkage', 22 | ]; 23 | 24 | console.log(findRotationPoint(words)); 25 | 26 | // O(log n) space complexity. Every time we go through loop we cut the length in half 27 | // O(1) space to store the indices 28 | function findRotationPoint(wordsArray){ 29 | const firstWord = wordsArray[0]; 30 | 31 | let floorIndex = 0; 32 | let ceilingIndex = wordsArray.length - 1; 33 | 34 | while(floorIndex < ceilingIndex){ 35 | 36 | const guessIndex = Math.floor(floorIndex + ((ceilingIndex - floorIndex) / 2)); 37 | 38 | if(wordsArray[guessIndex] >= firstWord){ 39 | // Look right 40 | floorIndex = guessIndex; 41 | } else { 42 | // Look left 43 | ceilingIndex = guessIndex; 44 | } 45 | 46 | if(floorIndex + 1 === ceilingIndex){ 47 | break; 48 | } 49 | } 50 | 51 | return ceilingIndex; 52 | } 53 | -------------------------------------------------------------------------------- /interviewcake/treesGraphs/balancedBinaryTree.js: -------------------------------------------------------------------------------- 1 | // A tree is "superbalanced" if the difference between the depths 2 | // of any two leaf nodes is no greater than one. 3 | 4 | class BinaryTreeNode { 5 | constructor(value) { 6 | this.value = value; 7 | this.left = null; 8 | this.right = null; 9 | } 10 | 11 | insertLeft(value) { 12 | this.left = new BinaryTreeNode(value); 13 | return this.left; 14 | } 15 | 16 | insertRight(value) { 17 | this.right = new BinaryTreeNode(value); 18 | return this.right; 19 | } 20 | } 21 | 22 | // depth first or breadth first tree traversal 23 | 24 | 25 | function isSuperbalanced(treeRoot){ 26 | 27 | // todo: get comfortable implementing BFS and DFS 28 | // breadth-first uses a queue and depth-first uses a stack. 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /interviewcake/treesGraphs/validateBST.js: -------------------------------------------------------------------------------- 1 | // Write a function to check that a binary tree is a valid binary search tree 2 | 3 | // Sample BST class: 4 | 5 | class BinaryTreeNode { 6 | constructor(value) { 7 | this.value = value; 8 | this.left = null; 9 | this.right = null; 10 | } 11 | 12 | insertLeft(value) { 13 | this.left = new BinaryTreeNode(value); 14 | return this.left; 15 | } 16 | 17 | insertRight(value) { 18 | this.right = new BinaryTreeNode(value); 19 | return this.right; 20 | } 21 | } 22 | 23 | const rootNode = new BinaryTreeNode(7); 24 | rootNode.insertRight(8); 25 | rootNode.insertLeft(10); 26 | 27 | console.log(isValidBST(rootNode)) 28 | 29 | 30 | function isValidBST(rootNode){ 31 | 32 | // todo 33 | } 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /rithmschool/algorithms/binarySearch.js: -------------------------------------------------------------------------------- 1 | // Select the middle element and compare lower or higher 2 | 3 | // O(log n) 4 | 5 | /****** Iterative Solution *******/ 6 | 7 | /* Returns either the index of the location in the array, 8 | or -1 if the array did not contain the targetValue */ 9 | function doSearch(array, targetValue) { 10 | var min = 0; 11 | var max = array.length - 1; 12 | var guess; 13 | 14 | while(max >= min){ 15 | guess = Math.floor((min+max)/2); 16 | 17 | if(array[guess] === targetValue){ 18 | return guess; 19 | } else if(array[guess] < targetValue){ 20 | min = guess + 1; 21 | } else { 22 | max = guess - 1; 23 | } 24 | } 25 | return -1; 26 | }; 27 | 28 | var primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 29 | 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]; 30 | var result = doSearchRecursive(primes, 73); 31 | console.log("Found prime at index " + result); 32 | 33 | 34 | 35 | /****** Recursive Solution (does not find index) *******/ 36 | 37 | /* Returns either the index of the location in the array, 38 | or -1 if the array did not contain the targetValue */ 39 | // function doSearch(array, targetValue) { 40 | // var min = 0; 41 | // var max = array.length - 1; 42 | 43 | // var guess = parseInt((min + max)/2, 10); 44 | 45 | // if(array[guess] === targetValue){ 46 | // return true; 47 | // } 48 | 49 | // if(array[guess] > targetValue){ 50 | // var newArr = array.slice(min, guess + 1); 51 | // return doSearchRecursive(newArr, targetValue); 52 | // } else if (array[guess] < targetValue){ 53 | // var newArr = array.slice(guess + 1, max); 54 | // return doSearchRecursive(newArr, targetValue); 55 | // } 56 | 57 | // return -1; 58 | // }; 59 | 60 | 61 | -------------------------------------------------------------------------------- /rithmschool/algorithms/insertionSort.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connor11528/cs-fundamentals/c4a4bb0e11813702b82f2eedd710299187b69428/rithmschool/algorithms/insertionSort.js -------------------------------------------------------------------------------- /rithmschool/algorithms/selectionSort.js: -------------------------------------------------------------------------------- 1 | // Find the smallest card. Swap it with the first card. 2 | // Find the second-smallest card. Swap it with the second card. 3 | // Find the third-smallest card. Swap it with the third card. 4 | // Repeat finding the next-smallest card, and swapping it into the correct position until the array is sorted. 5 | // This algorithm is called selection sort because it repeatedly selects the next-smallest element and swaps it into place. 6 | 7 | // O(n^2) 8 | 9 | var swap = function(array, firstIndex, secondIndex) { 10 | var temp = array[secondIndex]; 11 | array[secondIndex] = array[firstIndex]; 12 | array[firstIndex] = temp; 13 | }; 14 | 15 | var indexOfMinimum = function(array, startIndex) { 16 | var minValue = array[startIndex]; 17 | var minIndex = startIndex; 18 | 19 | for(var i = startIndex + 1; i < array.length; i++){ 20 | if(array[i] < minValue) { 21 | minValue = array[i]; 22 | minIndex = i; 23 | } 24 | } 25 | 26 | return minIndex; 27 | }; 28 | 29 | var selectionSort = function(array) { 30 | for(var i = 0; i< array.length; i++){ 31 | var min = indexOfMinimum(array, i); 32 | swap(array, i, min); 33 | } 34 | return array; 35 | }; 36 | 37 | var array = [22, 11, 99, 88, 9, 7, 42]; 38 | selectionSort(array); 39 | console.log("Array after sorting: " + array); 40 | 41 | 42 | -------------------------------------------------------------------------------- /rithmschool/data_structures/Dictionary.js: -------------------------------------------------------------------------------- 1 | function Dictionary(){ 2 | var items = {}; 3 | 4 | this.set = (key, value) => { 5 | 6 | } 7 | 8 | this.delete = (key) => { 9 | 10 | } 11 | 12 | this.has = (key) => { 13 | 14 | } 15 | 16 | this.get = (key) => { 17 | 18 | } 19 | 20 | this.clear = () => { 21 | 22 | } 23 | 24 | this.size = () => { 25 | 26 | } 27 | 28 | this.keys = () => { 29 | 30 | } 31 | 32 | this.values = () => { 33 | 34 | } 35 | } -------------------------------------------------------------------------------- /rithmschool/data_structures/HashTable.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connor11528/cs-fundamentals/c4a4bb0e11813702b82f2eedd710299187b69428/rithmschool/data_structures/HashTable.js -------------------------------------------------------------------------------- /rithmschool/data_structures/LinkedList.js: -------------------------------------------------------------------------------- 1 | 2 | function LinkedList() { 3 | 4 | // helper class 5 | let Node = function(elem){ 6 | this.element = elem; 7 | this.next = null; 8 | } 9 | 10 | let length = 0; 11 | 12 | // reference to first node 13 | let head = null; 14 | 15 | // reference to the last node 16 | let tail = null; 17 | 18 | // adds element to the end 19 | this.append = (elem) => { 20 | 21 | } 22 | 23 | // insert item at specified index 24 | this.insert = (position, elem) => { 25 | 26 | } 27 | 28 | // remove element from specified position 29 | this.removeAt = (position) => { 30 | 31 | } 32 | 33 | // remove item from list 34 | this.remove = (elem) => { 35 | 36 | } 37 | 38 | // return index of element or -1 if not present 39 | this.indexOf = (elem) => { 40 | 41 | } 42 | 43 | // returns true if no elements in list 44 | this.isEmpty = () => { 45 | 46 | } 47 | 48 | // returns number of elements 49 | this.size = () => { 50 | 51 | } 52 | 53 | // output element values 54 | this.toString = () => { 55 | 56 | } 57 | 58 | this.print = () => { 59 | 60 | } 61 | } 62 | 63 | new LinkedList(); -------------------------------------------------------------------------------- /rithmschool/data_structures/Set.js: -------------------------------------------------------------------------------- 1 | function Set() { 2 | let items = {}; 3 | 4 | this.add = (value) => { 5 | if(!this.has(value)){ 6 | items[value] = value; 7 | return true; 8 | } 9 | return false; 10 | } 11 | 12 | this.delete = (value) => { 13 | // verify value exists 14 | if(this.has(value)){ 15 | delete items[value]; 16 | return true; 17 | } 18 | return false; 19 | } 20 | 21 | this.has = (value) => { 22 | // returns boolean if property exists 23 | return items.hasOwnProperty(value); 24 | } 25 | 26 | this.clear = () => { 27 | items = {}; 28 | } 29 | 30 | this.size = () => { 31 | return Object.keys(items).length; 32 | } 33 | 34 | this.values = () => { 35 | 36 | } 37 | } 38 | 39 | 40 | // union 41 | 42 | // intersection 43 | 44 | // difference 45 | 46 | // subset -------------------------------------------------------------------------------- /rithmschool/dynamic-programming.js: -------------------------------------------------------------------------------- 1 | // https://www.rithmschool.com/courses/javascript-computer-science-fundamentals/dynamic-programming 2 | 3 | // memoization = 'storing' the result of an expensive function 4 | // Memoization is implemented by maintaining a lookup table of previous solved sub-problems 5 | 6 | // tabulation you solve the by solving all related sub-problems first 7 | 8 | // Video from CTCI - Algorithms: Memoization and Dynamic Programming - https://www.youtube.com/watch?v=P8Xa2BitN3I 9 | 10 | // Lots of extra dynammic programming problems - http://www.geeksforgeeks.org/dynamic-programming/ 11 | 12 | //======= 13 | 14 | // Knapsack Problem 15 | // given a set of positive integers, 3, 5, 6, 10, 34 say, find a subset that sums 16 | // to exactly to a given value, such as 50. 17 | var ints = [3, 5, 6, 10, 34] 18 | var value = 50 19 | 20 | console.log(knapsack(ints, value)); // [6, 10, 34] 21 | 22 | function knapsack(arr, value){ 23 | 24 | } 25 | 26 | // Change Making Problem 27 | // https://www.interviewcake.com/question/javascript/coin 28 | 29 | 30 | // Fibonacci Sequence 31 | // [0,1,1,2,3,5,8,13,21] 32 | 33 | // console.log(fib(9)); 34 | 35 | function fib(i){ 36 | let dict = {}, output = Array(i).fill(0); output[1] = 1; 37 | 38 | for(let j = 2; j < output.length; j++){ 39 | if(output[j] == 0){ 40 | output[j] = output[j-1] + output[j-2] 41 | } 42 | } 43 | return output; 44 | 45 | } -------------------------------------------------------------------------------- /rithmschool/exercises.js: -------------------------------------------------------------------------------- 1 | console.log(getPowerset('abc')); 2 | 3 | // '' => [''] 4 | // 'a' => ['', 'a'] 5 | // 'ab' => ['', 'a', 'b', 'ab'] 6 | // 'abc' => ['', 'a', 'b', 'c', 'ab', 'ac', 'bc', 'abc'] 7 | 8 | // solution: https://rosettacode.org/wiki/Power_set#JavaScript 9 | 10 | function getPowerset(input){ 11 | // var counter = 0, output = [], inputArr = input.split(''); 12 | // var start = ''; 13 | 14 | // while(counter < inputArr.length){ 15 | // output.push(start); 16 | // for(var i = 0; i < inputArr.length; i++){ 17 | // start = inputArr[i]; 18 | // output.push(start); 19 | // } 20 | 21 | // counter++; 22 | // } 23 | // return output; 24 | } 25 | 26 | 27 | 28 | // Given an array a that contains only numbers in the range from 1 to a.length, find the first 29 | // duplicate number for which the second occurrence has the minimal index. In other words, if 30 | // there are more than 1 duplicated numbers, return the number for which the second occurrence 31 | // has a smaller index than the second occurrence of the other number does. If there are no such 32 | // elements, return -1. 33 | // Source: Codefights 34 | 35 | function firstDuplicate(arr) { 36 | 37 | // find duplicates 38 | var counts = arr.map((a, i)=>{ 39 | return { name: a, count: 1, index: i}; 40 | }); 41 | 42 | var totals = counts.reduce(function(a, b, i){ 43 | // handle >1 occurence 44 | if(typeof a[b.name] === 'object'){ 45 | return a; 46 | } 47 | 48 | if(a[b.name]){ 49 | a[b.name] = { count: a[b.name] + b.count, index: b.index }; 50 | } else { 51 | a[b.name] = b.count; 52 | } 53 | 54 | return a; 55 | }, {}); 56 | 57 | var hasDuplicates = false; 58 | var counts = []; 59 | 60 | for(var item in totals){ 61 | if(typeof totals[item] === 'object'){ 62 | hasDuplicates = true; 63 | counts.push(Object.assign({name: item }, totals[item])); 64 | } 65 | } 66 | 67 | // if no duplicates return -1 68 | if(!hasDuplicates) return -1; 69 | 70 | var minimal = arr.length; 71 | 72 | // get lowest index for duplicate 73 | counts.forEach((d)=>{ 74 | if(d.index < minimal) 75 | minimal = d.index; 76 | }); 77 | 78 | return arr[minimal]; 79 | } 80 | 81 | // Given a string s, find and return the first instance of a non-repeating character in it. 82 | // If there is no such character, return '_'. 83 | // Source: Codefights 84 | 85 | function firstNotRepeatingCharacter(str) { 86 | var repeats = []; 87 | for(var i = 0; i < str.length; i++){ 88 | repeats.push({ letter: str[i], count: 1 }); 89 | } 90 | 91 | var counts = repeats.reduce(function(a, b){ 92 | 93 | if(a[b.letter]) 94 | a[b.letter] += b.count; 95 | else 96 | a[b.letter] = 1; 97 | return a; 98 | }, {}); 99 | 100 | var nonrepeats = []; 101 | for (var k in counts){ 102 | if(counts[k] === 1) 103 | nonrepeats.push(k) 104 | } 105 | 106 | if (nonrepeats.length === 0) 107 | return '_'; 108 | 109 | var firstNonRepeater = str.length; 110 | nonrepeats.forEach(function(n){ 111 | if(str.indexOf(n) < firstNonRepeater) 112 | firstNonRepeater = n; 113 | }); 114 | return firstNonRepeater; 115 | } 116 | 117 | // You are given an n x n 2D matrix that represents an image. Rotate the image 118 | // by 90 degrees (clockwise). 119 | // Source: Codefights 120 | 121 | function rotateImage(img) { 122 | var output = []; 123 | var max = img[0].length; 124 | for(var i = 0; i < max; i++){ 125 | output.push([...Array(max)]); 126 | } 127 | 128 | for(var i = 0; i < max; i++){ 129 | var row = img[i]; 130 | 131 | for(var j = 0; j < max; j++){ 132 | output[j][i] = img[i][j] 133 | } 134 | } 135 | 136 | return output.map(function(row){ 137 | return row.reverse(); 138 | }); 139 | } 140 | 141 | // Return the number (count) of vowels in the given string. 142 | // Source: Codewars 143 | 144 | function getCount(str) { 145 | var vowelsCount = 0; 146 | str = str.toLowerCase(); 147 | var vowels = ['a', 'e', 'i', 'o', 'u']; 148 | 149 | for(let s of str){ 150 | 151 | if(vowels.includes(s)) vowelsCount += 1; 152 | } 153 | 154 | return vowelsCount; 155 | } 156 | 157 | // Return the next square if sq if a perfect square, -1 otherwise 158 | // Source: Codewars 159 | 160 | function findNextSquare(sq) { 161 | 162 | if (!Number.isInteger(Math.sqrt(sq))) return -1; 163 | 164 | var i = sq + 1; 165 | 166 | while(!Number.isInteger(Math.sqrt(i))){ 167 | i++; 168 | } 169 | 170 | return i; 171 | } 172 | 173 | // Finish the solution so that it returns the sum of all the multiples of 3 or 5 below the number passed in. 174 | // Source: Codewars 175 | 176 | function solution(number){ 177 | let sum = 0; 178 | number -= 1; 179 | while(number > 0){ 180 | if(number % 3 == 0 || number % 5 == 0){ 181 | sum += number; 182 | } 183 | number--; 184 | } 185 | 186 | return sum; 187 | } 188 | 189 | 190 | // You are going to be given an array of integers. Your job is to take that array and find an index N 191 | // where the sum of the integers to the left of N is equal to the sum of the integers to the right of N. 192 | // If there is no index that would make this happen, return -1. 193 | // Source: Codewars 194 | 195 | function sum(arr){ 196 | return arr.reduce(function(sum, value){ 197 | return sum + value; 198 | }, 0); 199 | } 200 | 201 | function findEvenIndex(arr) 202 | { 203 | for(var i=0; i < arr.length; i++){ 204 | let left = arr.slice(0, i); 205 | let right = arr.slice(i+1, arr.length); 206 | 207 | if (sum(left) == sum(right)) return i; 208 | } 209 | return -1; 210 | } 211 | 212 | 213 | // The new "Avengers" movie has just been released! There are a lot of people at the cinema 214 | // box office standing in a huge line. Each of them has a single 100, 50 or 25 dollars bill. 215 | // A "Avengers" ticket costs 25 dollars. Can Vasya sell a ticket to each person and give the 216 | // change if he initially has no money and sells the tickets strictly in the order people follow in the line? 217 | // Source: Codewars 218 | 219 | function tickets(peopleInLine){ 220 | let revenue = 0; 221 | let bills = {'25': 0, '50': 0, '100': 0}; 222 | 223 | for(var i = 0; i < peopleInLine.length; i++){ 224 | var person = peopleInLine[i], 225 | change = person - 25; 226 | 227 | bills[person] += 1; 228 | 229 | revenue = revenue + 25 - change; 230 | if(revenue < 0){ 231 | return 'NO'; 232 | } else { 233 | // give change 234 | if(change == 25){ 235 | if(bills[25] >= 1){ 236 | bills[25] -= 1; 237 | } else { 238 | return 'NO'; 239 | } 240 | } 241 | 242 | if (change == 50){ 243 | if (bills[50] != 0){ 244 | bills[50] -= 1; 245 | } else if (bills[25] >= 2) { 246 | bills[25] -= 2; 247 | } else { 248 | return 'NO'; 249 | } 250 | } 251 | 252 | if (change == 75){ 253 | if (bills[25] >= 1 && bills[50] >= 1) { 254 | bills[25] -= 1; 255 | bills[50] -= 1; 256 | } else if (bills[25] >= 3){ 257 | bills[25] -= 3; 258 | } else { 259 | return 'NO'; 260 | } 261 | } 262 | } 263 | }; 264 | return 'YES'; 265 | } 266 | 267 | 268 | // Implement the function unique_in_order which takes as argument a 269 | // sequence and returns a list of items without any elements with the same value 270 | // next to each other and preserving the original order of elements 271 | 272 | var uniqueInOrder=function(iterable){ 273 | let output = []; 274 | for(var i = 0; i < iterable.length; i++){ 275 | if(iterable[i] !== iterable[i-1]){ 276 | output.push(iterable[i]); 277 | } 278 | } 279 | return output; 280 | } 281 | 282 | 283 | //Given two arrays a and b write a function comp(a, b) that checks whether the two arrays have the 284 | // "same" elements, with the same multiplicities. "Same" means, here, that the elements in b are 285 | // the elements in a squared, regardless of the order. 286 | 287 | function comp(array1, array2){ 288 | try { 289 | array1.sort((a,b) => a-b); array2.sort((a,b) => a-b); 290 | } catch(e) { return false; } 291 | 292 | for(var i = 0; i < array1.length; i++){ 293 | if((array1[i] * array1[i]) !== array2[i]){ 294 | return false; 295 | } 296 | } 297 | return true; 298 | } 299 | 300 | 301 | // accum("abcd"); // "A-Bb-Ccc-Dddd" 302 | // accum("RqaEzty"); // "R-Qq-Aaa-Eeee-Zzzzz-Tttttt-Yyyyyyy" 303 | // accum("cwAt"); // "C-Ww-Aaa-Tttt" 304 | function accum(s) { 305 | let output = [], i = 0; 306 | 307 | for(letter of s){ 308 | output.push(letter.toUpperCase() + letter.toLowerCase().repeat(i)); 309 | i++; 310 | } 311 | return output.join('-'); 312 | } 313 | 314 | 315 | // In DNA strings, symbols "A" and "T" are complements of each other, as "C" and "G". 316 | // You have function with one side of the DNA; you need to get the other complementary side. 317 | // DNA strand is never empty or there is no DNA at all 318 | 319 | function DNAStrand(dna){ 320 | var DNA = Array.of(...dna); 321 | 322 | return DNA.map((curr, i)=>{ 323 | if(curr == 'A') return 'T'; 324 | 325 | if(curr == 'T') return 'A'; 326 | 327 | if(curr == 'C') return 'G'; 328 | 329 | if(curr == 'G') return 'C'; 330 | }).join(''); 331 | } 332 | 333 | // Write a method that takes an array of consecutive (increasing) letters as input and 334 | // that returns the missing letter in the array. 335 | 336 | function findMissingLetter(array){ 337 | for(var i = 0; i < array.length; i++){ 338 | var currentPlusOne = array[i].charCodeAt(0) + 1; 339 | var next = array[i+1].charCodeAt(0); 340 | 341 | if(currentPlusOne !== next){ 342 | return String.fromCharCode(currentPlusOne); 343 | } 344 | } 345 | } 346 | 347 | 348 | // Sort a sorted array by their squares 349 | // [1,2,3] => [1, 4, 9] 350 | // [-10, -1, 0, 1, 2] => [0, 1, 1, 4, 100] 351 | 352 | function sortNums(arr){ 353 | var start = 0, end = arr.length - 1, output = []; 354 | 355 | while (start <= end) { 356 | if (Math.abs(arr[start]) > Math.abs(arr[end])) 357 | { 358 | output.unshift(Math.pow(arr[start], 2)) 359 | start++; 360 | } else { 361 | output.unshift(Math.pow(arr[end], 2)) 362 | end--; 363 | } 364 | } 365 | 366 | return output; 367 | } 368 | 369 | -------------------------------------------------------------------------------- /rithmschool/readme.md: -------------------------------------------------------------------------------- 1 | JS Array Methods 2 | === 3 | 4 | ``` 5 | // Map: 6 | //=== 7 | // The map() method creates a new array with the results 8 | // of calling a provided function on every element in the calling array. 9 | 10 | // map(currentValue, index, array) 11 | 12 | var numbers = [1, 5, 10, 15]; 13 | var doubles = numbers.map(function(x) { 14 | return x * 2; 15 | }); 16 | // doubles is now [2, 10, 20, 30] 17 | // numbers is still [1, 5, 10, 15] 18 | 19 | var numbers = [1, 4, 9]; 20 | var roots = numbers.map(Math.sqrt); 21 | // roots is now [1, 2, 3] 22 | // numbers is still [1, 4, 9] 23 | 24 | 25 | // Reduce: 26 | //=== 27 | // The reduce() method applies a function against an accumulator and each element 28 | // in the array (from left to right) to reduce it to a single value. 29 | 30 | // arr.reduce(callback[, initialValue]) 31 | 32 | var total = [0, 1, 2, 3].reduce(function(sum, value, i) { 33 | return sum + value; 34 | }, 0); 35 | // total is 6 36 | 37 | var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b, i) { 38 | return a.concat(b); 39 | }, []); 40 | // flattened is [0, 1, 2, 3, 4, 5] 41 | 42 | 43 | // Includes 44 | var myArray = [1, 2, 3, 4, 5]; 45 | myArray.includes(1) // true 46 | 47 | // filter 48 | 49 | // lastIndexOf 50 | 51 | // slice(begin, end) 52 | 53 | // some() 54 | 55 | // every() 56 | 57 | // toString() 58 | 59 | // join() 60 | 61 | // pop() 62 | 63 | // slice(begin, end) - does not modify original array 64 | 65 | // splice(start, deleteCount) - modifies original array 66 | 67 | // sort() - sort happens in place, no array copy made. will not sort numbers. You must run arr.sort(function(a, b){ return a-b; }) OR arr.sort((a,b)=> a-b) 68 | 69 | ``` 70 | 71 | 72 | // sum all elements in an array 73 | 74 | JS Number Methods 75 | === 76 | 77 | Number.isInteger(x) 78 | 79 | 80 | JS Set 81 | === 82 | 83 | JS String Methods 84 | === 85 | 86 | // charAt 87 | 88 | // toUpperCase 89 | 90 | // repeat 91 | 92 | // substr 93 | 94 | // substring 95 | 96 | // split 97 | 98 | // charCodeAt 99 | 100 | -------------------------------------------------------------------------------- /rithmschool/recursion.js: -------------------------------------------------------------------------------- 1 | // Write a function called `sumRange`. It will take a number and return 2 | //the sum of all numbers from 1 up to the number passed in. 3 | 4 | // sumRange(3) returns 6, since 1 + 2 + 3 = 6. 5 | 6 | var output = sumRange(3) 7 | // console.log(output); 8 | 9 | function sumRange(num){ 10 | if(num == 1) return 1; 11 | 12 | return num + sumRange(num - 1); 13 | } 14 | 15 | 16 | // Write a function called `power` which takes in a base and an exponent. If 17 | // the exponent is 0, return 1. 18 | 19 | // You can think of it in terms of this example: 20 | // 2^4 = 2 * 2^3; 21 | // 2^3 = 2 * 2^2; 22 | // 2^2 = 2 * 2^1; 23 | // 2^1 = 2 * 2^0; // once our exponent is 0 we KNOW that the value is always 1! 24 | 25 | // console.log(power(2, 4)); 26 | // console.log(power(2, 3)); 27 | // console.log(power(2, 2)); 28 | // console.log(power(2, 1)); 29 | // console.log(power(2, 0)); 30 | 31 | function power(base, exponent){ 32 | if(exponent == 0) return 1; 33 | return base * power(base, exponent - 1); 34 | } 35 | 36 | 37 | // Write a function that returns the `factorial` of a number. As a quick refresher, 38 | // a factorial of a number is the result of that number multiplied by the number 39 | // before it, and the number before that number, and so on, until you reach 1. 40 | // The factorial of 1 is just 1. For example: 41 | 42 | factorial(5); // 5 * 4 * 3 * 2 * 1 === 120 43 | 44 | function factorial(num){ 45 | if(num == 1) return 1; 46 | 47 | return num * factorial(num - 1); // pending multiplier 48 | } 49 | 50 | 51 | // Write a function called `all` which accepts an array and a callback and returns 52 | // true if every value in the array returns true when passed as parameter to the 53 | // callback function 54 | 55 | var allAreLessThanSeven = all([1,2,9], function(num){ 56 | return num < 7; 57 | }); 58 | 59 | console.log(allAreLessThanSeven); 60 | 61 | function all(array, callback){ 62 | var copy = copy || array.slice(); // shallow copies array 63 | 64 | if(copy.length === 0) return true; 65 | 66 | if(callback(copy[0])){ 67 | copy.shift(); // remove first element from array 68 | return all(copy, callback); 69 | } else { 70 | return false; 71 | } 72 | } 73 | 74 | 75 | // Write a function called productOfArray which takes in an array of numbers 76 | // and returns the product of them all 77 | 78 | var six = productOfArray([1,2,3]) // 6 79 | var sixty = productOfArray([1,2,3,10]) // 60 80 | 81 | // console.log(six, sixty); 82 | 83 | function productOfArray(array){ 84 | if(array.length === 0) return 1; 85 | 86 | return array.shift() * productOfArray(array); 87 | } 88 | 89 | 90 | // Write a function called `contains` that searches for a value in a nested object. 91 | // It returns true if the object contains that value. 92 | 93 | var nestedObject = { 94 | data: { 95 | info: { 96 | stuff: { 97 | thing: { 98 | moreStuff: { 99 | magicNumber: 44, 100 | something: 'foo2' 101 | } 102 | } 103 | } 104 | } 105 | } 106 | } 107 | 108 | let hasIt = contains(nestedObject, 44); // true 109 | let doesntHaveIt = contains(nestedObject, "foo"); // false 110 | 111 | // console.log(hasIt, doesntHaveIt); 112 | 113 | function contains(obj, value){ 114 | for(var key in obj){ 115 | if(typeof obj[key] === 'object'){ 116 | return contains(obj[key], value); 117 | } 118 | 119 | if (obj[key] === value){ 120 | return true; 121 | } 122 | } 123 | return false; 124 | } 125 | 126 | 127 | // Given a multi-dimensional integer array, return the total number of integers 128 | // stored inside this array 129 | 130 | var seven = totalIntegers([[[5], 3], 0, 2, ['foo'], [], [4, [5, 6]]]); // 7 131 | // console.log(seven); 132 | 133 | function totalIntegers(array){ 134 | if(array.length === 0) return 0; 135 | 136 | let total = 0; 137 | let first = array.shift(); 138 | 139 | if (Array.isArray(first)){ 140 | total += totalIntegers(first); 141 | } else if (Number.isInteger(first)) { 142 | total += 1; 143 | } 144 | 145 | return total + totalIntegers(array); 146 | } 147 | 148 | 149 | // Write a function that sums squares of numbers in list that may contain more lists 150 | 151 | var l = [1,2,3]; 152 | // console.log(SumSquares(l)); // 14 153 | 154 | l = [[1,2],3]; 155 | // console.log(SumSquares(l)); // 14 156 | 157 | l = [[[[[[[[[1]]]]]]]]] 158 | // console.log(SumSquares(l)); // 1 159 | 160 | l = [10,[[10],10],[10]] 161 | // console.log(SumSquares(l)); // 400 162 | 163 | function SumSquares(array){ 164 | if(array.length === 0) return 0; 165 | let total = 0; 166 | 167 | for(let i = 0; i < array.length; i++){ 168 | if(Array.isArray(array[i])){ 169 | total += SumSquares(array[i]); 170 | } else { 171 | total += array[i] * array[i]; 172 | } 173 | 174 | } 175 | return total; 176 | } 177 | 178 | 179 | // The function should return an array containing repetitions of the number argument. 180 | // For instance, replicate(3, 5) should return [5,5,5]. 181 | // If the times argument is negative, return an empty array. 182 | 183 | // console.log(replicate(3, 5)) // [5, 5, 5] 184 | // console.log(replicate(1, 69)) // [69] 185 | // console.log(replicate(-2, 6)) // [] 186 | 187 | function replicate(times, number){ 188 | if(times <= 0) return []; 189 | 190 | return [number].concat(replicate(times - 1, number)); 191 | } 192 | 193 | 194 | // BONUS 195 | //======= 196 | 197 | // Write a function called search that finds a value in an array and returns the index 198 | // where the value is at. If the value is not found, the function should return negative 1. 199 | 200 | // search([1,2,3,4,5],5) // 4 201 | // search([1,2,3,4,5],15) // -1 202 | 203 | 204 | // Refactor your search function to use a faster algorithm called binary search 205 | // https://www.youtube.com/watch?v=JQhciTuD3E8 206 | 207 | // binarySearch([1,2,3,4,5],5) // 4 208 | // binarySearch([1,2,3,4,5],15) // -1 209 | 210 | 211 | // Write a function called stringifyNumbers which takes in an object and finds all of the 212 | // values which are numbers and converts them to strings. 213 | 214 | var obj = { 215 | num: 1, 216 | test: [], 217 | data: { 218 | val: 4, 219 | info: { 220 | isRight: true, 221 | random: 66 222 | } 223 | } 224 | } 225 | 226 | // stringifyNumbers(obj) 227 | /*/ 228 | Output: 229 | { 230 | num: "1", 231 | test: [], 232 | data: { 233 | val: "4", 234 | info: { 235 | isRight: true, 236 | random: "66" 237 | } 238 | } 239 | } 240 | /*/ -------------------------------------------------------------------------------- /rithmschool/searching-algorithms.js: -------------------------------------------------------------------------------- 1 | // https://www.rithmschool.com/courses/javascript-computer-science-fundamentals/searching-algorithms 2 | 3 | // Algorithms: Graph Search, DFS and BFS by author of CTCI: https://www.youtube.com/watch?v=zaBhtODEL0w 4 | 5 | // Algorithm course on Coderbyte: 6 | // https://coderbyte.com/course/learn-data-structures-and-algorithms/ 7 | // https://coderbyte.com/course/trees-and-graphs 8 | // https://coderbyte.com/course/arrays-and-lists 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /sql/khan-academ-sql/01-sql-queries.sql: -------------------------------------------------------------------------------- 1 | /****** 2 | 3 | Khan Academy SQL course exercises 4 | 5 | https://www.khanacademy.org/computing/computer-programming/sql 6 | 7 | ******/ 8 | 9 | /* Books table */ 10 | 11 | CREATE TABLE books ( 12 | id integer PRIMARY key, 13 | name text, 14 | rating integer 15 | ); 16 | 17 | insert into books values (1, 'Harry Potter', 5); 18 | insert into books values (2, 'Chronicles of Narnia', 4); 19 | insert into books values (3, 'The Martian', null); 20 | 21 | 22 | /* Groceries table */ 23 | 24 | SELECT * FROM groceries WHERE aisle > 5 ORDER BY aisle; 25 | 26 | SELECT aisle, SUM(quantity) FROM groceries GROUP BY aisle; 27 | 28 | /* Online store */ 29 | 30 | create table bikes ( 31 | id integer primary key, 32 | name text, 33 | quantity integer, 34 | price numeric, 35 | category text 36 | ); 37 | 38 | insert into bikes values (1, 'Nimbus 2000', 10, 500.00, 'Mountain'); 39 | insert into bikes values (2, 'Firebolt', 5, 599.99, 'Racing'); 40 | insert into bikes values (3, 'RoadRacer', 1, 445.50, 'Racing'); 41 | insert into bikes values (4, 'MountainClimber', 6, 330.00, 'Mountain'); 42 | insert into bikes values (5, 'Beach Cruiser', 12, 220, 'Cruiser'); 43 | 44 | select category from bikes group by category order by quantity desc; 45 | 46 | select * from bikes where category = 'Mountain' order by price desc; 47 | select * from bikes where category = 'Racing' order by price desc; 48 | select * from bikes where category = 'Cruiser' order by price desc; 49 | 50 | select sum(quantity) from bikes; 51 | 52 | /* Karaoke selector */ 53 | 54 | select title from songs; 55 | select title from songs where released > 1990 or mood = 'epic'; 56 | select title from songs where released > 1990 and mood = 'epic' and duration < 240; 57 | 58 | /* Exercise logs */ 59 | 60 | create table exercise_logs ( 61 | id integer primary key autoincrement, 62 | type, text, minutes integer, 63 | calories integer, 64 | heart_rate integer 65 | ); 66 | create table drs_favorites ( 67 | id integer primary key, 68 | type text, 69 | reason text 70 | ); 71 | 72 | insert into exercise_logs(type, minutes, calories, heart_rate) values ('biking', 30, 100, 110); 73 | insert into drs_favorites(type, reason) values ('biking', 'improves endurance and flexibility.'); 74 | 75 | /* subquery - selects all activities that the user did that are recommended by doctor for cardio health */ 76 | select * from exercise_logs where type in (select type from drs_favorites where reason like "%cardiovascular%"); 77 | 78 | /* table of all types of activity and the total amount of calories burned by doing that activity */ 79 | select type, sum(calories) as total_calories from exercise_logs group by type; 80 | 81 | select type, sum(calories) as total_calories 82 | from exercise_logs 83 | group by type 84 | having total_calories > 150; /* having applies to the grouped condition */ 85 | 86 | /* 50-90% of max heart rate for activity */ 87 | select count(*) from exercise_logs 88 | where heart_rate >= round(.5 * (220 -30)) 89 | and heart_rate <= round(.9 * (220 - 30)); 90 | 91 | /* add column for activity's target heart rate status */ 92 | select type, heart_rate, 93 | case 94 | when heart_rate > 220 - 30 then 'above max' 95 | when heart_rate > round(.9 * (220 - 30)) then 'above target' 96 | when heart_rate > round(.5 * (220 - 30)) then 'within target' 97 | else 'below target' 98 | end as 'heart_rate_zone' 99 | from exercise_logs; 100 | 101 | /* Group the count of exercises by each heart rate zone */ 102 | select count(*), 103 | case 104 | when heart_rate > 220 - 30 then 'above max' 105 | when heart_rate > round(.9 * (220 - 30)) then 'above target' 106 | when heart_rate > round(.5 * (220 - 30)) then 'within target' 107 | else 'below target' 108 | end as 'heart_rate_zone' 109 | from exercise_logs 110 | group by heart_rate_zone; 111 | 112 | /* Playlist maker */ 113 | 114 | select title from songs where artist in (select name from artists where genre = 'Pop'); 115 | 116 | /* Wordiest author */ 117 | 118 | /* from books, author that has written more than a million words */ 119 | select author, sum(words) as total_words from books group by author having total_words > 1000000; 120 | 121 | /* author whose average book is over 150,000 words */ 122 | select author, avg(words) as avg_words from books group by author having avg_words > 150000; 123 | 124 | /* Gradebook */ 125 | 126 | CREATE TABLE student_grades ( 127 | id INTEGER PRIMARY KEY AUTOINCREMENT, 128 | name TEXT, 129 | number_grade INTEGER, 130 | fraction_completed REAL); 131 | 132 | INSERT INTO student_grades (name, number_grade, fraction_completed) 133 | VALUES ("Winston", 90, 0.805); 134 | INSERT INTO student_grades (name, number_grade, fraction_completed) 135 | VALUES ("Winnefer", 95, 0.901); 136 | INSERT INTO student_grades (name, number_grade, fraction_completed) 137 | VALUES ("Winsteen", 85, 0.906); 138 | INSERT INTO student_grades (name, number_grade, fraction_completed) 139 | VALUES ("Wincifer", 66, 0.7054); 140 | INSERT INTO student_grades (name, number_grade, fraction_completed) 141 | VALUES ("Winster", 76, 0.5013); 142 | INSERT INTO student_grades (name, number_grade, fraction_completed) 143 | VALUES ("Winstonia", 82, 0.9045); 144 | 145 | select name, number_grade, round(100.00 * fraction_completed) as percent_completed from student_grades; 146 | 147 | /* how many students have earned which letter grade */ 148 | select count(number_grade), 149 | case 150 | when number_grade > 90 then 'A' 151 | when number_grade > 80 then 'B' 152 | when number_grade > 70 then 'C' 153 | else 'F' 154 | end as 'letter_grade' 155 | from student_grades 156 | group by letter_grade; 157 | 158 | /* Marvel characters database 159 | https://gist.github.com/pamelafox/585364b62390ea720858 160 | */ 161 | 162 | /* Marvel Heroes and Villains 163 | Based on the website http://marvel.wikia.com/Main_Page 164 | with popularity data from http://observationdeck.io9.com/something-i-found-marvel-character-popularity-poll-cb-1568108064 165 | and power grid data from http://marvel.wikia.com/Power_Grid#Power 166 | Collected by: https://www.khanacademy.org/profile/Mentrasto/ 167 | */ 168 | 169 | CREATE TABLE marvels (ID INTEGER PRIMARY KEY, 170 | name TEXT, 171 | popularity INTEGER, 172 | alignment TEXT, 173 | gender TEXT, 174 | height_m NUMERIC, 175 | weight_kg NUMERIC, 176 | hometown TEXT, 177 | intelligence INTEGER, 178 | strength INTEGER, 179 | speed INTEGER, 180 | durability INTEGER, 181 | energy_Projection INTEGER, 182 | fighting_Skills INTEGER); 183 | 184 | INSERT INTO marvels VALUES(1, "Spider Man", 1, "Good", "Male", 1.78, 75.75, "USA", 4, 4, 3, 3, 1, 4); 185 | INSERT INTO marvels VALUES(2, "Iron Man", 20, "Neutral", "Male", 1.98, 102.58, "USA", 6, 6, 5, 6, 6, 4); 186 | INSERT INTO marvels VALUES(3, "Hulk", 18, "Neutral", "Male", 2.44, 635.29, "USA", 6, 7, 3, 7, 5, 4); 187 | INSERT INTO marvels VALUES(4, "Wolverine", 3, "Good", "Male", 1.6, 88.46, "Canada", 2, 4, 2, 4, 1, 7); 188 | INSERT INTO marvels VALUES(5, "Thor", 5, "Good", "Male", 1.98, 290.3, "Norway", 2, 7, 7, 6, 6, 4); 189 | INSERT INTO marvels VALUES(6, "Green Goblin", 91, "Bad", "Male", 1.93, 174.63, "USA", 4, 4, 3, 4, 3, 3); 190 | INSERT INTO marvels VALUES(7, "Magneto", 11, "Neutral", "Male", 1.88, 86.18, "Germany", 6, 3, 5, 4, 6, 4); 191 | INSERT INTO marvels VALUES(8, "Thanos", 47, "Bad", "Male", 2.01, 446.79, "Titan", 6, 7, 7, 6, 6, 4); 192 | INSERT INTO marvels VALUES(9, "Loki", 32, "Bad", "Male", 1.93, 238.14, "Jotunheim", 5, 5, 7, 6, 6, 3); 193 | INSERT INTO marvels VALUES(10, "Doctor Doom", 19, "Bad", "Male", 2.01, 188.24, "Latveria", 6, 4, 5, 6, 6, 4); 194 | INSERT INTO marvels VALUES(11, "Jean Greay", 8, "Good", "Female", 1.68, 52.16, "USA", 3, 2, 7, 7, 7, 4); 195 | INSERT INTO marvels VALUES(12, "Rogue", 4, "Good", "Female", 1.73, 54.43, "USA", 7, 7, 7, 7, 7, 7); 196 | 197 | /* most popular and least popular */ 198 | select name, min(popularity) from marvels; 199 | select name, max(popularity) from marvels; 200 | 201 | 202 | 203 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /sql/khan-academ-sql/02-relational-queries.sql: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Covers joins and multi table queries. I also suggest watching 4 | this laracast episode: https://laracasts.com/lessons/understanding-joins 5 | 6 | */ 7 | 8 | /* Student grades */ 9 | 10 | CREATE TABLE students (id INTEGER PRIMARY KEY, 11 | first_name TEXT, 12 | last_name TEXT, 13 | email TEXT, 14 | phone TEXT, 15 | birthdate TEXT, 16 | buddy_id INTEGER); 17 | 18 | INSERT INTO students (first_name, last_name, email, phone, birthdate) 19 | VALUES ("Peter", "Rabbit", "peter@rabbit.com", "555-6666", "2002-06-24", 2); 20 | INSERT INTO students (first_name, last_name, email, phone, birthdate) 21 | VALUES ("Alice", "Wonderland", "alice@wonderland.com", "555-4444", "2002-07-04", 1); 22 | INSERT INTO students 23 | VALUES (3, "Aladdin", "Lampland", "aladdin@lampland.com", "555-3333", "2001-05-10", 4); 24 | INSERT INTO students 25 | VALUES (4, "Simba", "Kingston", "simba@kingston.com", "555-1111", "2001-12-24", 3); 26 | 27 | CREATE TABLE student_grades (id INTEGER PRIMARY KEY, 28 | student_id INTEGER, 29 | test TEXT, 30 | grade INTEGER); 31 | 32 | INSERT INTO student_grades (student_id, test, grade) 33 | VALUES (1, "Nutrition", 95); 34 | INSERT INTO student_grades (student_id, test, grade) 35 | VALUES (2, "Nutrition", 92); 36 | INSERT INTO student_grades (student_id, test, grade) 37 | VALUES (1, "Chemistry", 85); 38 | INSERT INTO student_grades (student_id, test, grade) 39 | VALUES (2, "Chemistry", 95); 40 | 41 | SELECT * FROM student_grades; 42 | 43 | /* cross join */ 44 | SELECT * FROM student_grades, students; 45 | 46 | /* implicit inner join */ 47 | SELECT * FROM student_grades, students 48 | WHERE student_grades.student_id = students.id; 49 | 50 | /* explicit inner join - JOIN */ 51 | SELECT students.first_name, students.last_name, students.email, student_grades.test, student_grades.grade FROM students 52 | JOIN student_grades 53 | ON students.id = student_grades.student_id 54 | WHERE grade > 90; 55 | 56 | create table student_projects (id integer primary key, student_id integer, title text); 57 | 58 | insert into student_projects (student_id, title) values (1, 'Carrotapault'); 59 | 60 | /* inner join only creates records for matches between the two tables */ 61 | select students.first_name, students.last_name, student_projects.title 62 | from students 63 | join student_projects 64 | on students.id = student_projects.student_id; 65 | 66 | /* outer join - list of all students and their projects, regardless if they have a project or not */ 67 | select students.first_name, students.last_name, student_projects.title 68 | from students 69 | left outer join student_projects /* outer means to retain the rows even if there is no match */ 70 | on students.id = student_projects.student_id; 71 | 72 | /* self join - ids are in the same table */ 73 | select students.first_name, students.last_name, buddies.email as buddy_email 74 | from students 75 | join students buddies /* alias for table */ 76 | on students.buddy_id = buddies.id; 77 | 78 | /* Bobby's hobbies */ 79 | 80 | /* display a table of people and their hobbies */ 81 | select persons.name, hobbies.name from hobbies join persons on persons.id = hobbies.person_id; 82 | 83 | /* display only Bobby's hobbies */ 84 | select persons.name, hobbies.name 85 | from persons join hobbies 86 | where persons.name = 'Bobby McBobbyFace' and hobbies.person_id = persons.id; 87 | 88 | /* Customers' orders */ 89 | 90 | CREATE TABLE customers ( 91 | id INTEGER PRIMARY KEY AUTOINCREMENT, 92 | name TEXT, 93 | email TEXT); 94 | 95 | INSERT INTO customers (name, email) VALUES ("Doctor Who", "doctorwho@timelords.com"); 96 | INSERT INTO customers (name, email) VALUES ("Harry Potter", "harry@potter.com"); 97 | INSERT INTO customers (name, email) VALUES ("Captain Awesome", "captain@awesome.com"); 98 | 99 | CREATE TABLE orders ( 100 | id INTEGER PRIMARY KEY AUTOINCREMENT, 101 | customer_id INTEGER, 102 | item TEXT, 103 | price REAL); 104 | 105 | INSERT INTO orders (customer_id, item, price) 106 | VALUES (1, "Sonic Screwdriver", 1000.00); 107 | INSERT INTO orders (customer_id, item, price) 108 | VALUES (2, "High Quality Broomstick", 40.00); 109 | INSERT INTO orders (customer_id, item, price) 110 | VALUES (1, "TARDIS", 1000000.00); 111 | 112 | /* select all 'customers' and their orders even if they have not ordered before */ 113 | select customers.name, customers.email, orders.item, orders.price 114 | from customers 115 | left outer join orders 116 | on customers.id = orders.customer_id; 117 | 118 | /* show a list of all customers and their total order volume */ 119 | select customers.name, customers.email, sum(orders.price) as total_spending 120 | from customers 121 | left outer join orders 122 | on customers.id = orders.customer_id 123 | group by customers.email 124 | order by total_spending desc; 125 | 126 | /* Harry Potter sequels - self join */ 127 | 128 | select movies.title, sequel.title 129 | from movies 130 | left outer join movies sequel 131 | on movies.sequel_id = sequel.id; 132 | 133 | /* Friendbook */ 134 | 135 | select persons.fullname, hobbies.name 136 | from persons 137 | join hobbies 138 | on persons.id = hobbies.person_id; 139 | 140 | select persons1.fullname, persons2.fullname 141 | from friends 142 | join persons persons1 143 | on persons1.id = friends.person1_id 144 | join persons persons2 145 | on persons2.id = friends.person2_id; 146 | 147 | /* 148 | Famous persons project 149 | Movie stars: What movies are they in? Are they married to each other? 150 | Singers: What songs did they write? Where are they from? 151 | Authors: What books did they write? 152 | Fictional characters: How are they related to other characters? What books do they show up in? 153 | */ 154 | 155 | 156 | 157 | /* 158 | Query planning and optimization: parse -> optimize -> execute 159 | 160 | query tuning with a sql profiler. manual optimization to improve the execution plan. 161 | 162 | create indexes makes repeated queries more efficient. 163 | 164 | query planner for sqlite: https://www.sqlite.org/queryplanner.html 165 | 166 | 167 | */ 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /sql/udemy-mysql-bootcamp/01-firstActivity.sql: -------------------------------------------------------------------------------- 1 | /* $ mysql -uroot -p */ 2 | help; 3 | help contents; 4 | show databases; 5 | select @@hostname; 6 | -------------------------------------------------------------------------------- /sql/udemy-mysql-bootcamp/02-creating-databases.sql: -------------------------------------------------------------------------------- 1 | create database udemy_mysql_bootcamp; 2 | 3 | drop database database_name; 4 | 5 | use udemy_mysql_bootcamp; 6 | select database(); /* udemy_mysql_bootcamp */ 7 | 8 | /* datatypes: int for numbers and varchar for strings */ 9 | 10 | -- CREATE TABLE tablename 11 | -- ( 12 | -- column_name data_type, 13 | -- column_name data_type 14 | -- ); 15 | 16 | CREATE TABLE cats 17 | ( 18 | name VARCHAR(100), 19 | age INT 20 | ); 21 | 22 | SHOW TABLES; 23 | 24 | /* Display columns for a table (same result) */ 25 | SHOW COLUMNS FROM cats; 26 | DESC cats; /* stands for describe */ 27 | 28 | DROP TABLE cats; 29 | 30 | /* create, show and delete a table for pastries */ 31 | CREATE TABLE pastries 32 | ( 33 | name VARCHAR(50), 34 | quantity INT 35 | ); 36 | 37 | SHOW TABLES; 38 | 39 | DESC pastries; 40 | 41 | DROP TABLE pastries; -------------------------------------------------------------------------------- /sql/udemy-mysql-bootcamp/03-inserting-data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO cats(name, age) VALUES ("Jetson", 7); /* order matters */ 2 | 3 | SELECT * FROM cats; 4 | 5 | /* multiple insert syntax */ 6 | INSERT INTO cats 7 | (name, age) 8 | VALUES 9 | ('Snowbell', 13), 10 | ('Whiskers', 2), 11 | ('Tinkerbell', 6); 12 | 13 | /* Challenge */ 14 | CREATE TABLE people 15 | (first_name VARCHAR(100), last_name VARCHAR(100), age INT); 16 | 17 | ALTER TABLE people MODIFY first_name VARCHAR(20); 18 | ALTER TABLE people MODIFY last_name VARCHAR(20); 19 | 20 | SHOW TABLES; 21 | DESC people; 22 | 23 | INSERT INTO people VALUES ('Tina', 'Belcher', 13); 24 | 25 | INSERT INTO people(last_name, first_name, age) VALUES ('Belcher', 'Linda', 45); 26 | 27 | INSERT INTO people 28 | (first_name, last_name, age) 29 | VALUES 30 | ('Phillip', 'Frond', 38), 31 | ('Calvin', 'Fischoeder', 70); 32 | 33 | SELECT * FROM people; 34 | 35 | DROP TABLE people; 36 | 37 | /* displays errors, if any */ 38 | SHOW WARNINGS; 39 | 40 | /* create table with default values and not null constraints */ 41 | CREATE TABLE cats2 42 | ( 43 | name VARCHAR(20) NOT NULL DEFAULT 'John Doe', 44 | age INT DEFAULT 99; 45 | ); 46 | 47 | /* Define table with primary key */ 48 | CREATE TABLE unique_cats 49 | ( 50 | id INT NOT NULL AUTO_INCREMENT, 51 | name VARCHAR(100) DEFAULT 'unnamed', 52 | age INT, 53 | PRIMARY KEY (id) 54 | ); 55 | 56 | /* id will automatically be assigned */ 57 | INSERT INTO unique_cats 58 | (name, age) 59 | VALUES 60 | ('Phideaux', 19), 61 | ('FiFi', 19), 62 | ('Cheatah', 100); 63 | 64 | /* Challenge */ 65 | CREATE TABLE employees 66 | ( 67 | id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 68 | first_name VARCHAR(50) NOT NULL, 69 | last_name VARCHAR(50) NOT NULL, 70 | middle_name VARCHAR(50), 71 | age INT NOT NULL, 72 | current_state VARCHAR(50) NOT NULL DEFAULT 'employed' 73 | ); 74 | 75 | insert into employees 76 | (first_name, last_name, age) 77 | VALUES 78 | ('Connor', 'Leech', 29); 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /sql/udemy-mysql-bootcamp/04-crud.sql: -------------------------------------------------------------------------------- 1 | SELECT column_1, column2 FROM table_name; 2 | 3 | SELECT * FROM cats WHERE age=4; 4 | 5 | SELECT * FROM cats WHERE name='EgG'; /* case insensitive */ 6 | 7 | /* SELECT Challenge */ 8 | select cat_id from cats where cat_id >= 1 and cat_id <= 7; 9 | select name, breed from cats; 10 | select name, age from cats where breed='tabby'; 11 | 12 | select cat_id, age 13 | from cats as c 14 | where c.cat_id = c.age; 15 | 16 | /* Aliases */ 17 | SELECT name AS 'cat name', breed AS 'kitty breed' FROM cats; 18 | 19 | /* Update */ 20 | UPDATE cats SET breed='Shorthair' WHERE breed='Tabby'; 21 | UPDATE cats SET age=14 WHERE name='Misty'; 22 | 23 | /* Update challenge */ 24 | update cats set name='Jack' where name='Jackson'; 25 | update cats set breed="British Shorthair" where name="Ringo"; 26 | update cats set age=12 where breed='Maine Coon'; 27 | 28 | /* Delete */ 29 | DELETE FROM cats WHERE age=4; 30 | delete from cats; /* deletes all cats! */ 31 | DELETE FROM cats WHERE cat_id=age; 32 | -------------------------------------------------------------------------------- /sql/udemy-mysql-bootcamp/05-crud-challenges.sql: -------------------------------------------------------------------------------- 1 | /* todo */ -------------------------------------------------------------------------------- /sql/udemy-mysql-bootcamp/06-string-functions.sql: -------------------------------------------------------------------------------- 1 | /* running SQL files */ 2 | CREATE TABLE cats 3 | ( 4 | cat_id INT NOT NULL AUTO_INCREMENT, 5 | name VARCHAR(100), 6 | age INT, 7 | PRIMARY KEY(cat_id) 8 | ); 9 | 10 | mysql-ctl cli 11 | 12 | use cat_app; 13 | 14 | source first_file.sql 15 | 16 | DESC cats; 17 | 18 | 19 | 20 | INSERT INTO cats(name, age) 21 | VALUES('Charlie', 17); 22 | 23 | INSERT INTO cats(name, age) 24 | VALUES('Connie', 10); 25 | 26 | SELECT * FROM cats; 27 | 28 | source testing/insert.sql 29 | 30 | /* Load in Book data */ 31 | CREATE TABLE books 32 | ( 33 | book_id INT NOT NULL AUTO_INCREMENT, 34 | title VARCHAR(100), 35 | author_fname VARCHAR(100), 36 | author_lname VARCHAR(100), 37 | released_year INT, 38 | stock_quantity INT, 39 | pages INT, 40 | PRIMARY KEY(book_id) 41 | ); 42 | 43 | INSERT INTO books (title, author_fname, author_lname, released_year, stock_quantity, pages) 44 | VALUES 45 | ('The Namesake', 'Jhumpa', 'Lahiri', 2003, 32, 291), 46 | ('Norse Mythology', 'Neil', 'Gaiman',2016, 43, 304), 47 | ('American Gods', 'Neil', 'Gaiman', 2001, 12, 465), 48 | ('Interpreter of Maladies', 'Jhumpa', 'Lahiri', 1996, 97, 198), 49 | ('A Hologram for the King: A Novel', 'Dave', 'Eggers', 2012, 154, 352), 50 | ('The Circle', 'Dave', 'Eggers', 2013, 26, 504), 51 | ('The Amazing Adventures of Kavalier & Clay', 'Michael', 'Chabon', 2000, 68, 634), 52 | ('Just Kids', 'Patti', 'Smith', 2010, 55, 304), 53 | ('A Heartbreaking Work of Staggering Genius', 'Dave', 'Eggers', 2001, 104, 437), 54 | ('Coraline', 'Neil', 'Gaiman', 2003, 100, 208), 55 | ('What We Talk About When We Talk About Love: Stories', 'Raymond', 'Carver', 1981, 23, 176), 56 | ("Where I'm Calling From: Selected Stories", 'Raymond', 'Carver', 1989, 12, 526), 57 | ('White Noise', 'Don', 'DeLillo', 1985, 49, 320), 58 | ('Cannery Row', 'John', 'Steinbeck', 1945, 95, 181), 59 | ('Oblivion: Stories', 'David', 'Foster Wallace', 2004, 172, 329), 60 | ('Consider the Lobster', 'David', 'Foster Wallace', 2005, 92, 343); 61 | 62 | 63 | SELECT database(); 64 | 65 | CREATE DATABASE book_shop; 66 | 67 | use book_shop; 68 | 69 | show tables; 70 | 71 | source book_data.sql 72 | 73 | DESC books; 74 | 75 | SELECT * FROM books; 76 | 77 | /* CONCAT */ 78 | SELECT 79 | CONCAT(author_fname, ' ', author_lname) 80 | AS 'full name' 81 | FROM books; 82 | 83 | SELECT author_fname AS first, author_lname AS last, 84 | CONCAT(author_fname, ' ', author_lname) AS full 85 | FROM books; 86 | 87 | SELECT 88 | CONCAT_WS(' - ', title, author_fname, author_lname) 89 | FROM books; 90 | 91 | /* SUBSTRING */ 92 | SELECT SUBSTRING(title, 1, 10) AS 'short title' FROM books; 93 | 94 | SELECT SUBSTR(title, 1, 10) AS 'short title' FROM books; 95 | 96 | SELECT CONCAT 97 | ( 98 | SUBSTRING(title, 1, 10), 99 | '...' 100 | ) AS 'short title' 101 | FROM books; 102 | 103 | /* REPLACE */ 104 | SELECT REPLACE('Hello World', 'Hell', '%$#@'); 105 | 106 | SELECT REPLACE(title, 'e ', '3') FROM books; 107 | 108 | /* REVERSE */ 109 | SELECT REVERSE(author_fname) FROM books; 110 | 111 | /* CHAR_LENGTH */ 112 | SELECT author_lname, CHAR_LENGTH(author_lname) AS 'length' FROM books; 113 | 114 | SELECT CONCAT(author_lname, ' is ', CHAR_LENGTH(author_lname), ' characters long') FROM books; 115 | 116 | /* UPPER and LOWER */ 117 | SELECT UPPER(title) FROM books; 118 | 119 | SELECT CONCAT('MY FAVORITE BOOK IS ', UPPER(title)) FROM books; 120 | 121 | SELECT CONCAT('MY FAVORITE BOOK IS ', LOWER(title)) FROM books; 122 | 123 | 124 | /* Challenge solutions */ 125 | 126 | 127 | SELECT 128 | author_lname AS forwards, 129 | REVERSE(author_lname) AS backwards 130 | FROM books; 131 | 132 | 133 | SELECT 134 | UPPER 135 | ( 136 | CONCAT(author_fname, ' ', author_lname) 137 | ) AS 'full name in caps' 138 | FROM books; 139 | 140 | 141 | SELECT 142 | CONCAT(title, ' was released in ', released_year) AS blurb 143 | FROM books; 144 | SELECT 145 | title, 146 | CHAR_LENGTH(title) AS 'character count' 147 | FROM books; 148 | 149 | 150 | SELECT 151 | CONCAT(SUBSTRING(title, 1, 10), '...') AS 'short title', 152 | CONCAT(author_lname, ',', author_fname) AS author, 153 | CONCAT(stock_quantity, ' in stock') AS quantity 154 | FROM books; -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/01_string_reversal.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Given a string, return a new string with the reversed 4 | order of characters 5 | 6 | reverse('apple') => 'elppa' 7 | */ 8 | 9 | function reverse(str){ 10 | let result = ''; 11 | for(var i = str.length; i >= 0; i--){ 12 | result += str.charAt(i); 13 | } 14 | return result; 15 | } 16 | 17 | // use built in array and string 18 | function reverseSolution1(str){ 19 | return str.split('') 20 | .reverse() 21 | .join(''); 22 | } 23 | 24 | // use for ... of and prepend 25 | function reverseSolution2(str){ 26 | let result = ''; 27 | for(let char of str){ 28 | result = char + result; 29 | } 30 | return result; 31 | } 32 | 33 | // use array reduce 34 | function reverseSolution3(str){ 35 | return str 36 | .split('') 37 | .reduce((result, letter)=> letter + result, ''); 38 | } 39 | 40 | console.log(reverseSolution3('hello')); 41 | 42 | module.exports = reverse; -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/02_palindromes.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Given a string, return true if the string is a palindrome 3 | // or false if it is not. Palindromes are strings that 4 | // form the same word if it is reversed. *Do* include spaces 5 | // and punctuation in determining if the string is a palindrome. 6 | // --- Examples: 7 | // palindrome("abba") === true 8 | // palindrome("abcdefg") === false 9 | 10 | function palindrome(str){ 11 | const middle = Math.floor(str.length/2); 12 | 13 | const firsthalf = str.substring(0, middle); 14 | const secondhalf = (str.length % 2 === 0)? str.substring(middle) : str.substring(middle + 1); 15 | 16 | return (firsthalf === reverse(secondhalf)); 17 | } 18 | 19 | function reverse(str){ 20 | return str.split('').reduce((accum, letter)=> letter + accum, ''); 21 | } 22 | 23 | 24 | // first solution. No need for splitting the terms into halves! 25 | function palindromeSolution1(str){ 26 | const reversed = str.split('').reduce((accum, letter)=> letter + accum, ''); 27 | return reversed === str; 28 | } 29 | 30 | 31 | // second solution: compare each letter from beginning and end of array 32 | function palindromeSolution2(str){ 33 | return str.split('').every((current, index, arr)=>{ 34 | return (current === arr[arr.length - index - 1]); 35 | }); 36 | } 37 | 38 | console.log(palindromeSolution2("abba")); 39 | console.log(palindromeSolution2("abcdefg")); -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/03_integer_reversal.js: -------------------------------------------------------------------------------- 1 | 2 | // reverseInteger(500) === 5 3 | // reverseInteger(981) === 189 4 | // reverseInteger(-15) === -51 5 | // reverseInteger(-90) === -9 6 | 7 | function reverseInteger(integer) { 8 | let isNegative = false; 9 | 10 | if(integer < 0) isNegative = true; 11 | 12 | const reversed = String(integer).split('').reverse().join(''); 13 | 14 | return (isNegative) ? parseInt(`-${reversed}`) : parseInt(`${reversed}`); 15 | } 16 | 17 | 18 | 19 | // You can use Math.sign to determine the +/- of a number 20 | // (could use reverse function as above) 21 | 22 | function reverseIntegerSolution(integer){ 23 | const reversed = integer.toString().split('').reduce((current, accum)=>{ 24 | return accum + current; 25 | }, ''); 26 | 27 | return Math.sign(integer) * parseInt(reversed); 28 | } 29 | 30 | console.log(reverseIntegerSolution(-15)); 31 | -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/04_max_chars.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Given a string, return the character that is most 3 | // commonly used in the string. 4 | // --- Examples 5 | // maxChar("abcccccccd") === "c" 6 | // maxChar("apple 1231111") === "1" 7 | 8 | function maxChar(str) { 9 | let map = {}; 10 | let maxCount = 0; 11 | let letter; 12 | 13 | str.split('').forEach((letter)=>{ 14 | map[letter] = (map[letter]) ? map[letter] + 1 : 1; 15 | }); 16 | 17 | for(key in map){ 18 | if(map[key] > maxCount){ 19 | maxCount = map[key]; 20 | letter = key; 21 | } 22 | 23 | } 24 | 25 | return letter; 26 | } 27 | 28 | 29 | 30 | function maxCharSolution(str){ 31 | const charMap = {}; 32 | let max = 0; 33 | let maxChar = ''; 34 | 35 | for(let char of str) { 36 | if(charMap[char]){ 37 | charMap[char]++; 38 | } else { 39 | charMap[char] = 1; 40 | } 41 | } 42 | 43 | for(char in charMap){ 44 | if(charMap[char] > max){ 45 | max = charMap[char]; 46 | maxChar = char; 47 | } 48 | } 49 | 50 | return maxChar; 51 | } 52 | 53 | console.log(maxCharSolution("abcccccccd")); 54 | 55 | 56 | /****************** 57 | Most common string questions: 58 | 59 | - What is the most common character in this string? 60 | - Does string A have the same characters as string B? (anagram) 61 | - Does the string have any repeating characters in it? 62 | ******************/ -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/05_fizzbuzz.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Write a program that console logs the numbers 3 | // from 1 to n. But for multiples of three print 4 | // “fizz” instead of the number and for the multiples 5 | // of five print “buzz”. For numbers which are multiples 6 | // of both three and five print “fizzbuzz”. 7 | // --- Example 8 | // fizzBuzz(5); 9 | // 1 10 | // 2 11 | // fizz 12 | // 4 13 | // buzz 14 | 15 | 16 | function fizzBuzz(integer){ 17 | let output = ''; 18 | for(var i = 1; i <= integer; i++){ 19 | if(i % 3 === 0 && i % 5 === 0){ 20 | output = "fizzbuzz"; 21 | } else if (i % 3 === 0){ 22 | output = "fizz"; 23 | } else if (i % 5 === 0){ 24 | output = "buzz"; 25 | } else { 26 | output = i; 27 | } 28 | console.log(output); 29 | } 30 | } 31 | 32 | fizzBuzz(15); -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/06_array_chunking.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Given an array and chunk size, divide the array into many subarrays 3 | // where each subarray is of length size 4 | // --- Examples 5 | // chunk([1, 2, 3, 4], 2) --> [[ 1, 2], [3, 4]] 6 | // chunk([1, 2, 3, 4, 5], 2) --> [[ 1, 2], [3, 4], [5]] 7 | // chunk([1, 2, 3, 4, 5, 6, 7, 8], 3) --> [[ 1, 2, 3], [4, 5, 6], [7, 8]] 8 | // chunk([1, 2, 3, 4, 5], 4) --> [[ 1, 2, 3, 4], [5]] 9 | // chunk([1, 2, 3, 4, 5], 10) --> [[ 1, 2, 3, 4, 5]] 10 | 11 | function chunk(array, size) { 12 | let currentChunk = 0; 13 | let result = []; 14 | let chunk = []; 15 | 16 | for(var i = 0; i < array.length; i++){ 17 | if(currentChunk == size){ 18 | result.push(chunk); 19 | currentChunk = 0; 20 | chunk = []; 21 | } 22 | 23 | currentChunk++; 24 | chunk.push(array[i]); 25 | } 26 | 27 | if(chunk.length) result.push(chunk); 28 | 29 | return result; 30 | } 31 | 32 | 33 | function chunkSolution1(array, size){ 34 | // create empty array to hold all other arrays 35 | const chunked = []; 36 | 37 | for(let element of array){ 38 | // retrieve the last element in the chunked array 39 | const last = chunked[chunked.length - 1]; 40 | 41 | // if there is no last element or it's length is the size 42 | if(!last || last.length === size){ 43 | 44 | // add a new chunk with the current element 45 | chunked.push([element]); 46 | } else { 47 | // add the current element into the chunk 48 | last.push(element); 49 | } 50 | } 51 | 52 | return chunked; 53 | } 54 | 55 | 56 | // Rolling window with startIndex variable 57 | // Good practice for using Array.prototype.slice 58 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice 59 | function chunkSolution2(array, size){ 60 | let startIndex = 0; 61 | let output = []; 62 | 63 | while(startIndex < array.length){ 64 | 65 | output.push(array.slice(startIndex, startIndex + size)); 66 | 67 | startIndex += size; 68 | } 69 | 70 | return output; 71 | } 72 | 73 | 74 | 75 | console.log(chunkSolution2([1, 2, 3, 4], 2)); 76 | console.log(chunkSolution2([1, 2, 3, 4, 5, 6, 7, 8], 3)); 77 | console.log(chunkSolution2([1, 2, 3, 4, 5], 4)); 78 | -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/07_anagrams.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Check to see if two provided strings are anagrams of eachother. 3 | // One string is an anagram of another if it uses the same characters 4 | // in the same quantity. Only consider characters, not spaces 5 | // or punctuation. Consider capital letters to be the same as lower case 6 | // --- Examples 7 | // anagrams('rail safety', 'fairy tales') --> True 8 | // anagrams('RAIL! SAFETY!', 'fairy tales') --> True 9 | // anagrams('Hi there', 'Bye there') --> False 10 | 11 | function anagrams(string1, string2){ 12 | let sorted1 = string1.replace(/[^\w]/g, '').toLowerCase().split('').sort().join(''); 13 | let sorted2 = string2.replace(/[^\w]/g, '').toLowerCase().split('').sort().join(''); 14 | 15 | return (sorted1 === sorted2); 16 | 17 | } 18 | 19 | // console.log(anagrams('rail safety', 'fairy tales')); // true 20 | // console.log(anagrams('RAIL! SAFETY!', 'fairy tales')); // true 21 | // console.log(anagrams('Hi there', 'Bye there')); // false 22 | 23 | // Regular Expressions: 24 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp 25 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions 26 | // string.replace(/[^\w]/g, "") --> removes any non-alphanumeric characters 27 | 28 | // Object.keys(obj).length --> gets the number of keys in a JS object 29 | 30 | 31 | function anagramsSolution1(string1, string2){ 32 | let obj1 = {}, 33 | obj2 = {}, 34 | s1 = string1.replace(/[^\w]/g, '').toLowerCase().split(''); 35 | s2 = string2.replace(/[^\w]/g, '').toLowerCase().split(''); 36 | 37 | if(s1.length !== s2.length) return false; 38 | 39 | s1.forEach((letter)=>{ 40 | obj1[letter] = (obj1[letter]) ? obj1[letter] + 1 : 1; 41 | }); 42 | 43 | s2.forEach((letter)=>{ 44 | obj2[letter] = (obj2[letter]) ? obj2[letter] + 1 : 1; 45 | }); 46 | 47 | for(var char in obj1){ 48 | if(obj1[char] !== obj2[char]) return false; 49 | } 50 | 51 | return true; 52 | } 53 | 54 | 55 | 56 | console.log(anagramsSolution1('rail safety', 'fairy tales')); //True 57 | console.log(anagramsSolution1('RAIL! SAFETY!', 'fairy tales')); // True 58 | console.log(anagramsSolution1('Hi there', 'Bye there')); // False 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/08_capitalize.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Write a function that accepts a string. The function should 3 | // capitalize the first letter of each word in the string then 4 | // return the capitalized string. 5 | // --- Examples 6 | // capitalize('a short sentence') --> 'A Short Sentence' 7 | // capitalize('a lazy fox') --> 'A Lazy Fox' 8 | // capitalize('look, it is working!') --> 'Look, It Is Working!' 9 | 10 | function capitalize(string){ 11 | return string.split(' ').map((word)=>{ 12 | return word.substr(0, 1).toUpperCase() + word.substr(1); 13 | }).join(' '); 14 | } 15 | 16 | 17 | // console.log(capitalize('a short sentence')); //'A Short Sentence' 18 | // console.log(capitalize('a lazy fox')); // 'A Lazy Fox' 19 | // console.log(capitalize('look, it is working!')); // 'Look, It Is Working!' 20 | 21 | 22 | function capitalizeSolution1(string){ 23 | if(string.length === 0) return ''; 24 | 25 | let result = string[0].toUpperCase(); 26 | 27 | for(let i = 1; i < string.length; i++){ 28 | if(result[i-1] === " "){ 29 | result += string[i].toUpperCase(); 30 | } else { 31 | result += string[i]; 32 | } 33 | } 34 | 35 | return result; 36 | } 37 | 38 | console.log(capitalizeSolution1('a short sentence')); //'A Short Sentence' 39 | console.log(capitalizeSolution1('a lazy fox')); // 'A Lazy Fox' 40 | console.log(capitalizeSolution1('look, it is working!')); // 'Look, It Is Working!' 41 | -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/09_steps.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Write a function that accepts a positive number N. 3 | // The function should console log a step shape 4 | // with N levels using the # character. Make sure the 5 | // step has spaces on the right hand side! 6 | // --- Examples 7 | // steps(2) 8 | // '# ' 9 | // '##' 10 | // steps(3) 11 | // '# ' 12 | // '## ' 13 | // '###' 14 | // steps(4) 15 | // '# ' 16 | // '## ' 17 | // '### ' 18 | // '####' 19 | 20 | 21 | function steps(size){ 22 | 23 | for(let row = 0; row < size; row++){ 24 | let step = ''; 25 | 26 | for(let column = 0; column < size; column++){ 27 | if(row >= column){ 28 | step += '#'; 29 | } else { 30 | step += ' '; 31 | } 32 | 33 | } 34 | console.log(step); 35 | } 36 | } 37 | 38 | function stepsRecursive(size, row = 0, step = ''){ 39 | // base case 40 | if(size === row){ 41 | return; 42 | } 43 | 44 | // move on to next row 45 | if(size === step.length){ 46 | console.log(step); 47 | return stepsRecursive(size, row + 1); 48 | } 49 | 50 | // build current row 51 | step += (step.length <= row) ? '#' : ' '; 52 | 53 | stepsRecursive(size, row, step); 54 | } 55 | 56 | stepsRecursive(4); 57 | 58 | 59 | -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/10_pyramids.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Write a function that accepts a positive number N. 3 | // The function should console log a pyramid shape 4 | // with N levels using the # character. Make sure the 5 | // pyramid has spaces on both the left *and* right hand sides 6 | // --- Examples 7 | // pyramid(1) 8 | // '#' 9 | // pyramid(2) 10 | // ' # ' 11 | // '###' 12 | // pyramid(3) 13 | // ' # ' 14 | // ' ### ' 15 | // '#####' 16 | 17 | function pyramids(height){ 18 | const midpoint = Math.floor((2 * height - 1) / 2); 19 | 20 | 21 | for(var row = 0; row < height; row++){ 22 | let block = ''; 23 | 24 | for(var column = 0; column < 2 * height - 1; column++){ 25 | 26 | block += (midpoint - row <= column && midpoint + row >= column) ? '#' : ' '; 27 | } 28 | console.log(block); 29 | } 30 | 31 | } 32 | 33 | 34 | function pyramidsRecursive(height, row = 0, level = ''){ 35 | if(row === height) return; 36 | 37 | if(level.length === 2 * height - 1){ 38 | console.log(level); 39 | return pyramidsRecursive(height, row + 1); 40 | } 41 | 42 | const midpoint = Math.floor((2 * height - 1) / 2); 43 | let add; 44 | 45 | if(midpoint - row <= level.length && midpoint + row >= level.length){ 46 | add = '#'; 47 | } else { 48 | add = ' '; 49 | } 50 | 51 | pyramidsRecursive(height, row, level + add); 52 | 53 | } 54 | 55 | pyramidsRecursive(3); -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/11_vowels.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Write a function that returns the number of vowels 3 | // used in a string. Vowels are the characters 'a', 'e' 4 | // 'i', 'o', and 'u'. 5 | // --- Examples 6 | // vowels('Hi There!') --> 3 7 | // vowels('Why do you ask?') --> 4 8 | // vowels('Why?') --> 0 9 | 10 | function vowels(str) { 11 | let count = 0; 12 | 13 | str.split('').map((letter)=>{ 14 | letter = letter.toLowerCase() || null; 15 | if(letter == 'a' || letter == 'e' || letter == 'i' || letter == 'o' || letter == 'u'){ 16 | count++; 17 | } 18 | }); 19 | 20 | return count; 21 | } 22 | 23 | 24 | 25 | 26 | // Could uss a for ... of loop 27 | function vowels(str) { 28 | let count = 0; 29 | const checker = ['a', 'e', 'i', 'o', 'u']; 30 | 31 | for (let char of str.toLowerCase()) { 32 | if (checker.includes(char)) { 33 | count++; 34 | } 35 | } 36 | 37 | return count; 38 | } 39 | 40 | 41 | 42 | 43 | // or a regular expression: 44 | function vowels(str) { 45 | const matches = str.match(/[aeiou]/gi); 46 | return matches ? matches.length : 0; 47 | } 48 | 49 | 50 | 51 | console.log(vowels('Why do you ask?')); -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/12_spiral_matrix.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Write a function that accepts an integer N 3 | // and returns a NxN spiral matrix. 4 | // --- Examples 5 | // matrix(2) 6 | // [[undefined, undefined], 7 | // [undefined, undefined]] 8 | // matrix(3) 9 | // [[1, 2, 3], 10 | // [8, 9, 4], 11 | // [7, 6, 5]] 12 | // matrix(4) 13 | // [[1, 2, 3, 4], 14 | // [12, 13, 14, 5], 15 | // [11, 16, 15, 6], 16 | // [10, 9, 8, 7]] 17 | 18 | function matrix(n) { 19 | const results = []; 20 | 21 | for (let i = 0; i < n; i++) { 22 | results.push([]); 23 | } 24 | 25 | let counter = 1; 26 | let startColumn = 0; 27 | let endColumn = n - 1; 28 | let startRow = 0; 29 | let endRow = n - 1; 30 | while (startColumn <= endColumn && startRow <= endRow) { 31 | // Top row 32 | for (let i = startColumn; i <= endColumn; i++) { 33 | results[startRow][i] = counter; 34 | counter++; 35 | } 36 | startRow++; 37 | 38 | // Right column 39 | for (let i = startRow; i <= endRow; i++) { 40 | results[i][endColumn] = counter; 41 | counter++; 42 | } 43 | endColumn--; 44 | 45 | // Bottom row 46 | for (let i = endColumn; i >= startColumn; i--) { 47 | results[endRow][i] = counter; 48 | counter++; 49 | } 50 | endRow--; 51 | 52 | // start column 53 | for (let i = endRow; i >= startRow; i--) { 54 | results[i][startColumn] = counter; 55 | counter++; 56 | } 57 | startColumn++; 58 | } 59 | 60 | return results; 61 | } 62 | 63 | module.exports = matrix; -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/13_fib.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Print out the n-th entry in the fibonacci series. 3 | // The fibonacci series is an ordering of numbers where 4 | // each number is the sum of the preceeding two. 5 | // For example, the sequence 6 | // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] 7 | // forms the first ten entries of the fibonacci series. 8 | // Example: 9 | // fib(4) === 3 10 | 11 | 12 | // Memoization: 13 | // store the arguments of each 14 | // function call along with the result. 15 | // If function is called with the same 16 | // arguments return the precompiled result 17 | function fib(n){ 18 | if(n < 2){ 19 | return n; 20 | } 21 | 22 | return fib(n - 2) + fib(n - 1, {}); 23 | } 24 | 25 | function memoize(fn){ 26 | const cache = {}; 27 | 28 | return function(...args){ 29 | if(cache[args]){ 30 | return cache[args]; 31 | } 32 | 33 | const result = fn.apply(this, args); 34 | cache[args] = result; 35 | 36 | return result; 37 | } 38 | } 39 | 40 | fib = memoize(fib); 41 | 42 | // Recursive solution 43 | // runtime complexity: exponential (really bad) 44 | // for every increase in n we're going to get a dramatic increase in the number of function calls 45 | // function fib(n){ 46 | // if(n == 0) return 0; 47 | // if(n == 1) return 1; 48 | 49 | // return fib(n - 2) + fib(n - 1); 50 | // } 51 | 52 | // iterative solution 53 | // runtime complexity: linear 54 | // 55 | // function fib(n){ 56 | // const sequence = [0, 1]; 57 | 58 | // for(let i = 2; i <= n; i++){ 59 | // const entry = sequence[i - 2] + sequence[i - 1]; 60 | // sequence.push(entry); 61 | // } 62 | // return entry; 63 | // } 64 | 65 | console.log(fib(4)); 66 | console.log(fib(9)); -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/14_weave.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Implement the 'weave' function. Weave 3 | // receives two queues as arguments and combines the 4 | // contents of each into a new, third queue. 5 | // The third queue should contain the *alterating* content 6 | // of the two queues. The function should handle 7 | // queues of different lengths without inserting 8 | // 'undefined' into the new one. 9 | // *Do not* access the array inside of any queue, only 10 | // use the 'add', 'remove', and 'peek' functions. 11 | // --- Example 12 | // const queueOne = new Queue(); 13 | // queueOne.add(1); 14 | // queueOne.add(2); 15 | // const queueTwo = new Queue(); 16 | // queueTwo.add('Hi'); 17 | // queueTwo.add('There'); 18 | // const q = weave(queueOne, queueTwo); 19 | // q.remove() // 1 20 | // q.remove() // 'Hi' 21 | // q.remove() // 2 22 | // q.remove() // 'There' 23 | 24 | const Queue = require('./data_structures/queue'); 25 | 26 | function weave(sourceOne, sourceTwo) { 27 | const result = new Queue(); 28 | 29 | while(sourceOne.peek() || sourceTwo.peek()){ 30 | if(sourceOne.peek()){ 31 | result.add(sourceOne.peek()); 32 | sourceOne.remove(); 33 | } 34 | 35 | if(sourceTwo.peek()){ 36 | result.add(sourceTwo.peek()); 37 | sourceTwo.remove(); 38 | } 39 | } 40 | 41 | return result; 42 | } 43 | 44 | const queueOne = new Queue(); 45 | queueOne.add(1); 46 | queueOne.add(2); 47 | const queueTwo = new Queue(); 48 | queueTwo.add('Hi'); 49 | queueTwo.add('There'); 50 | const q = weave(queueOne, queueTwo); 51 | q.remove(); // 1 52 | q.remove() // 'Hi' 53 | q.remove() // 2 54 | q.remove() // 'There' 55 | 56 | module.exports = weave; -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/15_qfroms.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Implement a Queue datastructure using two stacks. 3 | // *Do not* create an array inside of the 'Queue' class. 4 | // Queue should implement the methods 'add', 'remove', and 'peek'. 5 | // For a reminder on what each method does, look back 6 | // at the Queue exercise. 7 | // --- Examples 8 | // const q = new Queue(); 9 | // q.add(1); 10 | // q.add(2); 11 | // q.peek(); // returns 1 12 | // q.remove(); // returns 1 13 | // q.remove(); // returns 2 14 | 15 | const Stack = require('./data_structures/stack'); 16 | 17 | class Queue { 18 | constructor(){ 19 | this.stack1 = new Stack(); 20 | this.stack2 = new Stack(); 21 | } 22 | 23 | add(item){ 24 | this.stack1.push(item); 25 | } 26 | 27 | remove(){ 28 | 29 | while(this.stack1.peek()){ 30 | this.stack2.push(this.stack1.pop()) 31 | } 32 | 33 | const toRemove = this.stack2.pop(); 34 | 35 | while(this.stack2.peek()){ 36 | this.stack1.push(this.stack2.pop()); 37 | } 38 | 39 | return toRemove; 40 | 41 | } 42 | 43 | peek(){ 44 | 45 | while(this.stack1.peek()){ 46 | this.stack2.push(this.stack1.pop()); 47 | } 48 | 49 | const toShow = this.stack2.peek(); 50 | 51 | while(this.stack2.peek()){ 52 | this.stack1.push(this.stack2.pop()); 53 | } 54 | 55 | return toShow; 56 | 57 | } 58 | } 59 | 60 | // const q = new Queue(); 61 | // q.add(1); 62 | // q.add(2); 63 | // console.log(q.peek()); // returns 1 64 | // console.log(q.remove()); // returns 1 65 | // console.log(q.remove()); // returns 2 66 | 67 | module.exports = Queue; -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/16_midpoint.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Return the 'middle' node of a linked list. 3 | // If the list has an even number of elements, return 4 | // the node at the end of the first half of the list. 5 | // *Do not* use a counter variable, *do not* retrieve 6 | // the size of the list, and only iterate 7 | // through the list one time. 8 | // --- Example 9 | // const l = new LinkedList(); 10 | // l.insertLast('a') 11 | // l.insertLast('b') 12 | // l.insertLast('c') 13 | // midpoint(l); // returns { data: 'b' } 14 | 15 | const { LinkedList } = require('./data_structures/linked_list'); 16 | 17 | function midpoint(list){ 18 | let slow = list.getFirst(); 19 | let fast = list.getFirst(); 20 | 21 | while(fast.next && fast.next.next){ 22 | slow = slow.next; 23 | fast = fast.next.next; 24 | } 25 | 26 | return slow; 27 | } 28 | 29 | let list = new LinkedList(); 30 | list.insertLast('a'); 31 | list.insertLast('b'); 32 | list.insertLast('c'); 33 | list.insertLast('d'); 34 | 35 | console.log(midpoint(list)); -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/17_circular.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Given a linked list, return true if the list 3 | // is circular, false if it is not. 4 | // --- Examples 5 | // const l = new List(); 6 | // const a = new Node('a'); 7 | // const b = new Node('b'); 8 | // const c = new Node('c'); 9 | // l.head = a; 10 | // a.next = b; 11 | // b.next = c; 12 | // c.next = b; 13 | // circular(l) // true 14 | 15 | const { LinkedList } = require('./data_structures/linked_list'); 16 | 17 | function circular(list){ 18 | let slow = list.head; 19 | let fast = list.head; 20 | 21 | while(fast.next && fast.next.next){ 22 | slow = slow.next; 23 | fast = fast.next.next; 24 | 25 | if(slow === fast){ 26 | return true; 27 | } 28 | } 29 | 30 | return false; 31 | } 32 | 33 | let list = new LinkedList(); 34 | list.insertLast('a'); 35 | list.insertLast('b'); 36 | list.insertLast('c'); 37 | 38 | console.log(list); -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/18_from_last.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Given a linked list, return the element n spaces 3 | // from the last node in the list. Do not call the 'size' 4 | // method of the linked list. Assume that n will always 5 | // be less than the length of the list. 6 | // --- Examples 7 | // const list = new List(); 8 | // list.insertLast('a'); 9 | // list.insertLast('b'); 10 | // list.insertLast('c'); 11 | // list.insertLast('d'); 12 | // fromLast(list, 2).data // 'b' 13 | 14 | const { LinkedList } = require('./data_structures/linked_list'); 15 | 16 | function fromLast(list, n){ 17 | let slow = list.head; 18 | let fast = list.head; 19 | 20 | while(n > 0){ 21 | fast = fast.next; 22 | n--; 23 | } 24 | 25 | while(fast.next){ 26 | slow = slow.next; 27 | fast = fast.next; 28 | } 29 | 30 | return slow; 31 | } 32 | 33 | 34 | const list = new LinkedList(); 35 | list.insertLast('a'); 36 | list.insertLast('b'); 37 | list.insertLast('c'); 38 | list.insertLast('d'); 39 | console.log(fromLast(list, 2).data) // 'b' 40 | 41 | -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/19_level_width.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Given the root node of a tree, return 3 | // an array where each element is the width 4 | // of the tree at each level. 5 | // --- Example 6 | // Given: 7 | // 0 8 | // / | \ 9 | // 1 2 3 10 | // | | 11 | // 4 5 12 | // Answer: [1, 3, 2] 13 | 14 | const { Node } = require('./data_structures/trees'); 15 | 16 | function levelWidth(root) { 17 | let counters = []; 18 | let rowCount = 0; 19 | let queue = [root, 'STOP']; 20 | 21 | while(queue.length > 1){ 22 | 23 | let first = queue.shift(); 24 | 25 | if (first === 'STOP') { 26 | counters.push(rowCount); 27 | rowCount = 0; 28 | 29 | if(queue.length > 1){ 30 | queue.push('STOP'); 31 | } 32 | 33 | continue; 34 | } 35 | 36 | queue.push(...first.children); 37 | rowCount += 1; 38 | } 39 | 40 | return counters; 41 | 42 | } 43 | 44 | const root = new Node(0); 45 | root.add(1); 46 | root.add(2); 47 | root.add(3); 48 | root.children[0].add(4); 49 | root.children[2].add(5); 50 | 51 | console.log(levelWidth(root)) // [1, 3, 2] 52 | 53 | const root2 = new Node(0); 54 | root2.add(1); 55 | root2.children[0].add(2); 56 | root2.children[0].add(3); 57 | root2.children[0].children[0].add(4); 58 | 59 | console.log(levelWidth(root2)) // [1, 1, 2, 1] 60 | -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/20_validate_bst.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Given a node, validate the binary search tree, 3 | // ensuring that every node's left hand child is 4 | // less than the parent node's value, and that 5 | // every node's right hand child is greater than 6 | // the parent 7 | 8 | function validate(node, min = null, max = null) { 9 | if (max !== null && node.data > max) { 10 | return false; 11 | } 12 | 13 | if (min !== null && node.data < min) { 14 | return false; 15 | } 16 | 17 | if (node.left && !validate(node.left, min, node.data)) { 18 | return false; 19 | } 20 | 21 | if (node.right && !validate(node.right, node.data, max)) { 22 | return false; 23 | } 24 | 25 | return true; 26 | } -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/21_eventing_system.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // Create an 'eventing' library out of the 3 | // Events class. The Events class should 4 | // have methods 'on', 'trigger', and 'off'. 5 | 6 | class Events { 7 | constructor() { 8 | this.events = {}; 9 | } 10 | 11 | // Register an event handler 12 | on(eventName, callback) { 13 | if (this.events[eventName]) { 14 | this.events[eventName].push(callback); 15 | } else { 16 | this.events[eventName] = [callback]; 17 | } 18 | } 19 | 20 | // Trigger all callbacks associated 21 | // with a given eventName 22 | trigger(eventName) { 23 | if (this.events[eventName]) { 24 | for (let cb of this.events[eventName]) { 25 | cb(); 26 | } 27 | } 28 | } 29 | 30 | // Remove all event handlers associated 31 | // with the given eventName 32 | off(eventName) { 33 | delete this.events[eventName]; 34 | } 35 | } -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/README.md: -------------------------------------------------------------------------------- 1 | # The Coding Interview Bootcamp: Algorithms + Data Structures 2 | 3 | 4 | Udemy course link: [The Coding Interview Bootcamp: Algorithms + Data Structures](https://www.udemy.com/coding-interview-bootcamp-algorithms-and-data-structure) 5 | 6 | [Source code](https://github.com/StephenGrider/algocasts) for the lessons. 7 | 8 | ## Additional Resources 9 | 10 | ### Regular Expressions 11 | 12 | - An Introduction to Regular Expressions (Regex) In JavaScript ([Medium article](https://codeburst.io/an-introduction-to-regular-expressions-regex-in-javascript-1d3559e7ac9a)) 13 | 14 | - Chapter 9: Regular Expressions ([Eloquent Javascript](https://eloquentjavascript.net/09_regexp.html)) 15 | 16 | - Regular Expressions ([Javascript.info](https://javascript.info/regular-expressions)) 17 | 18 | -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/data_structures/binary_search_tree.js: -------------------------------------------------------------------------------- 1 | // --- Directions 2 | // 1) Implement the Node class to create 3 | // a binary search tree. The constructor 4 | // should initialize values 'data', 'left', 5 | // and 'right'. 6 | // 2) Implement the 'insert' method for the 7 | // Node class. Insert should accept an argument 8 | // 'data', then create an insert a new node 9 | // at the appropriate location in the tree. 10 | // 3) Implement the 'contains' method for the Node 11 | // class. Contains should accept a 'data' argument 12 | // and return the Node in the tree with the same value. 13 | // If the value isn't in the tree return null. 14 | 15 | class Node { 16 | constructor(data) { 17 | this.data = data; 18 | this.left = null; 19 | this.right = null; 20 | } 21 | 22 | insert(data) { 23 | if (data < this.data && this.left) { 24 | this.left.insert(data); 25 | } else if (data < this.data) { 26 | this.left = new Node(data); 27 | } else if (data > this.data && this.right) { 28 | this.right.insert(data); 29 | } else if (data > this.data) { 30 | this.right = new Node(data); 31 | } 32 | } 33 | 34 | contains(data) { 35 | if (this.data === data) { 36 | return this; 37 | } 38 | 39 | if (this.data < data && this.right) { 40 | return this.right.contains(data); 41 | } else if (this.data > data && this.left) { 42 | return this.left.contains(data); 43 | } 44 | 45 | return null; 46 | } 47 | } -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/data_structures/linked_list.js: -------------------------------------------------------------------------------- 1 | 2 | class Node { 3 | constructor(data, node = null){ 4 | this.data = data; 5 | this.next = node; 6 | } 7 | } 8 | 9 | class LinkedList { 10 | constructor(){ 11 | this.head = null 12 | } 13 | 14 | insertFirst(data){ 15 | this.head = new Node(data, this.head); 16 | } 17 | 18 | size(){ 19 | let size = 0, pointer = this.head; 20 | 21 | while(pointer){ 22 | pointer = pointer.next; 23 | size++; 24 | } 25 | 26 | return size; 27 | } 28 | 29 | getFirst(){ 30 | return this.head; 31 | } 32 | 33 | getLast(){ 34 | let last = this.head; 35 | if(!last){ 36 | return last; 37 | } 38 | 39 | while(last){ 40 | if(!last.next){ 41 | return last; 42 | } 43 | last = last.next; 44 | } 45 | } 46 | 47 | clear(){ 48 | this.head = null; 49 | } 50 | 51 | removeFirst(){ 52 | if(!this.head){ 53 | return; 54 | } 55 | 56 | this.head = this.head.next; 57 | } 58 | 59 | removeLast(){ 60 | // if empty list, nothing to remove 61 | if(!this.head){ 62 | return; 63 | } 64 | 65 | // if one node, remove it 66 | if(!this.head.next){ 67 | this.head = null; 68 | } 69 | 70 | let previous = this.head; 71 | let node = this.head.next; 72 | 73 | // if three nodes continue down the list 74 | while(node.next){ 75 | previous = node; 76 | node = node.next; 77 | } 78 | 79 | // remove pointer to the last node 80 | previous.next = null; 81 | } 82 | 83 | insertLast(data){ 84 | let last = this.getLast(); 85 | 86 | if(last){ 87 | last.next = new Node(data); 88 | } else { 89 | this.head = new Node(data); 90 | } 91 | } 92 | 93 | getAt(index){ 94 | let node = this.head, counter = 0; 95 | 96 | if(!node){ 97 | return null; 98 | } 99 | 100 | while(node){ 101 | if(counter === index){ 102 | return node; 103 | } 104 | counter++; 105 | node = node.next; 106 | } 107 | 108 | // index was out of bounds 109 | return null; 110 | } 111 | 112 | // todo: review methods below 113 | removeAt(index){ 114 | if(!this.head){ 115 | return; 116 | } 117 | 118 | if(index === 0){ 119 | this.head = this.head.next; 120 | return; 121 | } 122 | 123 | const previous = this.getAt(index - 1); 124 | if(!previous || !previous.next){ 125 | return; 126 | } 127 | 128 | previous.next = previous.next.next; 129 | 130 | } 131 | 132 | insertAt(data, index){ 133 | if(!this.head){ 134 | this.head = new Node(data); 135 | return; 136 | } 137 | 138 | if(index === 0){ 139 | this.head = new Node(data, this.head); 140 | return; 141 | } 142 | 143 | const previous = this.getAt(index - 1) || this.getLast(); 144 | const node = new Node(data, previous.next); 145 | previous.next = node; 146 | } 147 | 148 | forEach(fn){ 149 | let node = this.head; 150 | let counter = 0; 151 | 152 | while(node){ 153 | fn(node, counter); 154 | node = node.next; 155 | counter++; 156 | } 157 | } 158 | 159 | } 160 | 161 | module.exports = { Node, LinkedList }; -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/data_structures/queue.js: -------------------------------------------------------------------------------- 1 | // Queue = container. enter in one end and exit on the other. 2 | // First In, First Out (FIFO) 3 | 4 | // Methods: 5 | // enqueue - add to queue 6 | // dequeue - remove from queue 7 | 8 | class Queue { 9 | constructor(){ 10 | this.queue = []; 11 | } 12 | add(item){ 13 | this.queue.unshift(item); 14 | } 15 | 16 | remove(){ 17 | return this.queue.pop(); 18 | } 19 | 20 | // View the next element to be removed from the queue 21 | peek(){ 22 | return this.queue[this.queue.length - 1]; 23 | } 24 | } 25 | 26 | module.exports = Queue; -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/data_structures/stack.js: -------------------------------------------------------------------------------- 1 | // Stack - FILO - First In, Last Out 2 | 3 | // pushing - add to stack 4 | // popping - remove from stack 5 | 6 | class Stack { 7 | constructor(){ 8 | this.data = []; 9 | } 10 | 11 | push(item){ 12 | this.data.push(item); 13 | } 14 | 15 | pop(){ 16 | return this.data.pop(); 17 | } 18 | 19 | peek(){ 20 | return this.data[this.data.length - 1]; 21 | } 22 | 23 | } 24 | 25 | module.exports = Stack; -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/data_structures/trees.js: -------------------------------------------------------------------------------- 1 | 2 | class Node { 3 | constructor(data){ 4 | this.data = data; 5 | this.children = []; 6 | } 7 | 8 | add(data){ 9 | this.children.push(new Node(data)); 10 | } 11 | 12 | remove(data){ 13 | this.children = this.children.filter((node)=>{ 14 | return node.data !== data; 15 | }); 16 | } 17 | } 18 | 19 | class Tree { 20 | constructor(){ 21 | this.root = null; 22 | } 23 | 24 | breadthFirstTraverse(){ 25 | const queue = [this.root]; // first in, first out 26 | 27 | while(queue.length){ 28 | // remove first element from queue 29 | const first = queue.shift(); 30 | 31 | // log out the element 32 | console.log(first.data); 33 | 34 | // ES6 Spread syntax example: 35 | //=========================== 36 | // var parts = ['shoulders', 'knees']; 37 | // var lyrics = ['head', ...parts, 'and', 'toes']; 38 | // outputs: ["head", "shoulders", "knees", "and", "toes"] 39 | 40 | // add each element of children into the queue 41 | queue.push(...first.children); 42 | 43 | } 44 | 45 | } 46 | 47 | depthFirstTraverse(){ 48 | const stack = [this.root]; 49 | 50 | while(stack.length){ 51 | const first = stack.shift(); 52 | 53 | console.log(first.data); 54 | 55 | stack.unshift(...first.children); 56 | } 57 | 58 | } 59 | } 60 | 61 | // const t = new Tree(); 62 | // t.root= new Node('a'); 63 | // t.root.add('b'); 64 | // t.root.add('d'); 65 | // t.root.children[0].add('c'); 66 | 67 | 68 | // t.depthFirstTraverse(); 69 | 70 | module.exports = { Tree, Node }; -------------------------------------------------------------------------------- /udemy-interview-bootcamp-course/sorting_algorithms.js: -------------------------------------------------------------------------------- 1 | 2 | function bubbleSort(arr) { 3 | for (let i = 0; i < arr.length; i++) { 4 | for (let j = 0; j < (arr.length - i - 1); j++) { 5 | if (arr[j] > arr[j+1]) { 6 | const lesser = arr[j+1]; 7 | arr[j+1] = arr[j]; 8 | arr[j] = lesser; 9 | } 10 | } 11 | } 12 | 13 | return arr; 14 | } 15 | 16 | function selectionSort(arr) { 17 | for(let i = 0; i < arr.length; i++){ 18 | let indexOfMin = i; 19 | 20 | for(let j = i + 1; j < arr.length; j++){ 21 | if(arr[j] < arr[indexOfMin]){ 22 | indexOfMin = j; 23 | } 24 | } 25 | 26 | if(indexOfMin !== i){ 27 | const lesser = arr[indexOfMin]; 28 | arr[indexOfMin] = arr[i]; 29 | arr[i] = lesser; 30 | } 31 | } 32 | 33 | return arr; 34 | } 35 | 36 | function mergeSort(arr) { 37 | if(arr.length === 1){ 38 | return arr; 39 | } 40 | 41 | // determine centerpoint of array 42 | const center = Math.floor(arr.length / 2); 43 | const left = arr.slice(0, center); 44 | const right = arr.slice(center); 45 | 46 | return merge(mergeSort(left), mergeSort(right)); 47 | } 48 | 49 | // take two sorted arrays and merge them 50 | // together into one sorted array 51 | function merge(left, right) { 52 | let results = []; 53 | 54 | while(left.length && right.length){ 55 | if(left[0] < right[0]){ 56 | results.push(left.shift()); 57 | } else { 58 | results.push(right.shift()); 59 | } 60 | } 61 | 62 | return [...results, ...left, ...right]; 63 | } 64 | --------------------------------------------------------------------------------