├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Coding_Challenges ├── Black&White_Cookies │ └── README.md ├── CleanFunctions │ ├── README.md │ └── SOLUTION.js ├── JabroniGoogle │ └── README.md ├── MatchPatterns │ └── README.md ├── Poker │ └── README.md ├── README.md ├── Restaurant_ETL │ └── README.md ├── Shortest_Lock_Combos │ └── README.md ├── Smallest_Square │ ├── README.md │ └── SOLUTION.js ├── Strange_Sequence │ └── README.md └── iTunes_Search │ ├── README.md │ └── SOLUTION.md ├── Data_Structures └── Format_Example │ └── Prompt.md ├── LICENSE ├── README.md ├── System_Design ├── Format_Example │ └── Prompt.md ├── Two_Player_Chess │ ├── README.md │ └── SOLUTION.md └── Url_Shortener │ ├── README.md │ └── SOLUTION.md ├── Technical_Questions ├── Computer_Science_Fundamentals │ ├── Question#15.md │ ├── Question#16.md │ └── Question#2.md ├── Javascript_Fundamentals │ ├── Question#1.md │ ├── Question#17.md │ ├── Question#30.md │ ├── Question#31.md │ ├── Question#4.md │ ├── Question#7.md │ └── Question#8.md ├── Questions │ └── Question#24.md ├── README.md ├── Tools_&_Technologies │ ├── Question#10.md │ ├── Question#11.md │ ├── Question#12.md │ ├── Question#13.md │ ├── Question#14.md │ ├── Question#24.md │ ├── Question#3.md │ ├── Question#34.md │ ├── Question#36.md │ ├── Question#5.md │ ├── Question#9.md │ └── React.js │ │ ├── Question#18.md │ │ ├── Question#19.md │ │ ├── Question#20.md │ │ ├── Question#21.md │ │ ├── Question#22.md │ │ ├── Question#25.md │ │ └── Question#26.md └── Web_Development │ ├── Question#23.md │ ├── Question#27.md │ ├── Question#28.md │ ├── Question#29.md │ ├── Question#32.md │ ├── Question#33.md │ ├── Question#35.md │ └── Question#6.md └── Whiteboarding ├── 100_Light_Bulbs ├── README.md ├── SOLUTION.js └── SOLUTION.md ├── 24_Game └── README.md ├── 2nd_Smallest ├── README.md ├── SOLUTION.js └── SOLUTION.md ├── Add_Reversed_Linked_List ├── README.md └── SOLUTION.js ├── Autocomplete └── README.md ├── Best_Average_Score └── README.md ├── Childhood_Stairs ├── README.md └── SOLUTION.js ├── Counting_Squares ├── README.md ├── SOLUTION.js └── SOLUTION.md ├── Couples_Holding_Hands ├── README.md └── SOLUTION.js ├── Degrees_of_Separation ├── README.md ├── SOLUTION.js └── SOLUTION.md ├── Dictionary_Words └── README.md ├── Dinning_Philosophers └── README.md ├── Format_Example ├── README.md ├── SOLUTION.js └── SOLUTION.md ├── IOS_BST ├── README.md └── SOLUTION.js ├── Longest_Uniform_Subsequence └── README.md ├── MaxPathSum ├── README.md └── Solution.js ├── Merge_LinkList ├── README.md ├── SOLUTION.js └── SOLUTION.md ├── Mountain_Climbers ├── README.md ├── SOLUTION.js └── SOLUTION.md ├── Permutations_I └── README.md ├── Permutations_II └── README.md ├── Poker_Hands ├── README.md ├── pokerhands.js └── solution.md ├── Purple_Rain └── README.md ├── README.md ├── Sales_Intervals └── README.md ├── Sum_Nested_Array ├── README.md └── SOLUTION.js ├── Towers_of_Hanoi ├── README.md ├── hanoi.js └── solution.md ├── TwoSums ├── README.md └── SOLUTION.js ├── Validate_BST ├── README.md └── SOLUTION.js ├── kClosest └── README.md ├── longestSubString ├── README.md └── solution.js └── roombaCircles └── README.md /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at jason.mccutchan@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | 6 | Please note we have a [Code of Conduct](https://github.com/JClutch/Test-Bank/blob/master/CODE_OF_CONDUCT.md), please follow it in all your interactions with the project. 7 | 8 | ## Issues Notes 9 | 10 | If you notice an error or feel a solution is lacking please specificy exactly which file this is in as well as your specific proposed change or edge case. 11 | 12 | If you are interested in submitting problems that should be a part of this project please either make a pull request or submit a git issue with as much detail about the problem as possible as well as the correct file directory it should be entered under. 13 | 14 | ## Pull Request Notes 15 | 16 | 1. Please follow the format of the example file in the folder of which you are adding to. 17 | 2. Prompts/Problems must have provided detailed solutions with clear notes/comments. 18 | 3. Pull requests will be merged once all the criteria above is met 19 | 20 | ## Code of Conduct 21 | 22 | ### Our Pledge 23 | 24 | In the interest of fostering an open and welcoming environment, we as 25 | contributors and maintainers pledge to making participation in our project and 26 | our community a harassment-free experience for everyone, regardless of age, body 27 | size, disability, ethnicity, gender identity and expression, level of experience, 28 | nationality, personal appearance, race, religion, or sexual identity and 29 | orientation. 30 | 31 | ### Our Standards 32 | 33 | Examples of behavior that contributes to creating a positive environment 34 | include: 35 | 36 | * Using welcoming and inclusive language 37 | * Being respectful of differing viewpoints and experiences 38 | * Gracefully accepting constructive criticism 39 | * Focusing on what is best for the community 40 | * Showing empathy towards other community members 41 | 42 | Examples of unacceptable behavior by participants include: 43 | 44 | * The use of sexualized language or imagery and unwelcome sexual attention or 45 | advances 46 | * Trolling, insulting/derogatory comments, and personal or political attacks 47 | * Public or private harassment 48 | * Publishing others' private information, such as a physical or electronic 49 | address, without explicit permission 50 | * Other conduct which could reasonably be considered inappropriate in a 51 | professional setting 52 | 53 | ### Our Responsibilities 54 | 55 | Project maintainers are responsible for clarifying the standards of acceptable 56 | behavior and are expected to take appropriate and fair corrective action in 57 | response to any instances of unacceptable behavior. 58 | 59 | Project maintainers have the right and responsibility to remove, edit, or 60 | reject comments, commits, code, wiki edits, issues, and other contributions 61 | that are not aligned to this Code of Conduct, or to ban temporarily or 62 | permanently any contributor for other behaviors that they deem inappropriate, 63 | threatening, offensive, or harmful. 64 | 65 | ### Scope 66 | 67 | This Code of Conduct applies both within project spaces and in public spaces 68 | when an individual is representing the project or its community. Examples of 69 | representing a project or community include using an official project e-mail 70 | address, posting via an official social media account, or acting as an appointed 71 | representative at an online or offline event. Representation of a project may be 72 | further defined and clarified by project maintainers. 73 | 74 | ### Enforcement 75 | 76 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 77 | reported by contacting the project team at [INSERT EMAIL ADDRESS]. All 78 | complaints will be reviewed and investigated and will result in a response that 79 | is deemed necessary and appropriate to the circumstances. The project team is 80 | obligated to maintain confidentiality with regard to the reporter of an incident. 81 | Further details of specific enforcement policies may be posted separately. 82 | 83 | Project maintainers who do not follow or enforce the Code of Conduct in good 84 | faith may face temporary or permanent repercussions as determined by other 85 | members of the project's leadership. 86 | 87 | ### Attribution 88 | 89 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 90 | available at [http://contributor-covenant.org/version/1/4][version] 91 | -------------------------------------------------------------------------------- /Coding_Challenges/Black&White_Cookies/README.md: -------------------------------------------------------------------------------- 1 | #Black & White Cookies 2 | 3 | ## Prompt 4 | 5 | Build an HTML page (or web app) that: 6 | 7 | Shows a user an image of either a black or white ball upon visiting the page. This should be random, with a 50/50 chance of a user being shown either color ball. 8 | Determine whether the user saw a black or a white ball and the next time a user visits the page show them the same color ball they saw previously. 9 | 10 | Please work with cookies (and not local storage) to record how many times a user has seen each color of ball. You should be able to provide a report on users and number of times they saw each color ball. 11 | 12 | The test should work in any browser (including Chrome). Style as necessary (it is very much appreciated if you do). 13 | 14 | Code should be written in Javascript and feel free to use a framework for building the page/application. Any cookie functionality should not be abstracted by jQuery or any other module provided by NPM or the like. -------------------------------------------------------------------------------- /Coding_Challenges/CleanFunctions/README.md: -------------------------------------------------------------------------------- 1 | ## Prompt 2 | 3 | Given the following code snippet below, please finish the cleanseFunction so that it doesn't break the for loop and so that in the for loop it console logs either the random number or the error message. 4 | 5 | ``` 6 | function randomChanceError(x){ 7 | var i; 8 | if(typeof x !== "number"){ 9 | i = Math.round(Math.random() * 100) 10 | } else{ 11 | i = x 12 | } 13 | if(i % 2 === 0){ 14 | return i; 15 | } else{ 16 | throw new Error('Randomly throw error!') 17 | } 18 | } 19 | 20 | function cleanseFunction(fn){ 21 | /*YOUR CODE HERE*/ 22 | } 23 | 24 | var cleanFunction = cleanseFunction(randomChanceError) 25 | 26 | 27 | for (var i=0; i < 10; i++) { 28 | console.log(cleanFunction()) 29 | } 30 | ``` 31 | -------------------------------------------------------------------------------- /Coding_Challenges/CleanFunctions/SOLUTION.js: -------------------------------------------------------------------------------- 1 | function randomChanceError(x){ 2 | var i; 3 | if(typeof x !== "number"){ 4 | i = Math.round(Math.random() * 100) 5 | } else{ 6 | i = x 7 | } 8 | if(i % 2 === 0){ 9 | return i; 10 | } else{ 11 | throw new Error('Randomly throw error!') 12 | } 13 | } 14 | 15 | function cleanseFunction(fn){ 16 | return () => { 17 | try{ 18 | return fn() 19 | } catch(err){ 20 | return err.message 21 | } 22 | } 23 | } 24 | 25 | var cleanFunction = cleanseFunction(randomChanceError) 26 | 27 | 28 | for (var i=0; i < 10; i++) { 29 | console.log(cleanFunction()) 30 | } -------------------------------------------------------------------------------- /Coding_Challenges/JabroniGoogle/README.md: -------------------------------------------------------------------------------- 1 | # Jabroni Google 2 | 3 | ## Prompt 4 | 5 | Create an application (CLI or GUI) that prompts the user for a text string, performs a Web search (Google(deprecated)/Yahoo(deprecated)/Bing/other - your choice) and returns the title and URL of the first result. Use any tools / libraries you wish, but you must provide instructions on how to build and run your application(README.md file). Include a brief description of your application, why you implemented it the way you did, and any optomizations you did. 6 | 7 | -------------------------------------------------------------------------------- /Coding_Challenges/MatchPatterns/README.md: -------------------------------------------------------------------------------- 1 | # Match Patterns 2 | 3 | ## Prompt 4 | 5 | Given two text files: 6 | 1.) input.txt - a free-text document composed of 1 or more lines of text 7 | 2.) patterns.txt - a set of search strings (1 per line). 8 | 9 | Create an application (CLI or GUI) that can run in three following modes: 10 | 11 | ### Modes: 12 | 1: output all the lines from input.txt that match exactly any pattern in patterns.txt 13 | 2: output all the lines from input.txt that contain a match from patterns.txt somewhere in the line. 14 | 3: output all the lines from input.txt that contain a match with edit distance <= 1 patterns.txt 15 | 16 | 17 | An example of this: 18 | 19 | ``` 20 | input.txt 21 | Hello. This is line 1 of text. 22 | and this is another. 23 | line 3 here 24 | the end 25 | 26 | patterns.txt 27 | the end 28 | matches 29 | line 3 30 | and this is anoother. 31 | 32 | Mode 1 outputs: 33 | the end 34 | 35 | Mode 2 outputs: 36 | line 3 here 37 | the end 38 | 39 | Mode 3 outputs: 40 | and this is another. 41 | the end 42 | ``` -------------------------------------------------------------------------------- /Coding_Challenges/Poker/README.md: -------------------------------------------------------------------------------- 1 | Poker 2 | ========= 3 | 4 | Prompt 5 | ====== 6 | 7 | Create a function that takes in two poker hands and returns the winning hand. Return 'TIE' if the hands are tied. 8 | 9 | Each hand will be an array of five objects, where each object has a suit and value property. 10 | 11 | Don’t worry about tie breaks; ie if the two hands are the same, don’t worry about which straight or flush is stronger than the other. 12 | 13 | EXCEPTION: The ONLY tiebreak to consider is a Royal Straight Flush, which should beat any other Straight Flush 14 | 15 | Link for poker hands: http://img.rankplan.net/p/3/pokerhands_big.jpg 16 | 17 | 18 | Example to give 19 | ``` 20 | Input: (hand1, hand2) 21 | hand 1 = 22 | [ {value: 1,suit: 'spade'}, 23 | {value: 3,suit: 'spade'}, 24 | {value: 11,suit: 'spade'}, 25 | {value: 14,suit: 'spade'}, 26 | {value: 7,suit: 'spade'} ] 27 | 28 | hand 2 = 29 | [ {value: 1, suit: 'spade'}, 30 | {value: 1, suit: 'diamond'}, 31 | {value: 11, suit: 'diamond'}, 32 | {value: 11, suit: 'heart'}, 33 | {value: 7, suit: 'club'} ] 34 | 35 | Output: hand1 36 | Explanation: hand1 is a flush, while hand2 is a two pair 37 | 38 | ``` 39 | -------------------------------------------------------------------------------- /Coding_Challenges/README.md: -------------------------------------------------------------------------------- 1 | # Coding Challenges 2 | 3 | 4 | These are examples coding challenges one could potentially recieve during the interview process.The prompt for each Coding Challenge will be in the README.md file of each folder. 5 | 6 | Notes and general soltuion outline will be listed in the SOLUTION.md file and an example code solution will be available in the SOLUTION.js file or SOLUTION Folder. Some of these prompts may not have actual solution code as the challenge will be general enough where there are multiple correct solutions. 7 | 8 | ## Contributing 9 | Please follow the example format located in the [Format_Example](https://github.com/JClutch/Test-Bank/tree/master/Coding_Challenges/Format_Example) folder. 10 | 11 | Also please read and follow [CONTRIBUTING.md](https://github.com/JClutch/Test-Bank/blob/master/CONTRIBUTING.md) 12 | -------------------------------------------------------------------------------- /Coding_Challenges/Restaurant_ETL/README.md: -------------------------------------------------------------------------------- 1 | # Restaurant E.T.L 2 | 3 | ## Prompt 4 | 5 | Using your choice of language and data store, create and E.T.L(Extract, Transform, Load) service to ingest from DOHMH New York City Restaurant Inspection Result Data set from NYC Open Data. 6 | 7 | (Download Link: https://nycopendata.socrata.com/api/views/xx67-kt59/rows.csv?accessType=DOWNLOAD) 8 | 9 | Generate a list of the top 10 Italian restraunts that have atleast a B health grade rating or better and enter these in your data store. This could be handled using a SQL query but this challenge is focused around building a front end to solve this problem. Also add visualizations of the selected data. 10 | 11 | **NOTES** 12 | 13 | When choosing your data store, consider how to best setup your schema and why that type would be most optimal for this task. 14 | 15 | -------------------------------------------------------------------------------- /Coding_Challenges/Shortest_Lock_Combos/README.md: -------------------------------------------------------------------------------- 1 | # Strange Sequence 2 | 3 | ## Prompt 1 4 | 5 | Write a function that determines the minimum number of rotations needed to unlock a a basic number combination lock 6 | 7 | A rotation is defined as each time you increment/decrement a number by one. 8 | For example, to get from 2 to 4, you would perform 2 rotations: 9 | 2 -> 3, and 3 -> 4 10 | 11 | Furthermore, the lock can wrap around the numbers, so that it would only take 3 rotations to get from 9 to 2 12 | 9 -> 0, 0 -> 1, and 1 ->2 13 | 14 | Your function takes two arguments: 15 | 1. the current state of the lock, which is shown as an array of single digits representing each bit of the lock 16 | 2. An array showing the unlocking position 17 | Both arrays will made up of single digits and they will be the same length, though they can be of any size 18 | 19 | Example: 20 | current lock state: [0, 0, 0] 21 | unlocking combination: [3, 1, 8] 22 | 23 | first: 0 -> 1 -> 2 -> 3 ____ 3 rotations 24 | Second: 0 -> 2 ___ 1 rotation 25 | third: 0 -> 9 -> 8 ____ 2 rotations 26 | Total: 6 rotations 27 | 28 | 29 | ## Prompt 2 30 | 31 | Update your answer to the previous prompt to account for locks with arbitrary characters instead of numbers 0-9. 32 | They will be accepted as a third character set array, and will contain at least two strings. 33 | The character set is ordered and will contain only unique values. 34 | Similarly, you are able to wrap around the lock from one end of the array to the other. 35 | Your first two array arguments will only contains values that appear in the character set of locks 36 | 37 | Example: 38 | starting point: ['*', '#', '+'] 39 | unlocking combination: ['+', 'i', '{\}'] 40 | Character set: ['!', '+', '*', ')', 'i', '=', '{\}', '#'] 41 | 42 | The result would be the following: 43 | '*' -> '+ ____ 1 rotation 44 | '#' -> '{\}' -> '=' -> 'i' ____ 3 rotations 45 | '+' -> '!' -> '#' -> '{\}' ___ 3 rotations 46 | Total: 7 rotations -------------------------------------------------------------------------------- /Coding_Challenges/Smallest_Square/README.md: -------------------------------------------------------------------------------- 1 | # Smallest Squre 2 | 3 | ## Prompt 4 | 5 | Write a function that when given two arrays (1st array will be of the x values for each point and the 2nd will be an array of the corresponding y values for each point) and a random integer K will find the area of the smallest perfect square that would encompass K number of points in it. 6 | 7 | Example 8 | 9 | ``` 10 | Inputs: 11 | let x = [0, 2, 2]; 12 | let y = [0, 7, 2]; 13 | let k = 2; 14 | 15 | const smallestSquare = function(arrayX, arrayY, k){ 16 | /*your code here*/ 17 | } 18 | 19 | Output: 20 | Should return 16 21 | 22 | Explanation: 23 | The square will encompass (0,0) + (2,2) 24 | *The squares sides can't go through the points but have to wrap around them* 25 | 26 | ``` 27 | 28 | **BONUS POINTS IF YOU CAN SOLVE THIS IN BETTER THAN EXPONENTIAL TIME** 29 | -------------------------------------------------------------------------------- /Coding_Challenges/Smallest_Square/SOLUTION.js: -------------------------------------------------------------------------------- 1 | //Brute Force Solution 2 | 3 | const smallestSquare = (x, y, k) => { 4 | xys = x.map((p, j) => [p, y[j]]) 5 | var areas = [] 6 | var buildKPointList = function(list, points){ 7 | if (list.length === k) return areas.push(calcSq(list)) 8 | for (var i = 0; i < points.length; i++){ 9 | buildKPointList( 10 | list.concat([points[i]]), 11 | points.slice(0, i).concat(points.slice(i+1)) 12 | ) 13 | } 14 | } 15 | buildKPointList([], xys) 16 | return Math.min(...areas) 17 | } 18 | 19 | calcSq = (list) => { 20 | const xs = list.map(tuple => tuple[0]), 21 | ys = list.map(tuple => tuple[1]), 22 | maxX = Math.max(...xs), 23 | minX = Math.min(...xs), 24 | maxY = Math.max(...ys), 25 | minY = Math.min(...ys), 26 | xlen = Math.abs(maxX - minX), 27 | ylen = Math.abs(maxY - minY), 28 | sqrt = Math.max(xlen, ylen) + 2 29 | return sqrt * sqrt 30 | } 31 | 32 | 33 | 34 | 35 | /*K-Nearest Neighbor Solution 36 | This is the more optimal as it is quadratic time solution versus exponential 37 | 38 | This solution could be cleaned up and slightly optomized <--- great pull request if anyone wants to =] 39 | 40 | */ 41 | const findSmallestSquare = function(x, y, k){ 42 | var small = null 43 | var gr = new graph(k) 44 | x.forEach((val, key) => { 45 | gr.addNode([val, y[key]]) 46 | }) 47 | gr.findNeighbors() 48 | gr.allNodes.forEach((val) => { 49 | if(small){ 50 | if(small > val.sqr){ 51 | small = val.sqr 52 | } 53 | } else{ 54 | small = val.sqr 55 | } 56 | }) 57 | return small 58 | } 59 | 60 | const graph = function(k) { 61 | this.k = k 62 | this.allNodes = [] 63 | }; 64 | 65 | 66 | graph.prototype.addNode = function(array){ 67 | var obj = {} 68 | obj.x = array[0] 69 | obj.y = array[1] 70 | obj.neighbors = [] 71 | obj.sqr = null 72 | this.allNodes.push(obj) 73 | } 74 | 75 | graph.prototype.findSquare = function(node){ 76 | var xl = node.neighbors[1][1].x 77 | var xs = node.neighbors[1][1].x 78 | var yl = node.neighbors[1][1].y 79 | var ys = node.neighbors[1][1].y 80 | node.neighbors.forEach((val) => { 81 | if(val[1].x > xl){ 82 | xl = val[1].x 83 | } 84 | if(val[1].x < xs){ 85 | xs = val[1].x 86 | } 87 | if(val[1].y > yl){ 88 | yl = val[1].y 89 | } 90 | if(val[1].y < ys){ 91 | ys = val[1].y 92 | } 93 | }) 94 | xl += 1 95 | xs -= 1 96 | yl += 1 97 | ys -= 1 98 | var x = xl - xs 99 | var y = yl - ys 100 | if(x > y){ 101 | node.sqr = x*x 102 | } else{ 103 | node.sqr = y*y 104 | } 105 | } 106 | 107 | graph.prototype.findNeighbors = function(){ 108 | this.allNodes.forEach((val) => { 109 | var neighbors = [] 110 | this.allNodes.forEach((nay) => { 111 | var x = val.x - nay.x 112 | var y = val.y - nay.y 113 | var z = Math.sqrt(Math.pow(x, 2)+Math.pow(y, 2)) 114 | if(neighbors.length < this.k){ 115 | neighbors.push([z, nay]) 116 | } else if(neighbors.length === this.k){ 117 | for(var j=0;j 40 | [Andrew Lichtenstein](https://github.com/andrewblgithub)
41 | [Jonathan Yuen](https://github.com/lalapro)
42 | [Gustaf Brostedt](https://github.com/GustafB)
43 | -------------------------------------------------------------------------------- /System_Design/Format_Example/Prompt.md: -------------------------------------------------------------------------------- 1 | ## Prompt 2 | 3 | Please write out the prompt that will be given to the person whiteboarding 4 | 5 | Example to give 6 | ``` 7 | Example here 8 | 9 | ``` 10 | -------------------------------------------------------------------------------- /System_Design/Two_Player_Chess/README.md: -------------------------------------------------------------------------------- 1 | # **How would you design a two player online chess game?** 2 | 3 | #### All credit goes to Tim Manfield https://github.com/tim-hr/stuff/wiki/System-design:-Calculate-degrees-of-separation 4 | 5 | ## The essence of this problem 6 | 7 | The key here isn't really making a working 2-player chess game that only plays a single game at a time. It's assumed that you can do that, or at least that would be a different kind of a problem, more focused on implementation than on design. 8 | 9 | This question, by contrast, is really about how you make such a chess-playing system **scalable** to many games, and furthermore make it **extensible** in various ways. The "exploring assumptions" section below (which you would do live, in real-time, in a real interview), is meant to illustrate how you'd touch on these factors just enough for you to be able to spin a coherent design story for your audience. 10 | 11 | 12 | ## Exploring assumptions 13 | 14 | Before you can examine scalability and maintainability, the first step is to explore assumptions about the problem specification. In the case of this problem, you don't have a live interviewer, so you have to mimic the Q&A interaction on your own. 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 |
How many parallel games can you have?Let's say just hundreds at first, but later it will scale to tens of thousands.
How do you find someone to play with?To keep this simple let's say you create a game then it's up to you to share the game URL to your opponent outside of the system (i.e., via IM). You can't find or invite users directly within the system.
Do you need to have a user account to play?Yes, you must sign up / sign in via Facebook or Google OAuth.
Is there email validation?Let's say OAuth is configured with email permission required. We'll assume that this email is valid.
Can the user choose the notification type?E.g., in-app only or email-only. Yes they can, in a settings page.
Can there be a computer player (AI)?No.
Is the gameplay synchronous or asynchronous? 48 | I.e., Synchronous means "like you are facing each other across a board in real life". Asynchronous means "like chess-by-mail games that were played a long time ago, before the Internet". Answer: The gameplay is asynchronous. 49 |
How do I know when it's my turn to play?There's a notification system that can alert you in-app or send you an email.
Is this web-only or is there a mobile app as well?Good question! It's web-only... for now. Later, native mobile apps are likely.
Do games "expire"?Yes, let's keep track of activity so we can archive inactive (abandoned) games.
-------------------------------------------------------------------------------- /System_Design/Two_Player_Chess/SOLUTION.md: -------------------------------------------------------------------------------- 1 | # **How would you design a two player online chess game?** 2 | 3 | #### All credit goes to Tim Manfield https://github.com/tim-hr/stuff/wiki/System-design:-Calculate-degrees-of-separation 4 | 5 | ## Outline of program design 6 | 7 | ### System nouns 8 | 9 | We'll try to keep things simple. So at the top level, let's say there are the following objects: 10 | 11 | * Sessions (either unauthenticated or authenticated) 12 | * Players 13 | * Games 14 | 15 | The interesting action naturally takes place inside a Game, which we will define as skeletally as possible: 16 | 17 | * Game 18 | 1. `player1`: the uuid of that Player 19 | 1. `player2`: the uuid of that Player 20 | 1. `lastActive`: timestamp in epoch time 21 | 1. `moveHistory`: array of strings in standard chess move notation 22 | 23 | The `lastActive` attribute would be tracked in order to allow us to expire games, as per the specification. 24 | 25 | Where are the rest of the attributes, you might ask? 26 | 27 | ### Design choice: reconstruct current state from history? 28 | 29 | All the following attributes of a game instance can be inferred from `moveHistory`. 30 | 31 | 1. `currentTurn`: enum for `White` or `Black` 32 | 1. `board`: 2-d array of board squares, piece names are enum of 'Knight', 'Bishop' etc. 33 | 1. `winState`: enum for `White` or `Black` or `null` if no winner yet 34 | 1. `takenWhitePieces`: array of piece names 35 | 1. `takenBlackPieces`: array of piece names 36 | 37 | Right after a given Game is loaded into memory from storage, init code would reconstruct the current state by replaying the moves in `moveHistory`. 38 | 39 | This approach is very DRY and fits in with some interesting design ideas, such as the "traditional databases are just global state, which is Bad, so rather than a monolithic schema for all uses, we should transform the event log into any schema we need" [idea that partially inspired Redux](https://www.confluent.io/blog/turning-the-database-inside-out-with-apache-samza/). 40 | 41 | For a typical game design, this "replay only" approach is probably a controversial storage choice since it requires extra processing before you can do even basic operations and makes the system more opaque to querying and indexing. 42 | 43 | We can easily see use cases where you want to move attributes back to top-level existence. For example, `winState` being implied means you can't easily run a query to see which games have been won, which seems potentially annoying. 44 | 45 | However, let's say we go with reconstructing current state from history as a starting point for discussion. In a real interview I might or might not get pushback for going this way... probably not, I'd likely just have to justify the approach in response to their questions, in a collegial and logical manner. 46 | 47 | ### Decoupling rendering 48 | 49 | One key factor we covered is that we want to support multiple client types. 50 | 51 | This suggests that game logic needs to be completely decoupled from rendering. The game engine would be designed to handle abstract moves and return an abstract board. The I/O and rendering happens at another layer. 52 | 53 | You could have the render function injected into the game logic component as a callback. However since this is a client-server system it's probably better to just have a simple linear MVC flow where: 54 | 55 | * UI reacts to user events 56 | * a controller layer marshals those events into abstract moves that are sent as messages to the game logic component 57 | * the game logic updates move history and thus board state 58 | * controller is notified of update to board state 59 | * controller passes board state to renderer 60 | * UI is updated with fresh rendering 61 | 62 | Pretty standard MVC stuff... you typically need to explain just enough to make it clear that you get the basic concept of decoupling. 63 | 64 | ## Outline of system architecture 65 | 66 | ### Back-of-the-envelope on traffic 67 | 68 | Estimating load is usually a good early step in system design. 69 | 70 | In our case, we know from the earlier requirements exploration that the system is meant to support "tens of thousands" of simultaneous games. 71 | 72 | So, chess is a game with long think times, this isn't a twitchy first-person shooter. Let's assume 30 seconds of think time on average, or 2 moves per minute per game. 73 | 74 | If there are 10,000 games and 2 moves per minute per game, then that's 20,000 moves per minute. If we naively distribute that traffic evenly, then we have ~330 moves per second. 75 | 76 | **However**, we also said that the gameplay is **asynchronous**, more like chess-by-mail than like playing each other face-to-face, in terms of the timing of moves. 77 | 78 | Thus the traffic should drop dramatically. Let's change the estimation tack accordingly. Let's assume that there are 50 moves per game and games take 8 hours to complete on average. 79 | 80 | There are 500,000 moves distributed over 28,800 seconds, or a naive average of 17 moves per second. 81 | 82 | ### Note: it's ok to make stuff up 83 | 84 | The numbers above are made-up but plausible. Don't get too hung up on not knowing exact figures, or trying to concoct a scheme by which you would directly measure those numbers. Implementing metrics and business intelligence (BI) stuff so you can get hard data about user behavior is a completely separate topic and not germane unless the interviewer explicitly brings it up. 85 | 86 | At this stage we assume the system isn't built yet and such hard data is not at hand, so we have to use our initial intuitions and common sense to put some reasonable starting figures into place for estimation. 87 | 88 | ### Desktop browser case 89 | System architecture can be very plain-vanilla: a cluster of web app servers fronted by a load balancer, and a single database of any flavor to store all the games and sessions. 90 | 91 | With the traffic described above, to maintain responsiveness we'd just need to vary the cluster size, easy-peasy. 92 | 93 | If you didn't want to hit a RDBMS with session-lookup traffic then you could throw in a Redis instance to store the sessions, although for this amount of traffic it's hard to see why that's even necessary yet. 94 | 95 | ### Mobile app case 96 | 97 | Games can be asynchronous, which suggests in the mobile app case having an offline mode. However we didn't actually ask that during the "exploring assumptions" phase. So we'd ask it now, in a real interview. 98 | 99 | 100 | 101 | 102 | 103 | 104 |
Do the mobile apps have an offline mode?No.
105 | 106 | Let's keep it simple and say "no". :) 107 | 108 | By avoiding an offline mode, we avoid making a local copy of data in a sqlite database and we avoid having to sync, which can be annoying if you consider edge cases where players are playing on multiple devices and so forth. 109 | 110 | ## Summary 111 | 112 | Hopefully it's clear that this reference answer is **not** meant to be a canonical description of **the** one-and-only way to make an online chess game. 113 | 114 | It's just one person's take, one person riffing on the topic. It's meant to illustrate the kind of explanation that tends to put interviewers at ease, because it pattern-matches to the way that work gets done in the real world. 115 | 116 | Software engineers are frequently in this position of having to estimate things without much hard data to work with yet, and to design a system whose very requirements are still in flux. Being able to flexibly and diplomatically deal with such a situation, in miniature, in the context of an interview problem like this, bodes well for your future performance on the team. -------------------------------------------------------------------------------- /System_Design/Url_Shortener/README.md: -------------------------------------------------------------------------------- 1 | # **How would you design a url shortener?** 2 | 3 | #### All credit goes to Tim Manfield https://github.com/tim-hr/stuff/wiki/System-design:-Calculate-degrees-of-separation 4 | 5 | Design a url shortener like bit.ly. 6 | 7 | This kind of question can be viewed through a few primary lenses: 8 | 9 | 1. Basic components to satisfy the core use case(s) 10 | 2. Scalability 11 | 3. Maintainability / Operationalizing 12 | 4. Extensibility / Business needs -------------------------------------------------------------------------------- /System_Design/Url_Shortener/SOLUTION.md: -------------------------------------------------------------------------------- 1 | # **How would you design a Url Shortener?** 2 | 3 | #### All credit goes to Tim Manfield https://github.com/tim-hr/stuff/wiki/System-design:-Calculate-degrees-of-separation 4 | 5 | ## Basic components to satisfy the core use case(s) 6 | For a URL shortening service, the core uses are the initial shortening and the subsequent expansion. Nothing else is really required. 7 | 8 | ### Shortening 9 | 10 | Algorithmically you can consider how the shortening takes place. There will be some hashing mechanism. That mechanism should be reasonably efficient, you can discuss options. You don’t have to have anything suitable actually memorized, but you can talk about the characteristics of that algorithm that you’d look for. In this case, the primary motivation is shortness, so you’d want to find a hash that processed a URL into only a single-digit number of alphanumeric characters, probably. 11 | 12 | How many URL’s theoretically could you accommodate? You’d do the math. 13 | 14 | How do you handle hashing collisions? Consider the options. 15 | 16 | What component of the architecture does the processing of this hash? Is it the web server? Some purpose-built server? 17 | 18 | How do you handle storing the resulting hash? What type of data store do you consider? Why might one be better than another? 19 | 20 | ### Expansion 21 | 22 | Given some short hash of a URL, you look up the corresponding full URL and issue a redirect. (Which type of redirect? 301? 302? Something else?) 23 | 24 | Which type of server in your architecture handles the request? 25 | 26 | How do you do the data lookup? 27 | 28 | ### System Components 29 | 30 | Putting the above together, you can sketch out the system to minimally satisfy the core use cases as simply consisting of a single web server that performs the hashing itself, storing the resulting hash in a single instance of a relational db like Postgres. The hash is the indexed id of the URL. Collisions are primitively handled with an incremented suffix added to the hash result. Then the shortened URL is converted to the long form by the same cluster of web servers, who simply look up from Postgres and issue a 302 redirect (temporary type of redirect, because we probably want to see the traffic again later for tracking/reporting reasons rather than have the browser never send that user to us again). 31 | 32 | This tiny system would work. It wouldn’t scale of course, but it would work. That should be your starting point before throwing around a bunch more components and trying to perform a bunch of optimization. What would basically work? 33 | ## Scalability 34 | For all scalability considerations you need to start with the production / operational context. What are your projected traffic patterns? What is the difference between read and write traffic? 35 | 36 | Is there a steady pattern or is it very spiky in some way? If it’s spiky, is it spiky based on time or perhaps based on some other factor, like the viral popularity of some social object in the system? 37 | 38 | In the case of a URL shortening service, write traffic will be much more sporadic and light compared to read traffic (if it is at all popular, which is presumably what you’re planning for). 39 | 40 | Read traffic has the potential to be tremendously spiky depending on the popularity of a given URL (or, rather, the popularity of the website that that URL leads to). If Rihanna (or her faceless handlers, rather) posts your shortened URL on her Twitter feed then that shortened URL is probably going to get slammed. 41 | 42 | That given, you almost certainly want to introduce a caching component to the design, for ultra-fast and ultra-cheap lookups of such “hot” URL’s. Where does that cache live? There are various options, you can weigh the tradeoffs. Typically you’d use a purpose-built caching server like Redis. Now you have a lifecycle consideration to your caching. How and when do you populate, refresh, and expire cache entries? 43 | 44 | Which system components are likely to fail? Well you only have a couple of components to consider at first because you kept the initial system really simple to satisfy the basic use cases, right? There’s a web server and a database. Obviously, either of those could fail. 45 | 46 | Let’s look at failure modes from a resource consumption perspective. 47 | 48 | First, to get it out of the way, any networked component can fail if it runs out of bandwidth to talk to other components. But don’t be seduced by that into thinking that that’s worth mentioning. It’s typically not a problem IRL. So don’t mention it, in answering questions like these… I’ve noticed that many HR grads tackling system design questions routinely mention bandwidth, trying to be thorough, but it just shouts of inexperience to do that, so don’t, please. (Unless you are specifically talking about a mobile client trying to talk over a non-WIFI connection to your servers, then of course bandwidth constraints are worth considering). 49 | 50 | Any component is a process or set of processes running ultimately on a machine (virtual or not), so it can run out of memory, disk space, or CPU. 51 | 52 | The web server doesn’t write much to its own disk (aside from logs) so it will more likely fail, resource-wise, due to CPU or running out of memory. Running out of disk should only happen in exceptional cases where the logging is misconfigured and the logs don’t rotate properly but just keep writing to new files and filling up disk. Running out of memory should only happen in exceptional cases where the app has a memory leak or is misconfigured for the machine it’s on. So the most likely resource-related failure mode of a web server is going to be running out of CPU. 53 | 54 | Note: you can mention that if this weren’t a Node server, and if this system weren’t so simple, with no dependencies other than on the database itself, you’d also face the potential for the web server to bog down while waiting for synchronous service calls to return. In a system unlike Node, where serving each request consumes considerable resources in order to service, the client requests will quickly stack up in a high-traffic situation, while waiting for 2nd- or 3rd-party calls to return, and the later requests can wind up dropping on the floor from timeouts. 55 | 56 | The database is also most likely to be a failure point, resource-wise, when it is “out of CPU”, in a manner of speaking. This might or might not literally mean that the CPU is actually visibly pegged, perhaps a better way to say this is "running out of time". Meaning that the database as a program can only finish processing queries in terms of executing simultaneous queries, especially even slightly long-running queries. Similar to the failure mode described above, queries can stack up in the processing queue (although database servers are multi-threaded, there are limits to how much context switching among parallel queries they can really do). 57 | 58 | Some common ways that databases wind up getting asked to do much work per query: 59 | 60 | * when proper indexes aren’t applied, so every query triggers a table scan. 61 | * Or if there are too many / too-ugly joins that trigger a ton of processing per query. 62 | * Or if lock contention becomes a problem (too many queries trying to update the same row or set of rows, given your database settings). 63 | 64 | In your case, there’s hardly anything going on here. The naive initial solution has literally a two (or so) column table with the short URL as an indexed key, there’s nothing to join and the lookup will be fast due to the index. It’s pretty hard to see the system failing due to db lookups, this given. 65 | 66 | You could talk speculatively about how, if db performance somehow did become a problem in the future, you could approach the problem either vertically (beefing up the db server, which is usually the easy first step to take), or horizontally (figuring out how to spread the load across multiple shards, typically). Of course, before taking either of those steps, you’d actually measure what’s going on in order to make an evidence-based decision about investing development time or dollars. Which leads to... 67 | ## Maintainability / Operationalizing 68 | One oft-overlooked angle to system design is how you’ll keep the thing running IRL. 69 | 70 | Being mere mortals and not omniscient super-beings (such as, say, Geoff Boss), we need data in digestible formats in order to be able to spot patterns when troubleshooting or generally for keeping tabs the system’s health. 71 | 72 | That implies monitoring the system, like what New Relic or Data Dog provide. Make sure you know basically what those services do and the kind of graphs / visibility they give you. They also provide some alerting, more on that below. 73 | 74 | You also need some kind of logging system, of course. You’re used to being able to look at a console and see your output streaming by for a single process on a single machine. When you go to scale you will have many instances all merrily writing reams of data to many logs. Therefore you will need to set up log aggregation and probably log searching / filtering as well. Look at services like PaperTrail, LogEntries, and Splunk to see what features they offer. 75 | 76 | Note in particular: although it’s indispensable to be able to manually pore over logs to look for exceptional situations and patterns, you’ll also want your system to automatically alert you when there are troubling patterns in the logs. That’s a standard feature area for logging services. 77 | 78 | You may also want to track system uptime from the outside -- look at the Pingdom service. As the name suggests they do simple pings of your publicly visible pages (if the app requires sign-in), but they also can do Selenium-like scripts that mimic user activity. Either way they’ll check your uptime and you can trigger alerts through them as well. 79 | 80 | Having set up the above monitoring and alerting, you need to be able to react to problems quickly when they arise. That means setting up some kind of paging system, like what the PagerDuty service offers. Check them out and see what their deal is too… 81 | 82 | You’ll want to implement backups for your data. Replicating your master database to one or more slave databases in near-realtime is a common simple approach there. This enables you to flip a slave to master with minimal downtime for your overall system if the master database goes out of commission. 83 | 84 | Speaking of downtime, what does happen when the system is down, either planned maintenance, or unplanned? Since the component that’s crashing might be your normal web servers, you may want to have a separate dedicated server (or 3rd party service) to serve a maintenance page. Or perhaps you build it into your main web server, but in a way that falls back to simple static web page serving, so can still be served even if most things are broken. (A static page might not work well though if you want to display partially-dynamic things like announcing the time window of a specific scheduled downtime). 85 | 86 | There’s a lot more stuff you can do in this area, of course (all these sections could be expanded into book-length treatments of all the possibilities and edge cases and strategies, obviously), but touching on the basics above will be very reassuring to your interviewer. 87 | 88 | ## Extensibility / Business needs 89 | One VERY oft-overlooked angle to system design is catering to the business needs that drive the existence of this technical system in the first place. 90 | 91 | A big example is business reporting. Since we are presuming that the business in this hypothetical case is successful, there will be money and reason to afford business analysts poring over site data to optimize sales / traffic / partnerships, etc. 92 | 93 | The db queries to satisfy such business reporting needs often are long and expensive because they are aggregating and processing data over an entire time window. 94 | 95 | The simple thing to mention here is that you don’t want those queries to be pummeling the live master database, so you can replicate the data off to a reporting slave, and hit that instead. 96 | 97 | Another big business need is security, so you could potentially talk about that angle too. How might you stop DDOS attacks is a typical fun one here. 98 | 99 | ## A quantitative estimation approach to all this 100 | With the above basics in place, you can now try numerically estimating traffic and thereby figuring out what your pain points are likely to be and what options you have to address them. 101 | 102 | To watch someone working through actual numeric back-of-the-envelope calculations that illustrate/apply some of the ideas above, and more besides, please read through / watch the (short!) vids at the following site: 103 | https://www.hiredintech.com/classrooms/system-design/lesson/55 -------------------------------------------------------------------------------- /Technical_Questions/Computer_Science_Fundamentals/Question#15.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is middleware and how do you use it? -------------------------------------------------------------------------------- /Technical_Questions/Computer_Science_Fundamentals/Question#16.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is currying? -------------------------------------------------------------------------------- /Technical_Questions/Computer_Science_Fundamentals/Question#2.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is the difference between an Array and a Stack? -------------------------------------------------------------------------------- /Technical_Questions/Javascript_Fundamentals/Question#1.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is a Javascript Closure? -------------------------------------------------------------------------------- /Technical_Questions/Javascript_Fundamentals/Question#17.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is hoisting in javascript? -------------------------------------------------------------------------------- /Technical_Questions/Javascript_Fundamentals/Question#30.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | Define scope in javascript -------------------------------------------------------------------------------- /Technical_Questions/Javascript_Fundamentals/Question#31.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | Did anything change with scope in javascript in ES6? -------------------------------------------------------------------------------- /Technical_Questions/Javascript_Fundamentals/Question#4.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What’s the difference between Prototypal Inheritance and Classical Inheritance? -------------------------------------------------------------------------------- /Technical_Questions/Javascript_Fundamentals/Question#7.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is a promise? What makes it different than a callback? How does it work under the hood? -------------------------------------------------------------------------------- /Technical_Questions/Javascript_Fundamentals/Question#8.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What’s the difference between let and const? -------------------------------------------------------------------------------- /Technical_Questions/Questions/Question#24.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | How would you speed up an Angular application? -------------------------------------------------------------------------------- /Technical_Questions/README.md: -------------------------------------------------------------------------------- 1 | # Technical Questions 2 | Each question will be in a Question#.md file in the Question folder. The answers will be in the solution branch of the Question folder and will be in the same file as the question. 3 | 4 | ## Contributing 5 | Please read and follow [CONTRIBUTING.md](https://github.com/JClutch/Test-Bank/blob/master/CONTRIBUTING.md) 6 | 7 | Also for Technical Questions make to follow the already established format. Question#(N+1).md with the question being in the master branch and the question as well as the solution being in the solution branch in the same file. 8 | -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/Question#10.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is 2 way data binding? -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/Question#11.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is a service(Angular) and a factory(React)? -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/Question#12.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is Node.js? -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/Question#13.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is Express.js? -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/Question#14.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | If you have node.js, why use express.js? -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/Question#24.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | How would you speed up an Angular application? -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/Question#3.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What’s are the major differences between Angular and React? -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/Question#34.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is the difference between JQuery's onLoad and JavaScript's onDocumentReady functions? -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/Question#36.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | Explain in as much detail what transactions are? 4 | - Why are they important? 5 | - Why use them? 6 | - What goes on underneath the hood? 7 | - What are locks? 8 | - What are the varying isolation levels in PostgreSQL? -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/Question#5.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What’s the difference between Mongo and MySQL? Which is better for scaling? -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/Question#9.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What’s the difference between Angular and Angular 2? 4 | -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/React.js/Question#18.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | Name all of react's life cycle methods -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/React.js/Question#19.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is the order of react lifecycle method execution after .setState() is triggered? 4 | 5 | ## Answer 6 | 7 | 1.) shouldComponentUpdate()
8 | 2.) componentWillUpdate()
9 | 3.) Render()
10 | 4.) componentDidUpdate()
11 | 12 | https://cdn-images-1.medium.com/max/1600/1*u0CoE_GHlUB4Ce-yZtgv0Q.png 13 | -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/React.js/Question#20.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is the order of react lifecycle method execution when a component will recieve new props from a provider/parent component that also triggers a re-render? 4 | 5 | ## Answer 6 | 7 | 1.) componentWillRecieveProps()
8 | 2.) shouldComponentUpdate()
9 | 3.) componentWillUpdate()
10 | 4.) Render()
11 | 5.) componentDidUpdate()
12 | 13 | 14 | https://cdn-images-1.medium.com/max/1600/1*5fwo0VC1KtiWH64CENQ8dQ.png 15 | -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/React.js/Question#21.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is the order of react lifecycle method execution when a component is first mounting? 4 | 5 | ## Answer 6 | 7 | 1.) The Constructor function runs first getting the components props and then the initial state.
8 | 2.) componentWillMount()
9 | 3.) Render()
10 | 4.) componentDidMount()
11 | 12 | https://camo.githubusercontent.com/461765618c95d7d3d0941d767a95855cb5698195/687474703a2f2f7279616e73756b616c652e636f6d2f76697a2f74682f6a732f72656163746a735f636f6d706f6e656e745f6c6966656379636c652f696e697469616c5f72656e6465722e706e67 13 | 14 | -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/React.js/Question#22.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is the virtual dom in react? -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/React.js/Question#25.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What are higher order components? -------------------------------------------------------------------------------- /Technical_Questions/Tools_&_Technologies/React.js/Question#26.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is conditional rendering? -------------------------------------------------------------------------------- /Technical_Questions/Web_Development/Question#23.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | How does flexbox work? -------------------------------------------------------------------------------- /Technical_Questions/Web_Development/Question#27.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What is a run time error? Would the application continue or stop? -------------------------------------------------------------------------------- /Technical_Questions/Web_Development/Question#28.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | Given a programming language you are not familiar with, explain to me your process on how you would go about figuring out how to make a call to an api with said language. -------------------------------------------------------------------------------- /Technical_Questions/Web_Development/Question#29.md: -------------------------------------------------------------------------------- 1 | ## Quesiton 2 | 3 | What is the difference between CSS Grid and Flex Box? -------------------------------------------------------------------------------- /Technical_Questions/Web_Development/Question#32.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | What happens when you type in google.com into your browser and press enter? 4 | 5 | ## Answer 6 | 7 | ALL CREDIT -> https://github.com/tim-hr/stuff/wiki/Outline-for-%22What-happens-when-you-type-http:--www.gmail.com-into-your-browser-location-bar%3F%22 8 | 9 | ### What interviewers are looking for 10 | ``` 11 | 1.) Do you have a clear, systemic understanding of how web apps work? 12 | 2.) Do you care about how things work under the hood, generally? 13 | 3.) Are you able to coherently marshal your thoughts about a system? 14 | 4.) Can you deal effectively with a very open-ended question, clarifying the questioner's intent and managing your time so as to give a "good" answer? 15 | ``` 16 | 17 | Good programmers operate fluidly at multiple levels of abstraction and across many components, tying them all together in a coherent story of how processes unfold. 18 | 19 | In particular, when you are doing (a) system design and (b) troubleshooting, having those mental models in your head is a key asset. 20 | 21 | Think of this as a weeder question to separate out people who can only code via copy/paste/tweak (and don't really understand what's going on) versus people who code based on clear mental models. 22 | 23 | ### Layman-level outline 24 | * Browser accepts the input "google.com". 25 | * Computer sends a request for that page to Google's computers. 26 | * Google's computers process the request and sends the page contents back. 27 | * Browser displays the page. 28 | 29 | ### High-level outline for interviews 30 | * DNS lookup on the URL, now you have an IP address. 31 | * Use the IP address + the port number (which is explicitly or implicitly described in the URL) to connect to the server via TCP/IP. 32 | * Google is obviously a huge site with many servers, so some kind of load-balancing is involved to route the request to a specific available server. 33 | * Use the TCP stream thus opened up to start sending text to the server. 34 | * Send an HTTP request (which is just text) to tell the server which path, host, and "verb" (GET, POST, etc) you are requesting. 35 | * The HTTP request also contains a variety of other important headers which tell the server who you are and more about what you want. 36 | * The server process the text of the HTTP request into a request object in memory. 37 | * The server probably has some kind of an MVC framework; it processes the request through that. 38 | * The resulting bundle of HTML, inline JavaScript, inline CSS, and possibly inlined binary data, is packaged up into an HTTP response. 39 | * The HTTP response is shipped back through the TCP stream. 40 | * The browser begins parsing the big wad of text in the HTTP response. 41 | * As HTML, JavaScript, CSS are parsed, more HTTP requests are sent out to fetch more assets for the page. 42 | * The browser executes script and renders the results of all its parsing to the viewport. 43 | Note: there is a LOT more than can be said, but outlining up to this level is probably good enough for most interviews. 44 | -------------------------------------------------------------------------------- /Technical_Questions/Web_Development/Question#33.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | When a server sends a response, what happens before it shows up on the client? -------------------------------------------------------------------------------- /Technical_Questions/Web_Development/Question#35.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | How does getElementsByClassName work, and what does it return? -------------------------------------------------------------------------------- /Technical_Questions/Web_Development/Question#6.md: -------------------------------------------------------------------------------- 1 | ## Question 2 | 3 | If you were to make a website responsive, where would you start? -------------------------------------------------------------------------------- /Whiteboarding/100_Light_Bulbs/README.md: -------------------------------------------------------------------------------- 1 | # 100 Light Bulbs 2 | ## Prompt 3 | 4 | There is a group of a 100 people in a line (all numbered 1-100) and a room filled with 100 lightbulbs (all numbered 1-100) all of which are currently off. When a person walks into the light bulb room, they would flip the switch for lightbulbs that their number is a factor of. If every person was to do this then how many lightbulbs would be left on after all 100 people were to walk through the room? 5 | 6 | Please write a function to find this answer given a single number input of N=100 7 | 8 | Can you write a function that solves this in constant time? 9 | 10 | Example to give 11 | ``` 12 | Person #25 would flip the switch for lightbulbs 25, 50, 75, 100. 13 | 14 | ``` 15 | -------------------------------------------------------------------------------- /Whiteboarding/100_Light_Bulbs/SOLUTION.js: -------------------------------------------------------------------------------- 1 | const LightBultCount = (n) => { 2 | return Math.floor(Math.sqrt(n)) 3 | } -------------------------------------------------------------------------------- /Whiteboarding/100_Light_Bulbs/SOLUTION.md: -------------------------------------------------------------------------------- 1 | ## Solution 2 | 3 | This problem revolves more aorund your problem solving abilities and how you think about problems rather than javascript solutions. In that sense this problem is more mathmatical than coding. 4 | 5 | Hopefully the person being whiteboarded asks the question of what number of people have the flip a switch for it to be still be on at the end and come to realiization that this number has to be odd. 6 | 7 | After realizing this they should then realize that this translates to the number of factors a number has and that the lightbulbs will have an odd number of factors. 8 | 9 | From there this should lead them to realize that only numbers with odd numbers of factors will be perfect squares so if you can count the number of perfect squares in a range you can easily solve this problem in constant time! -------------------------------------------------------------------------------- /Whiteboarding/24_Game/README.md: -------------------------------------------------------------------------------- 1 | # 24 Game 2 | ## Prompt 3 | 4 | You have 4 cards each containing a number from 1 to 9. You need to judge whether they could operated through *, /, +, -, (, ) to get the value of 24. 5 | 6 | Example to give 7 | ``` 8 | Input: [4, 1, 8, 7] 9 | Output: True 10 | Explanation: (8-4) * (7-1) = 24 11 | 12 | Input: [1, 2, 1, 2] 13 | Output: False 14 | 15 | ``` 16 | -------------------------------------------------------------------------------- /Whiteboarding/2nd_Smallest/README.md: -------------------------------------------------------------------------------- 1 | # 2nd Smallest Element 2 | ## Prompt 3 | 4 | Given an array of integers, return the 2nd smallest value in the array
5 | Solve for linear time complexity -> O(N) 6 | 7 | Example to give 8 | ``` 9 | Input: [6,3,1,5,8] 10 | Output: 3 11 | Explanation: 1 is the smallest, 3 is the 2nd smallest 12 | 13 | ``` 14 | -------------------------------------------------------------------------------- /Whiteboarding/2nd_Smallest/SOLUTION.js: -------------------------------------------------------------------------------- 1 | const secondSmallest = (array) => { 2 | let min = Infinity 3 | let result = Infinity 4 | if(array.length < 2){ 5 | return false 6 | } 7 | array.forEach((val) => { 8 | if(val < min){ 9 | result = min 10 | min = val 11 | } else if(val < result){ 12 | result = val 13 | } 14 | }) 15 | 16 | return result 17 | } -------------------------------------------------------------------------------- /Whiteboarding/2nd_Smallest/SOLUTION.md: -------------------------------------------------------------------------------- 1 | ## Solution 2 | 3 | ### Edge-Case 4 | What if the array doesn't have two or more elements? 5 | 6 | In this case just return false but this should be a question you ask. 7 | 8 | ### Explanation 9 | 10 | First check to make sure the array has two or more elements, if not return false immediately 11 | 12 | While you loop through the array you need to keep track of both the smallest and 2nd smallest values as you come across them. This can be broken down to two simple checks. 13 | 14 | if the current element is smaller than the current minimum then we know that element is now our new minimum and our old minimum is now our 2nd smallest value. 15 | 16 | if the element is smaller than our current 2nd smallest value and didn't hit the earlier check then we know the element is not our smallest element but instead is our new 2nd smallest element. 17 | 18 | and then just return our stored 2nd smallest value. 19 | -------------------------------------------------------------------------------- /Whiteboarding/Add_Reversed_Linked_List/README.md: -------------------------------------------------------------------------------- 1 | # Add Reversed Linked List 2 | ## Prompt 3 | 4 | You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as an array 5 | 6 | You may assume the two numbers do not contain any leading zero, except the number 0 itself. 7 | 8 | Solve for linear time complexity -> O(N) 9 | 10 | Example to give 11 | ``` 12 | Input: (2 -> 4 -> 3) , (5 -> 6 -> 4) 13 | Output: [7, 0, 8] 14 | Explanation: 342 + 465 = 807. 15 | 16 | ``` 17 | -------------------------------------------------------------------------------- /Whiteboarding/Add_Reversed_Linked_List/SOLUTION.js: -------------------------------------------------------------------------------- 1 | var addTwoLists = function(l1, l2) { 2 | 3 | let newList = []; 4 | let carryOver = 0; 5 | 6 | let node1 = l1.head; 7 | let node2 = l2.head; 8 | 9 | while(node1 !== null || node2 !== null){ 10 | let sum = 0 11 | if(node1){ 12 | sum += node1.val 13 | node1 = node1.next 14 | } 15 | if(node2){ 16 | sum += node2.val 17 | node2 = node2.next 18 | } 19 | if(carryOver > 0){ 20 | sum += carryOver 21 | carryOver = 0 22 | } 23 | if(sum > 9){ 24 | carryOver = Math.floor(sum/10) 25 | } 26 | newList.push(sum%10) 27 | } 28 | if(carryOver > 0){ 29 | newList.push(carryOver) 30 | } 31 | return newList 32 | }; 33 | -------------------------------------------------------------------------------- /Whiteboarding/Autocomplete/README.md: -------------------------------------------------------------------------------- 1 | # Autocomplete 2 | ## Prompt 3 | 4 | A common feature in applications is autocompletion of text. Let's create the function that would support this feature. 5 | 6 | When given an array of options can you create a function that when given a string of letters would return all possible options? 7 | 8 | Examples: 9 | 10 | ``` 11 | 1.) 12 | Input: 'as', ['pear', 'apple', 'astor', 'ten', 'horse', 'asteroid'] 13 | Output: ['astor', 'asteroid'] 14 | 15 | ``` 16 | 17 | Bonus: 18 | 19 | Consider how you could optomize your soltuion to handle for hundreds of thousands of words and something that would, as you typed, call this function. -------------------------------------------------------------------------------- /Whiteboarding/Best_Average_Score/README.md: -------------------------------------------------------------------------------- 1 | # Best Average Score 2 | ## Prompt 3 | 4 | Given an array of student scores, which may contain multiple scores per student, 5 | return the highest average score among the students. 6 | 7 | Note: Average must be an integer - floor the average if average is not an integer. 8 | Note 2: Scores can be positive or negative integers. 9 | 10 | ``` 11 | Example: 12 | 13 | [["Robert", "50"], 14 | ["Bob", "81"], 15 | ["James", "66"] 16 | ["Charles", "75"] 17 | ["Bob", "100"]] 18 | 19 | Result: 90 20 | ``` 21 | -------------------------------------------------------------------------------- /Whiteboarding/Childhood_Stairs/README.md: -------------------------------------------------------------------------------- 1 | # Childhood Stairs 2 | ## Prompt 3 | 4 | A child is running up a staircase with n steps and can hop either 1 step, 2 steps, or 3 steps at a time. Implement a method to count how many possible ways the child can run up the stairs if given the number of steps in the staircase as N. 5 | 6 | Examples 7 | 8 | ``` 9 | 1.) 10 | Input: 3 11 | Output: 4 12 | 13 | 2.) 14 | Input: 4 15 | Output: 7 16 | 17 | 3.) 18 | Input: 50 19 | Output: 10562230626642 20 | 21 | ``` 22 | 23 | *BONUS* 24 | 25 | Use dynamic programming to improve your programs efficiancy so that it could run the input of 50 in repl without timming out. -------------------------------------------------------------------------------- /Whiteboarding/Childhood_Stairs/SOLUTION.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* Brute Force Permutation */ 4 | 5 | const child = (n, count) => { 6 | count = count || 0 7 | let result = 0 8 | const steps = [1,2,3] 9 | steps.forEach((val) => { 10 | count += val 11 | if(count < n){ 12 | result += child(n, count) 13 | count -= val 14 | } else if(count === n){ 15 | result += 1 16 | } else{ 17 | count -= val 18 | } 19 | }) 20 | 21 | return result 22 | 23 | } 24 | 25 | /* Slightly better permutation/brute force */ 26 | 27 | const child = (n, count) => { 28 | count = count || 0 29 | let result = 0 30 | if(count <= n-3){ 31 | result += child(n, count+1) 32 | result += child(n, count+2) 33 | result += child(n, count+3) 34 | } else if(count <= n-2){ 35 | result += child(n, count+1) 36 | result += child(n, count+2) 37 | } else if(count <= n-1){ 38 | result += child(n, count+1) 39 | } else { 40 | result += 1 41 | } 42 | return result 43 | 44 | } 45 | 46 | 47 | /* Dyanmic Programming Solution */ 48 | 49 | const child = (steps, memo = []) => { 50 | if (steps < 0) { 51 | return 0; 52 | } else if (steps === 0) { 53 | return 1; 54 | } else if (memo[steps]) { 55 | return memo[steps]; 56 | } else { 57 | memo[steps] = child(steps - 1, memo) + child(steps - 2, memo) + child(steps - 3, memo); 58 | return memo[steps]; 59 | } 60 | } 61 | 62 | /* Best Solution but for specific reasons... can you figure out why it's better? and also why this solution is possible? */ 63 | 64 | const childhoodStairs = function(n) { 65 | let steps = [0,1,1] 66 | while (n > 2) { 67 | steps.push(steps.shift() + steps[0] + steps[1]) 68 | n-- 69 | } 70 | return steps[0] + steps[1] + steps[2] 71 | } 72 | -------------------------------------------------------------------------------- /Whiteboarding/Counting_Squares/README.md: -------------------------------------------------------------------------------- 1 | # Counting Squares 2 | ## Prompt 3 | 4 | Create a function that takes in two numbers and returns the count of squares inbetween the two numbers. 5 | Your function should run in constant time (O(N)) 6 | 7 | Example to give 8 | ``` 9 | 10 | Input: 12, 56 11 | Output: 4 12 | 13 | Explanation: 14 | 15 | Only perfect Squares between 12 and 56 are: 16, 25, 36, 49 16 | So the count would be 4 17 | 18 | ``` 19 | 20 | -------------------------------------------------------------------------------- /Whiteboarding/Counting_Squares/SOLUTION.js: -------------------------------------------------------------------------------- 1 | const countingSquares = (min, max) => { 2 | return Math.floor(Math.sqrt(max)) - Math.floor(Math.sqrt(min)) 3 | } -------------------------------------------------------------------------------- /Whiteboarding/Counting_Squares/SOLUTION.md: -------------------------------------------------------------------------------- 1 | ## Solution 2 | 3 | The brute force of this is pretty obvious... 4 | Loop through and check if the number is a perfect square. 5 | 6 | But to make this function constant time we need a better approach. 7 | Thankfully a small math trick to know is if you take the square root of a number and round it down the number you get is the largest square number in the range of 0 to the number you started with 8 | 9 | Example: 10 | 11 | If you square root 18 and round down you get 4. 4x4 gives you 16 which is the largest perfect square between 0 -> 18 12 | 13 | So if 4x4 is in that range would it be too much to assume 3x3 is? 14 | As 3x3 = (9) is less than 18. 15 | So is 2x2 = (4) 16 | And 1x1 = (1) 17 | 18 | So if you notice the count of square numbers under 18 is 4 which is also the Math.floor(Math.sqrt(18)) 19 | 20 | So if we do that operation for the larger number then we know the number of perfect squares between 0 and that larger number. We still need between the count between the smaller and larger number and not before the smaller number (between 0 and the smaller number) 21 | 22 | 0 -> [Numbers we don't care about] -> Smaller # -> [Numbers we want] -> Larger # 23 | 24 | So what if we do this same approach to calculate all the perfect squares between the smaller number and 0 and then subtract those from what we found when we calculated the square root of the larger number. This would then give us the count of perfect sqaures for the space between the larger and smaller number! -------------------------------------------------------------------------------- /Whiteboarding/Couples_Holding_Hands/README.md: -------------------------------------------------------------------------------- 1 | ## Prompt 2 | 3 | N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum number of swaps so that every couple is sitting side by side. A swap consists of choosing any two people, then they stand up and switch seats. 4 | 5 | The people and seats are represented by an integer from 0 to 2N-1, the couples are numbered in order, the first couple being (0, 1), the second couple being (2, 3), and so on with the last couple being (2N-2, 2N-1). 6 | 7 | The couples' initial seating is given by row[i] being the value of the person who is initially sitting in the i-th seat. 8 | 9 | Examples 10 | ``` 11 | Input: row = [0, 2, 1, 3] 12 | Output: 1 13 | Explanation: We only need to swap the second (row[1]) and third (row[2]) person. 14 | 15 | Input: row = [3, 2, 0, 1] 16 | Output: 0 17 | Explanation: All couples are already seated side by side. 18 | 19 | ``` 20 | 21 | Notes: 22 | ``` 23 | len(row) is even and in the range of [4, 60]. 24 | row is guaranteed to be a permutation of 0...len(row)-1. 25 | ``` 26 | -------------------------------------------------------------------------------- /Whiteboarding/Couples_Holding_Hands/SOLUTION.js: -------------------------------------------------------------------------------- 1 | /* 2 | NOTE: There is more than likely a more optimal solution that is O(N) time complexity. 3 | Feel free to submit a pull request with a more optomized solution. 4 | */ 5 | 6 | function sortCouples(row){ 7 | let count = 0 8 | 9 | //helperFunciton 10 | const swapHelper = (value, index) => { 11 | let oldIndex = row.indexOf(value) 12 | let currentValue = row[index] 13 | row[index] = value 14 | row[oldIndex] = currentValue 15 | count += 1 16 | } 17 | for(var i=0;i setB.size) { 13 | // Iterate the smaller set for efficiency. 14 | [setA, setB] = [setB, setA]; 15 | } 16 | 17 | for (var elem of setA) { 18 | if (setB.has(elem)) { 19 | return true; 20 | } 21 | } 22 | return false; 23 | }; 24 | 25 | const befriend = function(personA, personB) { 26 | personA.addFriend(personB); 27 | personB.addFriend(personA); 28 | }; 29 | 30 | const getFriends = function(people) { 31 | const allFriends = new Set(); 32 | people.forEach((person) => { 33 | person.friends.forEach((friend) => { 34 | allFriends.add(friend); 35 | }); 36 | }); 37 | return allFriends; 38 | }; 39 | 40 | const calculateDegreesOfSeparation = function(personA, personB) { 41 | if (personA === personB) { 42 | return 0; 43 | } 44 | 45 | let friendsA = new Set([personA]); 46 | let friendsB = new Set([personB]); 47 | let depth = 1; 48 | while (friendsA.size > 0 && friendsB.size > 0) { 49 | friendsA = getFriends(friendsA); 50 | if (intersects(friendsA, friendsB)) { 51 | return depth; 52 | } 53 | depth += 1; 54 | 55 | friendsB = getFriends(friendsB); 56 | if (intersects(friendsA, friendsB)) { 57 | return depth; 58 | } 59 | depth += 1; 60 | } 61 | return -1; 62 | }; 63 | -------------------------------------------------------------------------------- /Whiteboarding/Degrees_of_Separation/SOLUTION.md: -------------------------------------------------------------------------------- 1 | # **Calculate degrees of separation** 2 | #### All credit goes to Tim Manfield https://github.com/tim-hr/stuff/wiki/System-design:-Calculate-degrees-of-separation 3 | 4 | ## Data structure analysis 5 | 6 | You have two trees, with Person A as the root node of 1st tree, and Person B as the root node of the 2nd tree. 7 | 8 | ## Search strategy analysis 9 | 10 | ### DFS vs BFS 11 | 12 | When traversing a tree, you have two basic options -- depth-first traversal (DFS) and breadth-first traversal (BFS). 13 | 14 | Friend graphs in social networks tend to be shallow but broad (remember you are only a handful of degrees removed from anyone on earth!). 15 | 16 | So for this use case, BFS is clearly superior to DFS, because DFS will take a lot longer to discover that you are merely 1 degree removed away from a friend. 17 | 18 | ### Single-direction BFS 19 | 20 | So you can start a Person A and traverse the friend-tree looking for Person B, counting the "levels" as you go. 21 | 22 | To illustrate, let's assume naively that each person anywhere in the population has 100 friends and in this particular case all the friends are distinct. 23 | 24 | So Person A has 100 friends, who then have 10,000 friends, who then have 1,000,000 friends. Person B is somewhere in the A's third-degree group of 1,000,000 friends. 25 | 26 | If you search directly for Person B, it looks like this: 27 | 28 | ![image](http://i.imgur.com/PR1d7bPl.png) 29 | 30 | ### Launch from both directions 31 | 32 | Instead of looking directly for Person B, it's a lot more efficient on average to launch the BFS from both directions and look for a common friend. 33 | 34 | Same scenario as above -- Person A has 100 friends, who then have 10,000 friends, who then have 1,000,000 friends. And the same holds for Person B. 35 | 36 | ![image](http://i.imgur.com/tRnMzqWl.png) 37 | 38 | Notice how the "common friends" approach can dramatically cut down the processing. 39 | 40 | ### Side note 41 | 42 | This is assuming no further optimizations. In particular, we are not checking for an intersection while fetching friends -- the supplied diagrams assume that the entire set of friends at a given degree is assembled first, _then_ intersection is computed, which of course need not be the case. However the diagrams give the basic idea -- meeting in the middle is going to be a lot less work on average. 43 | 44 | ## Reference implementation 45 | 46 | You may or may not need to provide an actual implementation to answer this problem. Often, you don't -- it suffices to provide an algorithmic description. 47 | 48 | However for reference here is a simple implementation ([gist with rough tests](https://gist.github.com/tim-hr/08519a94b6ba56f97d8a7dbf73c38812)). 49 | 50 | ## How to scale this 51 | 52 | When you have huge user populations as large as LinkedIn or Facebook, and then track the ginormous number of relationships between those users, you generally can't fit all that data into memory on one machine. 53 | 54 | Adn even if you theoretically could, you probably still want to parallelize the processing for speed's sake, at least across different CPU cores on the same machine, or much more likely, distributed across different machines. 55 | 56 | So, how can you break up this problem for distribution? 57 | 58 | ### Analyze the processing phases for distribution / parallelization 59 | 60 | To answer that, what are the different aspects of processing? 61 | 62 | * the collection of node A friends into a friend set 63 | * the collection of node B friends into a friend set 64 | * the intersection of the friend set 65 | * the orchestration of the above, including tracking current degrees of separation 66 | 67 | You can envision each of the above pieces living in a different process and/or a different server, and tying the processing together with network calls. 68 | 69 | The orchestrator would begin the processing for each degree of separation, break up the work into chunks, farm out the chunks as messages/jobs with a message-bus/job-queuing part of your system architecture. External workers would do the fetching of friends and build up the friend set in a common transient data store. This would automatically start happening in parallel once the number of friends at given degree became larger than the per-worker batch size, thus dramatically speeding up the fetch-and-store operation. 70 | 71 | When the jobs are all done for a given phase (note: a "phase" could correspond to the first half or the second half of the `while` loop in the `calculateDegreesOfSeparation` above), then the orchestrator could either directly compute the intersection between sets or ask the common transient data store to do so. 72 | 73 | ### redis as an analogy 74 | 75 | For example, Redis has a native Set data type, as well as facilities for detecting and fully-computing intersections between sets. LinkedIn and Facebook don't use Redis that way, because that tool doesn't scale well enough for their tremendous data sets, but you can speak to what you know, and could offer that as an analogy for how this might work. 76 | 77 | ### map/reduce as a real potential solution 78 | 79 | You can look at map/reduce as an abstraction for organizing this type of processing. Here's [a random article describing that](http://stevekrenzel.com/finding-friends-with-mapreduce). 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /Whiteboarding/Dictionary_Words/README.md: -------------------------------------------------------------------------------- 1 | # Dictionary Words 2 | ## Prompt 3 | Given an input word as a string, and an dictionary (represented by an array of strings), 4 | output an array containing the word or words that are the longest permutations of the input 5 | word. 6 | 7 | Examples: 8 | ``` 9 | Given: "garage", ["age", "gear", "rage", "agar", "garage", "garages"] 10 | Output: ["garage"] 11 | 12 | Given: "parade", ["ad", "rap", "par", "read", "dear", "pear"] 13 | Output: ["read, "dear", "pear"] 14 | ``` 15 | -------------------------------------------------------------------------------- /Whiteboarding/Dinning_Philosophers/README.md: -------------------------------------------------------------------------------- 1 | # Dining Philosophers 2 | 3 | ## Prompt 4 | 5 | Five silent philosophers sit at a round table with bowls of spaghetti. Forks are placed between each pair of adjacent philosophers. 6 | 7 | Each philosopher must alternately think and eat. However, a philosopher can only eat spaghetti when they have both left and right forks. Each fork can be held by only one philosopher and so a philosopher can use the fork only if it is not being used by another philosopher. After an individual philosopher finishes eating, they need to put down both forks so that the forks become available to others. A philosopher can take the fork on their right or the one on their left as they become available, but cannot start eating before getting both forks. 8 | 9 | Eating is not limited by the remaining amounts of spaghetti or stomach space; an infinite supply and an infinite demand are assumed. 10 | 11 | The problem is how to design a discipline of behavior (a concurrent algorithm) such that no philosopher will starve; i.e., each can forever continue to alternate between eating and thinking, assuming that no philosopher can know when others may want to eat or think. 12 | 13 | ![Alt-text](https://upload.wikimedia.org/wikipedia/commons/7/7b/An_illustration_of_the_dining_philosophers_problem.png) 14 | -------------------------------------------------------------------------------- /Whiteboarding/Format_Example/README.md: -------------------------------------------------------------------------------- 1 | # Title 2 | ## Prompt 3 | 4 | Please write out the prompt that will be given to the person whiteboarding 5 | 6 | Example to give 7 | ``` 8 | Example here 9 | 10 | ``` 11 | -------------------------------------------------------------------------------- /Whiteboarding/Format_Example/SOLUTION.js: -------------------------------------------------------------------------------- 1 | const exampleFunction = () => { 2 | //solution code 3 | } 4 | 5 | /* 6 | Please give detailed, well commented, and styled code for this solution file. 7 | */ 8 | -------------------------------------------------------------------------------- /Whiteboarding/Format_Example/SOLUTION.md: -------------------------------------------------------------------------------- 1 | ## Solution 2 | 3 | Please list out any necessary edge cases the person whiteboarding should find with examples if applicable 4 | If there are several commonly asked questions or issues with the prompt please list them out here along with the appropriate answer 5 | 6 | Examples to give 7 | ``` 8 | Example here 9 | 10 | ``` 11 | Please give a general outline to the solution and what is neccessary to consider so that this outline is applicable to different solutions 12 | -------------------------------------------------------------------------------- /Whiteboarding/IOS_BST/README.md: -------------------------------------------------------------------------------- 1 | # In Order Sucessor of a Binary Search Tree 2 | ## Prompt 3 | 4 | Given a binary search tree and a node in it, find the in-order successor of that node in the BST. 5 | 6 | Note: If the given node has no in-order successor in the tree, return null. 7 | 8 | What is the time complexity of your solution? 9 | 10 | 11 | Examples to give 12 | ``` 13 | 1.) 14 | 15 | Input: root = [2,1,3], p = 1 16 | 17 | 2 18 | / \ 19 | 1 3 20 | 21 | Output: 2 22 | 23 | 2.) 24 | 25 | Input: root = [5,3,6,2,4,null,null,1], p = 6 26 | 27 | 5 28 | / \ 29 | 3 6 30 | / \ 31 | 2 4 32 | / 33 | 1 34 | 35 | Output: null 36 | 37 | ``` -------------------------------------------------------------------------------- /Whiteboarding/IOS_BST/SOLUTION.js: -------------------------------------------------------------------------------- 1 | var inorderSuccessor = function(tree, p, flag = false) { 2 | let test; 3 | if(flag){ 4 | if(tree.left){ 5 | return inorderSuccessor(tree.left, p, true) 6 | } else{ 7 | return tree.val 8 | } 9 | } else{ 10 | if(p.val === tree.val){ 11 | if(tree.right){ 12 | return inorderSuccessor(tree.right, p, true) 13 | } else{ 14 | return null 15 | } 16 | } else if( p.val < tree.val){ 17 | //go left 18 | test = inorderSuccessor(tree.left, p) 19 | if(test === null){ 20 | return tree.val 21 | } else{ 22 | if(test-p.val < tree.val-p.val){ 23 | return test 24 | } else{ 25 | return tree.val 26 | } 27 | } 28 | } else{ 29 | //go right 30 | test = inorderSuccessor(tree.right, p) 31 | return test 32 | } 33 | } 34 | }; 35 | 36 | // Time complexity of this solution is O(D) with D equal to the depth of the tree -------------------------------------------------------------------------------- /Whiteboarding/Longest_Uniform_Subsequence/README.md: -------------------------------------------------------------------------------- 1 | # Longest Uniform Subsequence 2 | ## Prompt 3 | 4 | Given a string, find the longest uniform subsequence in the string, 5 | return an array where the first number is the start index of the subsequence, 6 | and the second number is the length of the subsequence. 7 | 8 | A uniform subsequence is defined as any subsequence where all the 9 | characters are the same. 10 | 11 | ``` 12 | Examples: 13 | 14 | "" -> [-1, 0] 15 | "aaabbbbccd" -> [3, 4] 16 | "hello world" -> [2, 2] 17 | 18 | ``` 19 | -------------------------------------------------------------------------------- /Whiteboarding/MaxPathSum/README.md: -------------------------------------------------------------------------------- 1 | Given a non-empty binary tree, find the maximum path sum. 2 | For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root. 3 | 4 | 5 | Example 1: 6 | 7 | Input: [1,2,3] 8 | 9 | 1 10 | / \ 11 | 2 3 12 | 13 | Output: 6 14 | Example 2: 15 | 16 | Input: [-10,9,20,null,null,15,7] 17 | 18 | -10 19 | / \ 20 | 9 20 21 | / \ 22 | 15 7 23 | 24 | Output: 42 -------------------------------------------------------------------------------- /Whiteboarding/MaxPathSum/Solution.js: -------------------------------------------------------------------------------- 1 | var maxPathSum = function(root) { 2 | if(root === null) return; 3 | let total = root.val; 4 | const count = (node) => { 5 | let left = 0,right = 0; 6 | if(node.left !== null){ 7 | left = count(node.left) 8 | } 9 | if(node.right !== null){ 10 | right = count(node.right) 11 | } 12 | total = Math.max(total, node.val+left+right, node.val+left, node.val+right) 13 | return Math.max(node.val, node.val+left, node.val+right); 14 | } 15 | count(root) 16 | return total 17 | }; -------------------------------------------------------------------------------- /Whiteboarding/Merge_LinkList/README.md: -------------------------------------------------------------------------------- 1 | # Merge Linked Lists 2 | ## Prompt 3 | 4 | Given 2 Linked lists, return a single linked list with the sumed values of the two input linked linsts. 5 | 6 | Example to give 7 | ``` 8 | Linked List 1: {value: 1, next: ->} {value: 2, next: ->} {value: 3, next: null} 9 | Linked List 2: {value: 1, next: ->} {value: 2, next: null} 10 | 11 | Returns: 12 | {value: 2, next: ->} {value: 4, next: ->} {value: 3, next: null} 13 | 14 | ``` 15 | **NOTES** 16 | 17 | There are varying degrees of difficulty with this problem with minor changes.
18 | 19 | Easiest version: Return an array of the sumed values
20 | Medium version: Return a LL of the sumed values (create own LL constructor)
21 | Hard version: Return an LL of sumed values and with time compelxity O(N) 22 | -------------------------------------------------------------------------------- /Whiteboarding/Merge_LinkList/SOLUTION.js: -------------------------------------------------------------------------------- 1 | function mergeLinkedLists(LinkedListA, LinkedListB) => { 2 | let A = LinkedListA.head 3 | let B = LinkedListB.head 4 | var mergedList = new LinkedList() 5 | while(A !== null || B !== null){ 6 | let sum = 0 7 | if(A !== null){ 8 | sum += A.value 9 | A = A.next 10 | } 11 | if(B !== null){ 12 | sum += B.value 13 | B = B.next 14 | } 15 | mergedList.addToTail(sum) 16 | } 17 | return mergedList 18 | } 19 | 20 | //Linked List Constructor 21 | var LinkedList = function() { 22 | var list = {}; 23 | list.head = null; 24 | list.tail = null; 25 | 26 | list.addToTail = function(value) { 27 | 28 | var newTail = Node(value); 29 | 30 | if (!list.head) { 31 | list.head = newTail; 32 | } 33 | 34 | if (list.tail) { 35 | list.tail.next = newTail; 36 | } 37 | 38 | list.tail = newTail; 39 | }; 40 | 41 | list.removeHead = function() { 42 | 43 | if (list.head === null) { 44 | return null; 45 | } 46 | 47 | var currentHead = list.head; 48 | list.head = list.head.next; 49 | 50 | return currentHead.value; 51 | }; 52 | 53 | return list; 54 | }; 55 | 56 | //Node Constructor 57 | var Node = function(value) { 58 | var node = {}; 59 | 60 | node.value = value; 61 | node.next = null; 62 | 63 | return node; 64 | }; 65 | 66 | -------------------------------------------------------------------------------- /Whiteboarding/Merge_LinkList/SOLUTION.md: -------------------------------------------------------------------------------- 1 | # Merge Linked-Lists solution 2 | 3 | This problem has varying levels of difficulties: 4 | 5 | Easy: Return an Array of the summed values 6 | Medium: Return a Linked List with the node values being the summed values 7 | Hard: Return a Linked List with the node values being the summed values in linear time 8 | 9 | Keys things the person will hopefully ask about are - 10 | 11 | 1.) Clarificaiton of the inputs 12 | 2.) What does the LL look like and show their familiarity with the data structure but also to make sure there is a common understanding what the data structure will look like between the interviewer and interviewee 13 | 3.) **MOST IMPORTANTLY** Can they expect linked lists with differing amounts of nodes (Yes they can!) 14 | 15 | General outline to the solution is - 16 | 17 | * Defining a linked list constructor and creating an instance of it 18 | * Recursively iterating through both linked lists at the same time with two pointers (one for each list) 19 | * Checking inside the recursion if the pointer has reached null 20 | * Adding the node.values that the pointers are pointing to and passing that into the addToTail method of your returning link list 21 | * Recurse until both pointers reach null and the return the newly created linked list -------------------------------------------------------------------------------- /Whiteboarding/Mountain_Climbers/README.md: -------------------------------------------------------------------------------- 1 | # Mountain Climbers 2 | ## Prompt 3 | Given a 2 dimensional array of whole numbers please tell me the fewest amount of steps it would take to get from the smallest number to the highest number in the 2D array. Steps must be made to larger or same value numbers 4 | 5 | i.e. 2 -> 2 or 2 -> 4 but NOT 2 -> 1 6 | 7 | Example to give 8 | ``` 9 | [ 10 | [4, 5, 2], 11 | [3, 1, 6], 12 | [7, 8, 9] 13 | ] 14 | 15 | Steps = 2 16 | 17 | ``` 18 | -------------------------------------------------------------------------------- /Whiteboarding/Mountain_Climbers/SOLUTION.js: -------------------------------------------------------------------------------- 1 | function mountainClimbers(array){ 2 | let steps = null; 3 | //our measures of highest and lowest 4 | let min = Infinity; 5 | let max = -Infinity; 6 | //coordinates of row/column 7 | let lowestPoint = [] 8 | let highestPoint = [] 9 | 10 | //find the Largest and Smallest values 11 | const findMinMax = (array) => { 12 | for(var i=0;i max){ 19 | max = array[i][j] 20 | highestPoint = [i, j] 21 | } 22 | } 23 | } 24 | } 25 | 26 | //Helper function to check to see if a row/column actually exists before stepping there 27 | const doesItExist = (row, column) => { 28 | if(row >= array.length || row < 0){ 29 | return false 30 | } 31 | if(array.length > 0){ 32 | if(column >= array[0].length || column < 0){ 33 | return false 34 | } 35 | } 36 | return true 37 | } 38 | 39 | //This will be our recursive function 40 | const climb = (row, column, count, path) =>{ 41 | //Check to see if we made it to the top 42 | if(row === highestPoint[0] && column === highestPoint[1]){ 43 | if(count < steps || steps === null){ 44 | steps = count 45 | return 46 | } 47 | } 48 | //Check Left 49 | if(doesItExist(row, column-1)){ 50 | if(array[row][column] <= array[row][column-1] && path.indexOf(JSON.stringify([row, column-1])) === -1){ 51 | climb(row, column-1, count+1, path.concat(JSON.stringify([row, column-1]))) 52 | } 53 | } 54 | //Check Right 55 | if(doesItExist(row, column+1)){ 56 | if(array[row][column] <= array[row][column+1] && path.indexOf(JSON.stringify([row, column+1])) === -1){ 57 | climb(row, column+1, count+1, path.concat(JSON.stringify([row, column+1]))) 58 | } 59 | } 60 | //Check Up 61 | if(doesItExist(row-1, column)) 62 | if(array[row][column] <= array[row-1][column] && path.indexOf(JSON.stringify([row-1, column])) === -1){ 63 | climb(row-1, column, count+1, path.concat(JSON.stringify([row-1, column]))) 64 | } 65 | //Check Down 66 | if(doesItExist(row+1, column)) 67 | if(array[row][column] <= array[row+1][column] && path.indexOf(JSON.stringify([row+1, column])) === -1){ 68 | climb(row+1, column, count+1, path.concat(JSON.stringify([row+1, column]))) 69 | } 70 | } 71 | 72 | //OUR FUNCTION CALLS START HERE 73 | findMinMax(array) 74 | if(min === max){ 75 | //if the array has all the same numbers return 0 76 | return 0 77 | } else{ 78 | //Calling our recursive function to find shortest number of steps 79 | climb(lowestPoint[0], lowestPoint[1], 0, [JSON.stringify(lowestPoint)]) 80 | } 81 | return steps 82 | } -------------------------------------------------------------------------------- /Whiteboarding/Mountain_Climbers/SOLUTION.md: -------------------------------------------------------------------------------- 1 | ## Solution 2 | 3 | ### Common Questions 4 | * Will there be duplicate values or all integers will be unique? 5 | ``` 6 | A.) Duplicate maximum values is the more difficult version of this problem which the included solution 7 | will not handle. Same for duplicate minimums. There will be duplicate values though inbetween that are 8 | not the maximum or minimum value. 9 | ``` 10 | * Will I be given anything besides a 2D array of integers? 11 | ``` 12 | A.) No they will only be given a 2D array of integers 13 | ``` 14 | * Will the 2D array always be a square? 15 | ``` 16 | A.) The 2D array will always be either a square or a rectangle 17 | ``` 18 | 19 | ### Edge Cases 20 | * No path to return 21 | ``` 22 | Example: 23 | [ 24 | [4, 3, 5, 1] 25 | [2, 2, 2, 3] 26 | [4, 5, 6, 2] 27 | [5, 2, 8, 7] 28 | ] 29 | 30 | If no path, return undefined 31 | ``` 32 | * Negative Numbers 33 | ``` 34 | Example: 35 | [ 36 | [-2, -5, -1] 37 | [2, 0, 1] 38 | [5, 6, -1] 39 | ] 40 | 41 | When finding min and max position the person's inital variable have to be min= infinity, max = -infinity, 42 | or both equal to null/undefined 43 | ``` 44 | * Flat Plane/Local Maximum 45 | ``` 46 | Example: 47 | [ 48 | [0,3,4,5,6,6,3] 49 | [1,3,4,3,6,6,3] 50 | [2,3,4,3,3,3,3] 51 | [4,4,4,5,6,7,9] 52 | ] 53 | 54 | A solution without keeping track of where the person have moved from would hit an infinite loop 55 | in this solution. Any data structure that keeps track of places been and they implement a check 56 | against it with each step would handle this. 57 | ``` 58 | -------------------------------------------------------------------------------- /Whiteboarding/Permutations_I/README.md: -------------------------------------------------------------------------------- 1 | # Permutations I 2 | ## Prompt 3 | 4 | Given an array of unique integers, return an array of all possible permutations.
5 | 6 | 7 | Example to give 8 | ``` 9 | Input: [1, 2, 3] 10 | Output: [ 11 | [1,2,3], 12 | [1,3,2], 13 | [2,1,3], 14 | [2,3,1], 15 | [3,1,2], 16 | [3,2,1] 17 | ] 18 | 19 | 20 | ``` 21 | -------------------------------------------------------------------------------- /Whiteboarding/Permutations_II/README.md: -------------------------------------------------------------------------------- 1 | # Permutations I 2 | ## Prompt 3 | 4 | Given an array of unique integers, return an array of all possible permutations.
5 | 6 | 7 | Example to give 8 | ``` 9 | Input: [1, 2, 3] 10 | Output: [ 11 | [1,2,3], 12 | [1,3,2], 13 | [2,1,3], 14 | [2,3,1], 15 | [3,1,2], 16 | [3,2,1] 17 | ] 18 | 19 | 20 | ``` 21 | -------------------------------------------------------------------------------- /Whiteboarding/Poker_Hands/README.md: -------------------------------------------------------------------------------- 1 | ## Prompt 2 | ```markdown 3 | Write a function that will return the rank of a poker hand. 4 | ``` 5 | 6 | ##### Example of a hand - ['1♦', '12♣', '7♦', '9♠', '13♦'] 7 | 8 | * Each element will always have a number that represents the rank of the card, followed by the suit. 9 | * Each element is a string 10 | * Aces are represented by the character 0 (zero) 11 | * Suits are represented as follows - ♦♥♣♠ , these are string characters 12 | * Each number corresponds to its respective card rank, with 11,12,13 == J,Q,K 13 | * There is only one output - the highest rank of the hand 14 | 15 | ## Poker Hand Rankings 16 | 17 | 1. Royal Flush 18 | 2. Straight Flush 19 | 3. Four of a Kind 20 | 4. Full House 21 | 5. Straight 22 | 6. Flush 23 | 7. Three of a Kind 24 | 8. Two Pair 25 | 9. Pair 26 | 10. High Card 27 | 28 | 29 | ## Sample Cases 30 | 31 | ``` 32 | let hand = ['1♦', '12♦', '7♦', '9♦', '13♦'] 33 | calculateRank(hand) === 'Flush'; 34 | let hand2 = ['12♦', '12♣', '12♥', '9♦', '9♥'] 35 | calculateRank(hand2) === 'Full House'; 36 | ``` 37 | -------------------------------------------------------------------------------- /Whiteboarding/Poker_Hands/pokerhands.js: -------------------------------------------------------------------------------- 1 | let pokerHands = (hand) => { 2 | 3 | let isSuited = checkSuited(hand); 4 | let isRange = checkRange(hand); 5 | let frequencies = checkFrequencies(hand); 6 | 7 | if (isSuited && isRange) { 8 | if (frequencies[4][0] === '13' && frequencies[0][0] === '1') { 9 | return 'Royal Flush'; 10 | } else { 11 | return 'Straight Flush'; 12 | } 13 | } 14 | 15 | if (frequencies.length === 2) { 16 | if (frequencies[0][1] === 4) { 17 | return 'Four of a Kind'; 18 | } else { 19 | return 'Full House'; 20 | } 21 | } 22 | 23 | if (isSuited && !isRange) return 'Flush'; 24 | if (isRange && !isSuited) return 'Straight'; 25 | 26 | if (frequencies.length === 3) { 27 | if (frequencies[0][1] === 3) { 28 | return 'Three of a Kind'; 29 | } else { 30 | return 'Two Pair'; 31 | } 32 | } 33 | 34 | if (frequencies.length === 4) return 'One Pair'; 35 | return 'High Card'; 36 | } 37 | 38 | 39 | 40 | 41 | 42 | let checkSuited = (hand) => { 43 | let suit = hand[0][hand[0].length - 1]; 44 | for (let i = 1; i < hand.length; i++) { 45 | let currentSuit = hand[i][hand[i].length - 1]; 46 | if (suit !== currentSuit) { 47 | return false 48 | } 49 | } 50 | return true; 51 | } 52 | 53 | let checkRange = (hand) => { 54 | let cardNumbers = hand.map(card => Number(card.slice(0, card.length - 1))); 55 | cardNumbers.sort((a,b) => a-b); 56 | let cardNumbersWithAce = cardNumbers.slice(); 57 | if (cardNumbers.includes(1)) { 58 | cardNumbersWithAce.shift(); 59 | cardNumbersWithAce.push(14); 60 | } 61 | cardNumbers = isOrdered(cardNumbers); 62 | cardNumbersWithAce = isOrdered(cardNumbersWithAce); 63 | return cardNumbers || cardNumbersWithAce 64 | } 65 | 66 | let isOrdered = (array) => { 67 | return array.every((card, i) => { 68 | if (i === 0) return true; 69 | return card === array[i - 1] + 1; 70 | }) 71 | } 72 | 73 | 74 | let checkFrequencies = (hand) => { 75 | let hashMap = {}; 76 | hand.forEach((card) => { 77 | let cardNumber = Number(card.slice(0, card.length - 1)) 78 | hashMap[cardNumber] ? hashMap[cardNumber] += 1 : hashMap[cardNumber] = 1; 79 | }); 80 | 81 | let frequencies = Object.entries(hashMap); 82 | return frequencies.sort((a,b) => b[1] - a[1]); 83 | 84 | } 85 | -------------------------------------------------------------------------------- /Whiteboarding/Poker_Hands/solution.md: -------------------------------------------------------------------------------- 1 | # Poker Hands - Solution 2 | 3 | *[Medium article on this solution](https://medium.com/@jonathanyuenby/how-i-built-my-first-react-native-app-part-2-how-do-i-figure-out-the-strength-of-a-poker-hand-d08f1f4b3c09)* <- Give it some claps if you enjoyed this solution 4 | 5 | ### Algorithm 6 | 7 | An easy way to approach this problem is by identifying the key rules and breaking it down into smaller, individual problems. 8 | 9 | We know that we just need to return the highest poker rank, so we can check each ranking from top to bottom and see whether or not the hand satisfies the respective requirement. 10 | 11 | To start, let's think about some of the common rules that decide the ranking of each hand. 12 | 1. Are all the cards of the same suit? 13 | 2. Do the numbers of a card form a range? (consecutive numbers) 14 | 3. What are the frequencies for each card? 15 | 16 | 17 | 18 | Let's break down our problem with these new rules and apply them to our ranking list. 19 | 20 | | Poker Rank | isSuited | isRange | Frequency | 21 | | ------------- |:-------------:| :-------------:| :-------------: 22 | | Royal Flush | ✓ | ✓ | [1,1,1,1,1] 23 | | Straight Flush | ✓ | ✓ | [1,1,1,1,1] 24 | | Four of a Kind | | | [4,1] 25 | | Full House | | | [3,2] 26 | | Flush | ✓ | | X 27 | | Straight | | ✓ | [1,1,1,1,1] 28 | | Three of a Kind | | | [3,1,1] 29 | | Two Pair | | | [2,2,1] 30 | | One Pair | | | [2,1,1,1] 31 | | High Card | | | [1,1,1,1,1] 32 | 33 | Now our approach is simpler, we know that we can cross off certain rankings if they don't satisfy `isSuited` or `isRange`. We just need to figure out a way to implement the frequency rule. 34 | 35 | If we use an array to represent the frequency of each card, we can narrow down what the ranking is based on it's length. For rankings with the same "frequency lengths", we need to know the contents of the frequency array. 36 | 37 | To make it easier for readibility and to handle more cases, we can represent the frequencies with an array of tuples, with the first element representing the card number, and the second representing the specific card's frequencies. As such: 38 | 39 | `frequency === [[10, 4],[1, 1]]` 40 | 41 | Now our frequency array has a wealth of information in it. We can use the length of the array itself to narrow down our options, and if needed, we can look further into the array to find out what specific cards were in our hand, as well as how many times each card appeared. And finally, since our tuples are ordered by frequences from most to least, we can easily distinguish between a Four of a Kind and a Full House. 42 | 43 | Example use case: ```frequency[0][0]``` will give us the card that appears the most in our hand, and ```frequency[0][1]``` will give us how many times it appeared. 44 | 45 | Note that this is entirely optional but it is a good way to approach problems. Think about the how you want to order your information and what they can be used for. It will be especially impressive if you can come up with ways to reuse old code or satisfy future problems. 46 | 47 | 48 | --- 49 | 50 | ### Pseudo-pseudo code 51 | 52 | Now that we have our 3 rules set up, we can set up some statements that help us decide what to return. 53 | 54 | We know that out of our three helper functions, two return a boolean and one returns an array of tuples (in a very specific format). If we put all three of those returned values into their own variables, it makes things easier 55 | 56 | `isSuited === T/F` 57 | `isRange === T/F` 58 | `frequencies === array of tuples` 59 | 60 | Then we just write a bunch of if statements that correspond to our table. 61 | 62 | ``` 63 | if(isSuited && isRange) { 64 | if(frequencies[4][0] === '13' && frequencies[0][0] === '1') { 65 | return 'Royal Flush' 66 | } else { 67 | return 'Straight Flush' 68 | } 69 | } 70 | ``` 71 | 72 | We know that if isSuited && isRange is true, there are only two possible outcomes, and whenever isRange is true means that the frequency array must contain 5 elements, so we can access the tuples directly with confidence. Here we are checking if the last card is a K, if it is then it has to be a Royal Flush. 73 | 74 | 75 | Looking back at our table, we can use process of elimination with our boolean values, however, if both are false, then things get a little bit trickier. Let's look at what we should do when comparing frequencies only. 76 | 77 | ``` 78 | if (frequencies.length === 2) { 79 | if (frequencies[0][1] === 4) { 80 | return 'Four of a Kind' 81 | } else { 82 | return 'Full House' 83 | } 84 | } 85 | ``` 86 | 87 | Note that the card number itself is a string value, whereas the frequency is a number, this is just a personal preference. 88 | 89 | We know that `isSuited === false && isRange === false`, so we just have to check for the next poker ranking, Four of a Kind and Full House, both of which have a frequency array of length 2. Again, we can simply access the second element of the first tuple to find out what the ranking should be. 90 | 91 | We can simply do this for the rest of our table, provided that we actually have our helper functions done correctly. 92 | 93 | 94 | --- 95 | # Actual code 96 | Let's write our helper functions, starting with `checkFrequencies` 97 | #### checkFrequencies (helper function) 98 | ``` 99 | let checkFrequencies = (hand) => { 100 | // create an object to store frequencies 101 | let hashMap = {}; 102 | // loop through each card, if the card exists, add it to it's frequency, if not, set it to 1 103 | hand.forEach((card) => { 104 | let cardNumber = Number(card.slice(0, card.length - 1)) 105 | hashMap[cardNumber] ? hashMap[cardNumber] += 1 : hashMap[cardNumber] = 1; 106 | }) 107 | 108 | // convert the object to an array of tuples 109 | let frequencies = Object.entries(hashMap); 110 | 111 | // sort the frequencies by it's ... frequencies from max to min and return it 112 | return frequencies.sort((a,b) => b[1] - a[1]); 113 | 114 | // that should return an array of tuples in this format [[10, 4],[1, 1]] 115 | } 116 | ``` 117 | 118 | 119 | ## checkRange (helper function) 120 | * The idea of this solution is to create an array consisting solely of the card numbers and sort it, that way we can simply iterate through each number and see if each element is consecutive 121 | * One issue with this solution are the Aces, since they can work both ways (1,2,3,4,5) || (10,11,12,13,1) 122 | * My approach is to create two arrays and reuse our iteration, one where Ace is represented by 1, and the other were it is represented by 14 123 | * Then we can simply run both arrays using the same rules in our iteration, if any of the arrays return true, we can return true for the whole function 124 | ``` 125 | let checkRange = (hand) => { 126 | // create a new array of consisting of just the card numbers by slicing off the suit (last character) 127 | let cardNumbers = hand.map(card => Number(card.slice(0, card.length - 1))); 128 | // sort the arary 129 | cardNumbers.sort((a,b) => a-b); 130 | // create a copy of the array 131 | let cardNumbersWithAce = cardNumbers.slice(); 132 | // if the array has an Ace, take out the 1 and replace it with the 14, push the 14 to the end so that it's still sorted 133 | if (cardNumbers.includes(1)) { 134 | cardNumbersWithAce.shift(); 135 | cardNumbersWithAce.push(14); 136 | } 137 | // just using another helper function for modularity. 138 | cardNumbers = isOrdered(cardNumbers); 139 | cardNumbersWithAce = isOrdered(cardNumbersWithAce); 140 | 141 | // if any one of the two arrays return true, our hand is a range 142 | return cardNumbers || cardNumbersWithAce 143 | } 144 | ``` 145 | 146 | ``` 147 | let isOrdered = (array) => { 148 | // iterate through the array, if at any point after the first card the numbers aren't consecutive, return false 149 | return array.every((card, i) => { 150 | if (i === 0) return true; 151 | return card === array[i - 1] + 1; 152 | }) 153 | } 154 | ``` 155 | 156 | 157 | 158 | ## checkSuited (helper function) 159 | 160 | This one is fairly simple and there are a lot of different ways you can implement this 161 | 162 | ``` 163 | let checkSuited = (hand) => { 164 | // get suit from first card 165 | let suit = hand[0][hand[0].length - 1]; 166 | // loop through rest of cards... 167 | for (let i = 1; i < hand.length; i++) { 168 | let currentSuit = hand[i][hand[i].length - 1]; 169 | // if at any point suit is different, return false 170 | if (suit !== currentSuit) { 171 | return false 172 | } 173 | } 174 | return true; 175 | } 176 | ``` 177 | -------------------------------------------------------------------------------- /Whiteboarding/Purple_Rain/README.md: -------------------------------------------------------------------------------- 1 | ## Prompt 2 | 3 | *To be added* 4 | 5 | Example to give 6 | ``` 7 | Example here 8 | 9 | ``` 10 | -------------------------------------------------------------------------------- /Whiteboarding/README.md: -------------------------------------------------------------------------------- 1 | # White Boarding 2 | The prompt for each white boarding will be in the README.md file of each folder. If you are whiteboarding someone else please read this prompt verbatim. 3 | Notes and general soltuion outline will be listed in the SOLUTION.md file and an example code solution will be available in the SOLUTION.js file. 4 | 5 | ## Contributing 6 | Please follow the example format located in the [Format_Example](https://github.com/JClutch/Test-Bank/tree/master/Whiteboarding/Format_Example) folder. 7 | 8 | Also please read and follow [CONTRIBUTING.md](https://github.com/JClutch/Test-Bank/blob/master/CONTRIBUTING.md) 9 | -------------------------------------------------------------------------------- /Whiteboarding/Sales_Intervals/README.md: -------------------------------------------------------------------------------- 1 | # Sales Intervals 2 | ## Prompt 3 | You are given a class of the following format, where startTime and endTime are inclusive: 4 | 5 | ``` 6 | class Interval(startTime, endTime, price) { 7 | this.startTime = startTime; 8 | this.endTime = endTime; 9 | this.price = price; 10 | } 11 | ``` 12 | 13 | Given an input Array of Intervals, output an array of Intervals such that each Interval indicates 14 | the minimum price for that given Interval. 15 | 16 | Additional Detail: 17 | If there is no Interval that has a price at a given time, return the previous minimum price for that index, 18 | e.g. if there is a gap between intervals, utilize the minimum price from the beginning of the gap. 19 | 20 | 21 | Examples: 22 | ``` 23 | Example: 24 | Input: [Interval(1, 5, 20), Interval(3, 8, 15), Interval (7, 9, 8)] 25 | Output: [Interval(1, 3, 20), Interval(3, 7, 15), Interval(7, 9, 8)] 26 | 27 | Gap Example: 28 | Input: [Interval(1, 5, 20), Interval(6, 10, 15)] 29 | Output: [Interval(1, 6, 20), Interval(6, 10, 15)] 30 | 31 | ``` 32 | -------------------------------------------------------------------------------- /Whiteboarding/Sum_Nested_Array/README.md: -------------------------------------------------------------------------------- 1 | # Sum Nested Array 2 | ## Prompt 3 | 4 | Given an array of values that can include integers and nested arrays, write a function that returns a sum of all the integers in the given array. 5 | 6 | Example: 7 | 8 | ``` 9 | FunctionSum( [5,3,[2,3,[5,4,2],[3,4,5,[[]]],[[3,2,1,[23,[32]]],2]] ,2]] ) 10 | 11 | ``` 12 | 13 | 14 | -------------------------------------------------------------------------------- /Whiteboarding/Sum_Nested_Array/SOLUTION.js: -------------------------------------------------------------------------------- 1 | const sumNested = (array) => { 2 | let total = 0 3 | array.forEach((val) => { 4 | if(Array.isArray(val)){ 5 | total += sumNested(val) 6 | } else{ 7 | total += val 8 | } 9 | }) 10 | return total 11 | } -------------------------------------------------------------------------------- /Whiteboarding/Towers_of_Hanoi/README.md: -------------------------------------------------------------------------------- 1 | # **Towers of Hanoi** 2 | ## Prompt 3 | ```markdown 4 | Imagine a rod with n discs stacked on it in sorted order such that the largest disc sits at the bottom 5 | of the stack and the smallest disc sits on top of the stack. For example, if n = 3, the largest disc (#3) 6 | would be on the bottom, #2 would be in the middle, and #1 would be on the top. 7 | 8 | There are two empty rods next to this rod (let's call them helper and destination). Devise an algorithm that will move all the discs from the start rod to the destination without breaking either of the following rules: 9 | ``` 10 | 1. You may only move one disc at a time. 11 | 1. A disc cannot be placed on top of a smaller disc. 12 | ## The inputs to your algorithm are: 13 | - **n:** an integer 14 | - **start:** a stack containing __n__ values sorted from largest to smallest 15 | - **helper:** an empty stack 16 | - **destination:** an empty stack 17 | - NOTE: it will be helpful to treat each stack as a tuple where the value at index 0 is the stack itself, and the value at index 1 is the name of the stack. 18 | ## The output of your algorithm should be: 19 | ```markdown 20 | Print statements describing each of the steps you must take 21 | to solve the puzzle in the minimum number of moves. 22 | ``` 23 | 24 | ## *Example input:* 25 | - **n = 2** 26 | - **start = [[2, 1], "start"]** 27 | - **helper = [ [ ], "helper" ]** 28 | - **destination: [ [ ], "destination" ]** 29 | ## Example output: 30 | "Disc 1 moved from start to helper", 31 | "Disc 2 moved from start to destination", 32 | "Disc 1 moved from helper to destination" 33 | -------------------------------------------------------------------------------- /Whiteboarding/Towers_of_Hanoi/hanoi.js: -------------------------------------------------------------------------------- 1 | let hanoi = (n, start, helper, destination) => { 2 | if ( n > 0 ) { 3 | // move tower of size n - 1 from start to helper 4 | hanoi(n - 1, start, destination, helper); 5 | // move disc from start to destination and print out the description of the move 6 | if ( start[0].length >= 0 ) { 7 | let disc = start[0].pop(); 8 | console.log('moving disc ' + disc + ' from ' + start[1] + ' to ' + destination[1]); 9 | destination[0].push(disc); 10 | } 11 | // move tower of size n - 1 from helper to destination 12 | hanoi(n - 1, helper, start, destination); 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Whiteboarding/Towers_of_Hanoi/solution.md: -------------------------------------------------------------------------------- 1 | # Towers of Hanoi - solution 2 | The number of moves required to solve this puzzle is given by (2^n) - 1. As such, the sequence of moves becomes difficult to follow as n increases. However, the puzzle can be easily solved for any size input by breaking it down into smaller problems that can be solved recursively. For n = 2, the solution has three steps and looks like this: 3 | # starting position 4 | **start: [2, 1]** 5 | **helper: [ ]** 6 | **destination: [ ]** 7 | 8 | ## move #1 9 | **start: [ 2 ]** 10 | **helper: [ 1 ]** 11 | **destination: [ ]** 12 | 13 | ## move #2 14 | **start: [ ]** 15 | **helper: [ 1 ]** 16 | **destination: [ 2 ]** 17 | 18 | ## move #3 19 | **start: [ ]** 20 | **helper: [ ]** 21 | **destination: [ 2, 1 ]** 22 | 23 | 24 | If we model our algorithm off of this example, we want our algorithm to follow three simple steps: 25 | 1. Move n - 1 discs from **start** to **helper** 26 | 1. Move disc **n** from **start** to **destination** 27 | 1. Move n - 1 discs from **helper** to **destination** 28 | The tricky part of implementing this recursive algorithm is keeping track of the parameters we pass to our function during each recursive call. At the outset, our function is given by: 29 | ```markdown 30 | let hanoi = (n, start, helper, destination) => {...} 31 | ``` 32 | **Step one** is a recursive call given by: 33 | ```markdown 34 | hanoi(n-1, start, destination, helper); 35 | ``` 36 | Notice that, compared to the original function declaration, the positions of **destination** and **helper** are reversed. We will see why this is necessary in the next step. 37 | 38 | **Step two** involves popping the **start** stack and pushing the popped value onto the **destination** stack (and printing out the move that we made): 39 | ```markdown 40 | if ( start[0].length > 0 ) { 41 | let disc = start[0].pop(); 42 | console.log('moving disc ' + disc + ' from ' + start[1] + ' to ' + destination[1]); 43 | destination[0].push(disc); 44 | } 45 | ``` 46 | The key point to understand here is this: *since we change the order of function parameters in the recursive calls, the variables **start** and **destination** will not actually refer to the original function parameters **start** and **destination** at every point in the call stack*. Furthermore, we should notice that this is actually the only step in the solution where we take a disc off of one 'rod' and move it onto another. Everywhere else in the function, we are making recursive calls and flipping around the order of the function parameters. 47 | 48 | **Step three** is a recursive call given by: 49 | ```markdown 50 | hanoi(n-1, helper, start, destination); 51 | ``` 52 | Here, we reverse the positions of **helper** and **start** so that when we recurse, we will be executing the third step of our algorithm, moving a tower of n - 1 discs from **helper** to **destination**. 53 | 54 | Examine the complete solution code below and, if it remains unclear, try to diagram the call stack for n = 1, n = 2, and n = 3. 55 | 56 | let hanoi = (n, start, helper, destination) => { 57 | if ( n > 0 ) { 58 | // move tower of size n - 1 from start to helper 59 | hanoi(n - 1, start, destination, helper); 60 | // move disc from start to destination 61 | if ( start[0].length >= 0 ) { 62 | let disc = start[0].pop(); 63 | console.log('moving disc ' + disc + ' from ' + start[1] + ' to ' + destination[1]); 64 | destination[0].push(disc); 65 | } 66 | // move tower of size n - 1 from helper to destination 67 | hanoi(n - 1, helper, start, destination); 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /Whiteboarding/TwoSums/README.md: -------------------------------------------------------------------------------- 1 | # Two Sums 2 | 3 | ## Prompt 4 | 5 | Write a function that when given an array of numbers and a target integer will return any two integers within the array that could add up to the target value. 6 | 7 | Version 1: Solve in linear time!
8 | Version 2: Solve in linear time and constant space! (yes you can use var/let/const but no arrays, objects, or data structures)
9 | **Note they must ask if all arrays will be sorted as they will be** 10 | 11 | Examples to give 12 | 13 | ``` 14 | Inputs: [1,3,5] , 6 15 | Output: [1,5] 16 | 17 | Inputs: [1,2,3,4] , 7 18 | Output: [3,4] 19 | 20 | ``` 21 | -------------------------------------------------------------------------------- /Whiteboarding/TwoSums/SOLUTION.js: -------------------------------------------------------------------------------- 1 | 2 | //Version 1 (Constant Time) 3 | const twoSums = (array, target) => { 4 | var obj = {} 5 | for(var i=0;i{ 17 | let A = 0 18 | let B; 19 | if(Array.isArray(array) && array.length > 0){ 20 | B = array.length-1 21 | }else{ 22 | B = 0 23 | } 24 | while(A !== B) 25 | if(array[A]+array[B] === target){ 26 | return [array[A],array[B]] 27 | } else if(array[A]+array[B] > target){ 28 | B -= 1 29 | } else if(array[A]+array[B] < target){ 30 | A += 1 31 | } 32 | return false 33 | } 34 | -------------------------------------------------------------------------------- /Whiteboarding/Validate_BST/README.md: -------------------------------------------------------------------------------- 1 | # Validate a Binary Search Tree 2 | ## Prompt 3 | 4 | Given a binary tree, determine if it is a valid binary search tree (BST). 5 | 6 | Assume a BST is defined as follows: 7 | 8 | - The left subtree of a node contains only nodes with keys less than the node's key. 9 | - The right subtree of a node contains only nodes with keys greater than the node's key. 10 | - Both the left and right subtrees must also be binary search trees. 11 | 12 | What is the time complexity of your solution? 13 | 14 | 15 | Examples to give 16 | ``` 17 | 1.) 18 | 19 | Input: 20 | 2 21 | / \ 22 | 1 3 23 | 24 | Output: true 25 | 26 | 2.) 27 | 28 | Input: 29 | 5 30 | / \ 31 | 1 4 32 | / \ 33 | 3 6 34 | 35 | Output: false 36 | 37 | Explanation: The input is: [5,1,4,null,null,3,6]. The root node's value 38 | is 5 but its right child's value is 4. 39 | 40 | ``` -------------------------------------------------------------------------------- /Whiteboarding/Validate_BST/SOLUTION.js: -------------------------------------------------------------------------------- 1 | const isValidBST = function(root) { 2 | if(!root){ 3 | return true 4 | } 5 | let compare; 6 | let flag = true 7 | const inOrderTrav = (node) => { 8 | if(node.left){ 9 | inOrderTrav(node.left) 10 | } 11 | if(compare !== undefined){ 12 | if(compare < node.val){ 13 | compare = node.val 14 | } else{ 15 | flag = false 16 | compare = Infinity 17 | } 18 | }else{ 19 | compare = node.val 20 | } 21 | if(node.right){ 22 | inOrderTrav(node.right) 23 | } 24 | } 25 | inOrderTrav(root) 26 | return flag 27 | 28 | }; -------------------------------------------------------------------------------- /Whiteboarding/kClosest/README.md: -------------------------------------------------------------------------------- 1 | # K-Closest Points 2 | ## The problem 3 | Given an array of X-Y coordinate points and an integer K, determine the K-closest points to the origin (0, 0). The order in which you return the points does not matter. K will be less than or equal to the length of the array. You may not use Array.sort() - your solution should run in O(n) time where n is the length of the array. 4 | ### Examples 5 | - kClosest([[0, 1], [1, 0], [1, 1]], 2) // returns [[0, 1], [1, 0]] 6 | - kClosest([[5, 5], [10, 1], [-1, -2], [3, 3]], 3) // returns [[-1, -2], [3, 3], [5, 5]] -------------------------------------------------------------------------------- /Whiteboarding/longestSubString/README.md: -------------------------------------------------------------------------------- 1 | # Longest Sub-string 2 | ## Prompt 3 | 4 | Given a string, find the length of the longest substring without repeating characters. 5 | 6 | Examples: 7 | ``` 8 | Input: "abcabcbb" 9 | Output: 3 10 | Explanation: The answer is "abc", with the length of 3. 11 | 12 | Input: "bbbbb" 13 | Output: 1 14 | Explanation: The answer is "b", with the length of 1. 15 | 16 | Input: "pwwkew" 17 | Output: 3 18 | Explanation: The answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring. 19 | 20 | ``` -------------------------------------------------------------------------------- /Whiteboarding/longestSubString/solution.js: -------------------------------------------------------------------------------- 1 | var lengthOfLongestSubstring = function(s) { 2 | let temp = "" 3 | let count = 0; 4 | let cache = {}; 5 | let pointer = 0 6 | for(var i=0;i= pointer){ 8 | i-pointer > count ? count = i-pointer : null 9 | pointer = cache[s[i]]+1 10 | cache[s[i]] = i 11 | } else{ 12 | cache[s[i]] = i 13 | } 14 | } 15 | return Math.max(s.length-pointer, count) 16 | }; 17 | 18 | /* 19 | 20 | Time Complexity: O(N) 21 | Space Complexity: O(N) 22 | 23 | */ -------------------------------------------------------------------------------- /Whiteboarding/roombaCircles/README.md: -------------------------------------------------------------------------------- 1 | # Roomba Circles 2 | 3 | ## The Scenario 4 | Imagine a roomba that is vacuuming an infinitely-sized, two-dimensional room (i.e., the x-y coordinate plane). The roomba is initially sitting at position (0, 0). The roomba is given a set of instructions in the form of a string made up of three letters: 5 | 6 | 1. 'R' - turn 90 degrees to the right 7 | 2. 'L' - turn 90 degrees to the left 8 | 3. 'G' - move forward 1 unit 9 | 10 | The roomba executes the instructions character-by-character, and once it reaches the end of the string, it starts again from the beginning of the string, repeating itself ad infinitum. 11 | ## The Problem 12 | Write a function which takes in a string composed of 'R's, 'L's, and 'G's. Your function should return true if the roomba is moving in a circle, and false otherwise. A circle in this case means that, during its infinite execution of the given instructions, the roomba always returns to its initial position. 13 | 14 | ### Examples 15 | 16 | - roombaCircles('GGR') // returns True 17 | - roombaCircles('GLL') // returns True 18 | - roombaCircles('GRGL') // returns False 19 | --------------------------------------------------------------------------------