├── .gitignore ├── Fall2015 ├── README.md ├── interviewsolutions.md └── upl-interview-prep-fall-2015.pdf ├── LICENSE ├── README.md └── Spring2016 ├── README.md └── questions ├── q01 ├── Solution.c └── Solution.java ├── q02 ├── Solution.java ├── abb1.c └── is_abbr.py ├── q03 ├── FindAllAbbreviations.hs └── FindAllAbbreviations.py ├── q04 ├── Solution.hs ├── q04.go ├── q04_test.go └── q4.py ├── q08 └── Solution.java ├── q15 ├── MySet.java └── Q15.js ├── q18 ├── Solution.java └── look_and_say.py ├── q19 ├── Solution.java └── pairy-time.py ├── questions.pdf └── questions.tex /.gitignore: -------------------------------------------------------------------------------- 1 | *.out 2 | *.class 3 | -------------------------------------------------------------------------------- /Fall2015/README.md: -------------------------------------------------------------------------------- 1 | # Interview Prep - Fall 2015 2 | 3 | Questions and solutions for the interview prep from 10/1/15. 4 | 5 | Feel free to use these questions as practice, and **send us a pull request** if you have a solution! 6 | 7 | 8 | ## Questions 9 | 10 | [UPL Interview Prep in PDF Form](upl-interview-prep-fall-2015.pdf) 11 | 12 | 13 | ## Solutions 14 | 15 | [Our solutions](interviewsolutions.md) 16 | 17 | 18 | HackerRank environments for problems: 19 | 20 | 1. No hackerrank solution. 21 | 2. No hackerrank solution. 22 | 3. https://www.hackerrank.com/challenges/detect-whether-a-linked-list-contains-a-cycle 23 | 4. https://www.hackerrank.com/challenges/tree-inorder-traversal 24 | 5. https://www.hackerrank.com/challenges/merge-two-sorted-linked-lists 25 | 6. https://www.hackerrank.com/challenges/print-the-elements-of-a-linked-list-in-reverse 26 | 7. https://www.hackerrank.com/challenges/gem-stones 27 | 8. No hackerrank solution. 28 | 29 | 30 | Note: This was turned into a repository posthumously. Original may or may not still be [here](http://pages.cs.wisc.edu/~riccardo/interviewprep.html) 31 | -------------------------------------------------------------------------------- /Fall2015/interviewsolutions.md: -------------------------------------------------------------------------------- 1 | Solutions (Pseudocode): 2 | ``` 3 | 1. void FizzBuzz(int n){ 4 | for(int i = 0; i < n; i++){ 5 | if(i % 3 == 0) 6 | print "Fizz" 7 | if(i % 5 == 0) 8 | print "Buzz" 9 | print "\n" 10 | } 11 | 12 | 2: Returns true when n is a power of two 13 | 3: C++ Solution int HasCycle(Node* head) 14 | { 15 | Node *n1 = head; 16 | Node *n2 = head; 17 | //make sure neither are null, or we don't have a cycle 18 | while(n1 && n2){ 19 | //2 iterators for the list 20 | n1 = n1->next; 21 | n2 = n2->next; 22 | if(!n2) 23 | return 0; 24 | else 25 | n2 = n2->next; //n2 goes "twice as fast" as n1 26 | //this is how we know there is a cycle 27 | if(n1 == n2) 28 | return 1; 29 | } 30 | return 0; 31 | } 32 | 33 | 4: C++ Solution: 34 | 35 | void Inorder(node *root) { 36 | if(!root) { return; } 37 | Inorder(root->left); 38 | std::cout << root->data << " "; 39 | Inorder(root->right); 40 | } 41 | 42 | 43 | 5: Java Solution: 44 | Node MergeLists(Node list1, Node list2) { 45 | if (list1 == null) return list2; 46 | if (list2 == null) return list1; 47 | if (list1.data < list2.data) { 48 | list1.next = MergeLists(list1.next, list2); 49 | return list1; 50 | } else { 51 | list2.next = MergeLists(list2.next, list1); 52 | return list2; 53 | } } 54 | 55 | 6: C++ Solution 56 | void ReversePrint(Node *head) 57 | { 58 | if(head->next) 59 | ReversePrint(head->next); 60 | std::cout << head->data << std::endl; 61 | } 62 | 63 | 7: Python solution def find_intersection(values): 64 | all_uniques = [] 65 | for value in values: 66 | all_uniques.append(set([l for l in value])) 67 | return len(reduce(lambda x, y: x & y all_uniques)) 68 | 69 | 70 | 8: Solution TBD 71 | ``` 72 | -------------------------------------------------------------------------------- /Fall2015/upl-interview-prep-fall-2015.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UW-UPL/UPLInterviewPrep/689dfc090f13b37d84438880dd06e07cc73af559/Fall2015/upl-interview-prep-fall-2015.pdf -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UPL Interview Prep 2 | 3 | Collection of resources brought to you by the [UPL](http://upl.cs.wisc.edu) to help prepare you for interviews! 4 | 5 | We **encourage you** to do these problems and submit pull requests for good answers! 6 | 7 | Other talks and events from the UPL are [here](https://github.com/UW-UPL/Talks). 8 | 9 | 10 | ## Events 11 | 12 | We've done numerous interview prep events with the UPL. You can find those questions and solutions here: 13 | 14 | * [Spring 2016](Spring2016/) 15 | * [Fall 2015](Fall2015/) 16 | 17 | 18 | ## Building your own suite of questions 19 | 20 | If you wish to build your own suite of questions, you can follow these instructions using a .tex file from one of the question repositories. 21 | 22 | Simply putting the .tex file into an http://overleaf.com project and then saving as a PDF works well. Otherwise, install your favorite LaTeX distribution and do the same thing locally. Sometimes, in Unix, the `pdflatex` command is available. You can run `pdflatex questions.tex` to generate the PDF as well. 23 | 24 | 31 | -------------------------------------------------------------------------------- /Spring2016/README.md: -------------------------------------------------------------------------------- 1 | # Interview Prep - Spring 2016 2 | 3 | Questions and solutions for the interview prep from 1/28/16 4 | 5 | Feel free to use these questions as practice, and **send us a pull request** if you have a solution! 6 | 7 | 8 | ## Questions 9 | 10 | The questions can be found here: [.pdf](questions/questions.pdf) and [.tex](questions/questions.tex) 11 | 12 | 13 | ## Solutions 14 | 15 | All solutions can be found in the [questions](questions/) folder. 16 | 17 | Individual Solutions: 18 | 19 | * [Question 1](questions/q01/) 20 | * [Question 2](questions/q02/) 21 | * [Question 3](questions/q03/) 22 | * [Question 4](questions/q04/) 23 | * [Question 8](questions/q08/) 24 | * [Question 15](questions/q15/) 25 | * [Question 18](questions/q18/) 26 | * [Question 19](questions/q19/) 27 | 28 | 29 | ## Building your own suite of questions 30 | Simply putting the .tex file into an http://overleaf.com project and then saving as a PDF works well. Otherwise, install your favorite LaTeX distribution and do the same thing locally. Sometimes, in Unix, the `pdflatex` command is available. You can run `pdflatex questions.tex` to generate the PDF as well. 31 | 32 | 39 | -------------------------------------------------------------------------------- /Spring2016/questions/q01/Solution.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int firstOccurrence(int *nums, int length, int k) { 4 | int first = 0; 5 | int last = length - 1; 6 | while (first < last) { 7 | int med = first + (last - first) / 2; 8 | if (nums[med] < k) 9 | first = med + 1; 10 | else if (nums[med] > k) 11 | last = med - 1; 12 | else 13 | last = med; 14 | } 15 | if (nums[first] == k) return first; 16 | else return -1; 17 | } 18 | 19 | int main(int argc, char** argv) { 20 | int nums[] = { 1, 1, 1, 2, 2, 2, 2, 3, 4, 5, 6, 7, 8, 8, 10, 10, 11, 12, 16 }; 21 | int length = sizeof(nums) / sizeof(int); 22 | int i, k; 23 | printf("%s", "Array ["); 24 | for (i = 0; i < length; i++) { 25 | printf("%d%s", nums[i], i != length - 1 ? ", " : "]\n"); 26 | } 27 | for (k = 0; k < 20; k++) { 28 | printf("%d found at %d\n", k, firstOccurrence(nums, length, k)); 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Spring2016/questions/q01/Solution.java: -------------------------------------------------------------------------------- 1 | public class Solution { 2 | public static int firstOccurrence(int[] nums, int k) { 3 | int first = 0; 4 | int last = nums.length - 1; 5 | while (first < last) { 6 | int med = first + (last - first) / 2; 7 | if (nums[med] < k) { 8 | first = med + 1; 9 | } else if (nums[med] > k) { 10 | last = med - 1; 11 | } else { 12 | last = med; 13 | } 14 | } 15 | if (nums[first] == k) return first; 16 | else return -1; 17 | } 18 | 19 | public static void main(String[] args) { 20 | int[] nums = { 1, 1, 1, 2, 2, 2, 2, 3, 4, 5, 6, 7, 8, 8, 10, 10, 11, 12, 16 }; 21 | System.out.print("Array: ["); 22 | for (int i = 0; i < nums.length; i++) { 23 | System.out.print(nums[i]); 24 | if (i != nums.length - 1) System.out.print(", "); 25 | } 26 | System.out.println("]"); 27 | for (int k = 0; k < 20; k++) { 28 | int first = firstOccurrence(nums, k); 29 | System.out.println(k + " first found at index " + first); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Spring2016/questions/q02/Solution.java: -------------------------------------------------------------------------------- 1 | public class Solution { 2 | public static boolean isAbbr(String name, String abbr) { 3 | int namePos = 0; 4 | int abbrPos = 0; 5 | while (namePos < name.length() && abbrPos < abbr.length()) { 6 | if (Character.isDigit(abbr.charAt(abbrPos))) { 7 | int digitEnd = abbrPos; 8 | while (Character.isDigit(abbr.charAt(digitEnd))) { 9 | digitEnd++; 10 | } 11 | int abbrNum = Integer.parseInt(abbr.substring(abbrPos, digitEnd)); 12 | namePos += abbrNum; 13 | abbrPos = digitEnd; 14 | } else { 15 | if (name.charAt(namePos) != abbr.charAt(abbrPos)) { 16 | return false; 17 | } 18 | namePos++; 19 | abbrPos++; 20 | } 21 | } 22 | return namePos == name.length() && abbrPos == abbr.length(); 23 | } 24 | 25 | public static void main(String[] args) { 26 | System.out.println(isAbbr("LOCALIZATION", "L10N")); 27 | System.out.println(isAbbr("LOCALIZATION", "6Z4N")); 28 | System.out.println(isAbbr("LOCALIZATION", "L9N")); 29 | System.out.println(isAbbr("LOCALIZATION", "L10Q")); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Spring2016/questions/q02/abb1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static int __log10(int num) { 6 | int res = 0; 7 | for(;num > 0;res++) 8 | num /= 10; 9 | return res; 10 | } 11 | static int isAbbr(char* name, char* abbr) { 12 | int name_len = strlen(name); 13 | int abbr_len = strlen(abbr); 14 | int name_pos = 0; 15 | int abbr_pos = 0; 16 | while(name_pos < name_len && abbr_pos < abbr_len && 17 | abbr[abbr_pos] != 0 && name[name_pos] != 0) 18 | { 19 | if(abbr[abbr_pos] >= '0' && abbr[abbr_pos] <= '9') 20 | { 21 | int abbr_num = atoi(abbr + abbr_pos); 22 | abbr_pos += __log10(abbr_num); 23 | name_pos += abbr_num; 24 | } else { 25 | if(abbr[abbr_pos] != name[name_pos]) 26 | return 0; 27 | name_pos++; 28 | abbr_pos++; 29 | } 30 | } 31 | if (name_pos > name_len) return 0; 32 | if(abbr[abbr_pos] == name[name_pos] && abbr[abbr_pos] == 0) 33 | return 1; 34 | return 0; 35 | } 36 | int main(int argc, char** argv) { 37 | printf("1: %s\n", isAbbr("LOCALIZATION", "L10N") ? "TRUE" : "FALSE"); 38 | printf("1: %s\n", isAbbr("LOCALIZATION", "6Z4N") ? "TRUE" : "FALSE"); 39 | printf("2: %s\n", isAbbr("LOCALIZATION", "L9N") ? "TRUE" : "FALSE"); 40 | printf("3: %s\n", isAbbr("LOCALIZATION", "L10Q") ? "TRUE" : "FALSE"); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /Spring2016/questions/q02/is_abbr.py: -------------------------------------------------------------------------------- 1 | def takeWhile(pred, lst): 2 | res = [] 3 | for elem in lst: 4 | if pred(elem): 5 | res.append(elem) 6 | else: 7 | break 8 | return res 9 | 10 | def isAbbrRec(orig, test): 11 | if not orig and not test: 12 | return True 13 | elif (not orig) != (not test): 14 | return False 15 | elif orig[0] == test[0]: 16 | return isAbbrRec(orig[1:], test[1:]) 17 | elif orig[0] != test[0] and test[0].isdigit(): 18 | numeric_prefix = takeWhile(lambda c: c.isdigit(), test) 19 | prefix_len = len(numeric_prefix) 20 | num = int(''.join(numeric_prefix)) 21 | return isAbbrRec(orig[num:], test[prefix_len:]) 22 | else: 23 | return False 24 | 25 | def isAbbr(orig, test): 26 | return isAbbrRec(orig, test) 27 | 28 | if __name__ == '__main__': 29 | test_data = [ 30 | ('LOCALIZATION', 'L10N'), # True 31 | ('LOCALIZATION', '6Z4N'), # True 32 | ('LOCALIZATION', 'L9N' ), # False 33 | ('LOCALIZATION', 'L10Q'), # False 34 | ('LOCALIZATION', '12' ), # True 35 | ('LOCALIZATION', '11' ) # False 36 | ] 37 | 38 | for (orig, test) in test_data: 39 | print(isAbbr(orig, test)) 40 | -------------------------------------------------------------------------------- /Spring2016/questions/q03/FindAllAbbreviations.hs: -------------------------------------------------------------------------------- 1 | -- An algorithm to find all possible abbreviations of a word 2 | -- e.g. "the" -> ["the", "3", "t1e", "2e", "1h1", ...] 3 | -- c + c, c + n, n + c, n + n 4 | -- assumes argument string does not contain numerics 5 | 6 | -- Note: this problem is similar to the power set problem 7 | 8 | import Data.List (intercalate, sort) 9 | 10 | isNumeric :: Char -> Bool 11 | isNumeric c = c `elem` ['0'..'9'] 12 | 13 | appendAbbr :: Char -> String -> [String] -> [String] 14 | -- takes a character, a string, and a list of previous results 15 | appendAbbr c str acc = 16 | -- take the numeric prefix (if it exists) 17 | -- e.g. "123xyz4" => ("123", "xyz4") 18 | let (prefix, suffix) = span (isNumeric) str 19 | -- parse prefix into an integer 20 | num = read prefix :: Integer 21 | -- increment it and convert back to a string 22 | incrementedPrefix = show (1 + num) 23 | -- create new solution strings... 24 | additions = if (null prefix) 25 | -- [char + char, num + char] 26 | then [c:str, '1':str] 27 | -- char + num, num + num 28 | else [c:str, incrementedPrefix ++ suffix] 29 | -- return the new solutions appended to the previous results 30 | in acc ++ additions 31 | 32 | findAllAbbreviations :: String -> [String] 33 | findAllAbbreviations [singleChar] = [[singleChar], ['1']] 34 | findAllAbbreviations (c:cs) = 35 | -- take off the first char (`c`); the rest of the string is `cs` 36 | let subresults = findAllAbbreviations cs 37 | -- foldr is "reduce" in other languages 38 | in foldr (appendAbbr c) [] subresults 39 | 40 | main = do 41 | let abbrs = findAllAbbreviations "wisconsin" 42 | -- get pretty output 43 | output = intercalate "\n" $ sort abbrs 44 | putStrLn output 45 | return () 46 | -------------------------------------------------------------------------------- /Spring2016/questions/q03/FindAllAbbreviations.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | def prependAbbrev(front, abbr): 4 | if type(front) is type(abbr[0]): 5 | return [front + abbr[0]] + abbr[1:] 6 | else: 7 | return [front] + abbr 8 | 9 | def prefixAll(p, lst): 10 | return [prependAbbrev(p, l) for l in lst] 11 | 12 | def findAllAbbrev(s): 13 | if len(s) == 1: 14 | return [[s], [1]] 15 | else: 16 | rest = findAllAbbrev(s[1:]) 17 | return prefixAll(s[0], rest) + prefixAll(1, rest) 18 | 19 | if __name__ == '__main__': 20 | if len(sys.argv) == 1: 21 | print ' '.join(['usage:', sys.argv[0], '']) 22 | else: 23 | for s in findAllAbbrev(sys.argv[1]): 24 | print ''.join([str(i) for i in s]) 25 | -------------------------------------------------------------------------------- /Spring2016/questions/q04/Solution.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Control.Monad 4 | import Data.List 5 | import qualified Data.Set as S 6 | 7 | import Test.Hspec 8 | import Test.QuickCheck 9 | 10 | data Tree a = Leaf | Node (Tree a) a (Tree a) deriving (Eq, Show) 11 | 12 | -- This incantation generates random binary trees. It is necessary 13 | -- for the QuickCheck testing we will be doing 14 | 15 | genTree :: Arbitrary a => Gen (Tree a) 16 | genTree = frequency [ (1, return Leaf) 17 | , (2, liftM3 Node arbitrary arbitrary arbitrary) 18 | ] 19 | 20 | instance Arbitrary a => Arbitrary (Tree a) where 21 | arbitrary = genTree 22 | 23 | val :: Tree a -> Maybe a 24 | val Leaf = Nothing 25 | val (Node _ a _) = Just a 26 | 27 | children :: Tree a -> [a] 28 | children (Node (Node _ l _) _ Leaf) = [l] 29 | children (Node Leaf _ (Node _ r _)) = [r] 30 | children (Node (Node _ l _) _ (Node _ r _)) = [l, r] 31 | children _ = [] 32 | 33 | grandChildren :: Tree a -> [a] 34 | grandChildren Leaf = [] 35 | grandChildren (Node l _ r) = (children l) ++ (children r) 36 | 37 | anyEqual :: Ord a => [a] -> Bool 38 | anyEqual l = S.size (S.fromList l) /= length l 39 | 40 | anyGrandchildrenEqual :: Ord a => Tree a -> Bool 41 | anyGrandchildrenEqual Leaf = False 42 | anyGrandchildrenEqual t@(Node l _ r) = (anyEqual (grandChildren t)) || anyGrandchildrenEqual l || anyGrandchildrenEqual r 43 | 44 | -- properties of the functions above that should be true for all inputs 45 | 46 | prop_upToTwoChildren :: Tree a -> Bool 47 | prop_upToTwoChildren t = length (children t) <= 2 48 | 49 | prop_upToFourGrandchildren :: Tree a -> Bool 50 | prop_upToFourGrandchildren t = length (grandChildren t) <= 4 51 | 52 | prop_childrensChildrenAreGrandchildren :: Eq a => Tree a -> Tree a -> Bool 53 | prop_childrensChildrenAreGrandchildren t t' = 54 | all id $ map (\n -> elem n gc) (children t ++ children t') 55 | where gc = grandChildren (Node t undefined t') 56 | 57 | prop_anyGrandchildrenMeansAnyRoot :: Ord a => Tree a -> Bool 58 | prop_anyGrandchildrenMeansAnyRoot t = 59 | gc == (anyGrandchildrenEqual (Node t undefined Leaf)) && gc == (anyGrandchildrenEqual (Node Leaf undefined t)) 60 | where gc = anyGrandchildrenEqual t 61 | 62 | prop_noneEqualInUniq :: Ord a => [a] -> Bool 63 | prop_noneEqualInUniq l = not $ anyEqual (S.toList (S.fromList l)) 64 | 65 | prop_selfConcatEqual :: Ord a => [a] -> Bool 66 | prop_selfConcatEqual [] = True 67 | prop_selfConcatEqual l = anyEqual (l ++ l) 68 | 69 | prop_allEqualAnyOrder :: Ord a => [a] -> Bool 70 | prop_allEqualAnyOrder l = all (\l' -> anyEqual l' == ans) (permutations front) 71 | where front = take 5 l 72 | ans = anyEqual front 73 | 74 | -- the main function that tests all of the properties on 100 random inputs 75 | 76 | type PropStringTree = Tree String -> Bool 77 | type PropStringList = [String] -> Bool 78 | 79 | exampleTree1 :: Tree Char 80 | exampleTree1 = 81 | Node 82 | (Node (Node Leaf 'c' (Node Leaf 'e' Leaf)) 'b' (Node Leaf 'd' Leaf)) 83 | 'a' 84 | (Node Leaf 'f' (Node (Node Leaf 'h' Leaf) 'g' Leaf)) 85 | 86 | exampleTree2 :: Tree Char 87 | exampleTree2 = 88 | Node 89 | (Node (Node (Node Leaf 'd' Leaf) 'c' Leaf) 'b' (Node Leaf 'h' (Node Leaf 'd' Leaf))) 90 | 'a' 91 | (Node (Node (Node Leaf 'g' Leaf) 'f' (Node Leaf 'd' Leaf)) 'a' Leaf) 92 | 93 | main :: IO () 94 | main = hspec $ do 95 | describe "Binary trees" $ do 96 | it "should only have up to 2 children" $ do 97 | property $ (prop_upToTwoChildren :: PropStringTree) 98 | it "should only have up to 4 grandchildren" $ do 99 | property $ (prop_upToFourGrandchildren :: PropStringTree) 100 | it "should include all children's children as grandchildren" $ do 101 | property $ (prop_childrensChildrenAreGrandchildren :: Tree String -> Tree String -> Bool) 102 | describe "anyGrandchildrenEqual" $ do 103 | it "should check subtrees" $ do 104 | property $ (prop_anyGrandchildrenMeansAnyRoot :: PropStringTree) 105 | it "should get the correct answers" $ do 106 | anyGrandchildrenEqual exampleTree1 `shouldBe` False 107 | anyGrandchildrenEqual exampleTree2 `shouldBe` True 108 | describe "anyEqual" $ do 109 | it "should be False for a list with no duplicates" $ do 110 | property $ (prop_noneEqualInUniq :: PropStringList) 111 | it "should be True for any list concatenated with itself" $ do 112 | property $ (prop_selfConcatEqual :: PropStringList) 113 | it "should always give the same answer for all orderings of a list" $ do 114 | property $ (prop_allEqualAnyOrder :: PropStringList) 115 | -------------------------------------------------------------------------------- /Spring2016/questions/q04/q04.go: -------------------------------------------------------------------------------- 1 | package q04 2 | 3 | // Run the code online here: https://play.golang.org/. 4 | // Or, run `go test` (see q04_test.go). 5 | 6 | // Node contains a child nodes and data. 7 | type Node struct { 8 | Left *Node 9 | Right *Node 10 | Value rune 11 | } 12 | 13 | func (node *Node) getGrandchildren() []*Node { 14 | // Since we have a binary tree, we should have at most 4 grandchildren. 15 | ret := make([]*Node, 4) 16 | 17 | if node.Left != nil { 18 | if node.Left.Left != nil { 19 | ret = append(ret, node.Left.Left) 20 | } 21 | 22 | if node.Left.Right != nil { 23 | ret = append(ret, node.Left.Right) 24 | } 25 | } 26 | 27 | if node.Right != nil { 28 | if node.Right.Left != nil { 29 | ret = append(ret, node.Right.Left) 30 | } 31 | 32 | if node.Right.Right != nil { 33 | ret = append(ret, node.Right.Right) 34 | } 35 | } 36 | 37 | return ret 38 | } 39 | 40 | func (node *Node) anyGrandchildrenEqual() bool { 41 | grandchildren := node.getGrandchildren() 42 | 43 | dict := make(map[rune]bool) 44 | 45 | for _, gchild := range grandchildren { 46 | if gchild == nil { 47 | continue 48 | } 49 | 50 | key := gchild.Value 51 | 52 | if _, hasKey := dict[key]; hasKey { 53 | return true 54 | } 55 | 56 | dict[key] = true 57 | } 58 | 59 | if node.Left != nil { 60 | leftEq := node.Left.anyGrandchildrenEqual() 61 | if leftEq { 62 | return true 63 | } 64 | } 65 | 66 | if node.Right != nil { 67 | rightEq := node.Right.anyGrandchildrenEqual() 68 | if rightEq { 69 | return true 70 | } 71 | } 72 | 73 | return false 74 | } 75 | 76 | // Tree is a tree containing Nodes, all descending from a root Node. 77 | type Tree struct { 78 | Root Node 79 | } 80 | 81 | // AnyGrandchildrenEqual returns true iff any two grandchildren are equal at 82 | // any equal level in the tree. 83 | func (tree *Tree) AnyGrandchildrenEqual() bool { 84 | return tree.Root.anyGrandchildrenEqual() 85 | } 86 | -------------------------------------------------------------------------------- /Spring2016/questions/q04/q04_test.go: -------------------------------------------------------------------------------- 1 | package q04 2 | 3 | import "testing" 4 | 5 | func TestTreeAnyGrandchildrenEqual(t *testing.T) { 6 | for _, tc := range []struct { 7 | name string 8 | tree Tree 9 | wantResult bool 10 | }{{ 11 | name: "when nothing is equal in the tree", 12 | tree: Tree{ 13 | Root: Node{ 14 | Value: 'a', 15 | Left: &Node{ 16 | Value: 'b', 17 | Left: &Node{ 18 | Value: 'c', 19 | Right: &Node{ 20 | Value: 'e', 21 | }, 22 | }, 23 | Right: &Node{ 24 | Value: 'd', 25 | }, 26 | }, 27 | Right: &Node{ 28 | Value: 'f', 29 | Right: &Node{ 30 | Value: 'g', 31 | Left: &Node{ 32 | Value: 'h', 33 | }, 34 | }, 35 | }, 36 | }, 37 | }, 38 | wantResult: false, 39 | }, { 40 | name: "when only siblings are equal", 41 | tree: Tree{ 42 | Root: Node{ 43 | Value: 'a', 44 | Left: &Node{Value: 'z'}, 45 | Right: &Node{Value: 'z'}, 46 | }, 47 | }, 48 | wantResult: false, 49 | }, { 50 | name: "when grandchildren are equal", 51 | tree: Tree{ 52 | Root: Node{ 53 | Value: 'a', 54 | Left: &Node{ 55 | Value: 'b', 56 | Left: &Node{ 57 | Value: 'c', 58 | Left: &Node{ 59 | Value: 'd', // match 60 | }, 61 | }, 62 | Right: &Node{ 63 | Value: 'h', 64 | Right: &Node{ 65 | Value: 'd', // match 66 | }, 67 | }, 68 | }, 69 | Right: &Node{ 70 | Value: 'a', 71 | Left: &Node{ 72 | Value: 'f', 73 | Left: &Node{ 74 | Value: 'g', 75 | }, 76 | Right: &Node{ 77 | Value: 'd', 78 | }, 79 | }, 80 | }, 81 | }, 82 | }, 83 | wantResult: true, 84 | }} { 85 | t.Run(tc.name, func(t *testing.T) { 86 | if tc.tree.AnyGrandchildrenEqual() != tc.wantResult { 87 | t.Errorf("AnyGrandchildren was not %v", tc.wantResult) 88 | } 89 | }) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Spring2016/questions/q04/q4.py: -------------------------------------------------------------------------------- 1 | ''' 2 | The tree implementation is undefined. This is something you should ask about 3 | when given a plain `tree` question. It could be a: 4 | - binary tree (Left and Right children) 5 | - binary search tree (Left and Right children w/ some ordering) 6 | - `list tree` (children stored in a list) 7 | - red/black tree (painful...) 8 | - or something else! 9 | ''' 10 | 11 | class TreeNode: 12 | def __init__(self, data = None, *children): 13 | self.data = data 14 | self.children = children 15 | 16 | def is_leaf(self): 17 | return len(self.children) == 0 18 | 19 | # as required by the answer 20 | def grandchildren(self): 21 | if self.is_leaf(): 22 | return [] 23 | else: 24 | ret = [] 25 | 26 | for child in self.children: 27 | for gchild in child.children: 28 | ret.append(gchild) 29 | 30 | return ret 31 | 32 | def any_grandchildren_equal(self): 33 | if self.is_leaf(): 34 | # no grandchildren! 35 | return False 36 | else: 37 | data_list = map(lambda node: node.data, self.grandchildren()) 38 | data_set = set(data_list) 39 | 40 | # there will be duplicates if the list size != set size 41 | # because a set removes duplicates 42 | diff_exists = len(data_list) != len(data_set) 43 | 44 | if diff_exists: 45 | return True 46 | else: 47 | return any(map(lambda child: child.any_grandchildren_equal(), 48 | self.children)) 49 | 50 | class Tree: 51 | def __init__(self, root): 52 | self.root = root 53 | 54 | def any_grandchildren_equal(self): 55 | return self.root.any_grandchildren_equal() 56 | 57 | if __name__ == '__main__': 58 | tree1 = Tree(TreeNode('a', TreeNode('b', TreeNode('c'), TreeNode('d'), 59 | TreeNode('e')), TreeNode('f'), TreeNode('g', TreeNode('h')))) 60 | 61 | print('tree1: ' + str(tree1.any_grandchildren_equal()) + ' should be False') 62 | 63 | tree2 = Tree(TreeNode('a', TreeNode('b'), TreeNode('a'), TreeNode('c', 64 | TreeNode('d'), TreeNode('e')), TreeNode('f', TreeNode('d'), 65 | TreeNode('g')))) 66 | 67 | print('tree2: ' + str(tree2.any_grandchildren_equal()) + ' should be True') 68 | 69 | -------------------------------------------------------------------------------- /Spring2016/questions/q08/Solution.java: -------------------------------------------------------------------------------- 1 | public class Solution { 2 | // subarraySum fills out a 2-dimensional array, where 3 | // the value at index [i][j] is the sum of the elements 4 | // in nums from indices i to j (inclusive) 5 | public static int[][] subarraySum(int[] nums) { 6 | int[][] sums = new int[nums.length][nums.length]; 7 | 8 | // base case: i == j => nums[i] 9 | for (int i = 0; i < nums.length; i++) { 10 | sums[i][i] = nums[i]; 11 | } 12 | 13 | // general case: i < j 14 | // we fill out the array in order of ascending 15 | // difference j - i (set by the variable diff). 16 | for (int diff = 1; diff < nums.length; diff++) { 17 | for (int i = 0; i < nums.length - diff; i++) { 18 | int j = i + diff; 19 | // to sum elements i through j, look up the sum 20 | // for elements i through j-1 and add element j 21 | int sum = sums[i][j-1] + sums[j][j]; 22 | // if you know that i will always be less than j, 23 | // you only have to fill out one diagonal half of 24 | // the table 25 | sums[i][j] = sum; 26 | } 27 | } 28 | return sums; 29 | } 30 | 31 | // return the score of the _first_ player when both are playing 32 | // optimally. the second player's score can be found by subtracting 33 | // this from the total sum of elements 34 | public static int twoEnds(int[] nums) { 35 | int[][] sums = subarraySum(nums); 36 | // fill out a 2-dimensional array called opts (OPTimal valueS), 37 | // where opts[i][j] is the score of the first player if both 38 | // play optimally with the cards found between indices i and j 39 | int[][] opts = new int[nums.length][nums.length]; 40 | 41 | // base case: i == j => nums[i] 42 | for (int i = 0; i < nums.length; i++) { 43 | opts[i][i] = nums[i]; 44 | } 45 | 46 | // general case: i < j, filled out in order of ascending difference 47 | 48 | // the best that the first player can do is found by minimizing 49 | // the score of the second player. the second player will either 50 | // be playing with the cards from i+1 to j or from i to j-1. 51 | // to obtain the first player's score from this, subtract from 52 | // the sum of all the cards from i to j. 53 | 54 | // another way of looking at this: to find the first player's 55 | // score, take all the cards, remove all the cards that the 56 | // second player would take if they were playing optimally, and 57 | // sum the cards you have left 58 | for (int diff = 1; diff < nums.length; diff++) { 59 | for (int i = 0; i < nums.length - diff; i++) { 60 | int j = i + diff; 61 | opts[i][j] = sums[i][j] - Math.min(opts[i+1][j], opts[i][j-1]); 62 | } 63 | } 64 | // the answer is the value stored in opt[0][nums.length - 1] 65 | // because this contains every card 66 | return opts[0][nums.length - 1]; 67 | } 68 | 69 | public static void main(String[] args) { 70 | int[] nums = { 1, 3, 100, 2 }; 71 | int sum = 0; 72 | System.out.print("Nums: ["); 73 | for (int i = 0; i < nums.length; i++) { 74 | System.out.print(nums[i]); 75 | sum += nums[i]; 76 | if (i < nums.length - 1) System.out.print(", "); 77 | } 78 | System.out.println("]"); 79 | int firstPlayerScore = twoEnds(nums); 80 | System.out.println("First player score: " + firstPlayerScore); 81 | System.out.println("Second player score: " + (sum - firstPlayerScore)); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Spring2016/questions/q15/MySet.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Iterator; 3 | import java.util.List; 4 | import java.util.NoSuchElementException; 5 | import java.util.Comparator; 6 | 7 | public class MySet { 8 | public MyNode root; 9 | public Comparator cmp; 10 | public MySet(Comparator myCmp) { 11 | root = null; 12 | cmp = myCmp; 13 | } 14 | 15 | public void add(T data) { 16 | if (root == null) { 17 | root = new MyNode<>(data); 18 | } else { 19 | root.add(data, cmp); 20 | } 21 | } 22 | 23 | // The following set operations all return new MySet instances 24 | 25 | public MySet union(MySet otherSet) { 26 | MySet newSet = new MySet<>(cmp); 27 | Iterator myIt = iterator(); 28 | while (myIt.hasNext()) { 29 | newSet.add(myIt.next()); 30 | } 31 | 32 | Iterator otherIt = otherSet.iterator(); 33 | while (otherIt.hasNext()) { 34 | newSet.add(otherIt.next()); 35 | } 36 | 37 | return newSet; 38 | } 39 | 40 | public MySet intersection(MySet otherSet) { 41 | MySet newSet = new MySet<>(cmp); 42 | Iterator myIt = iterator(); 43 | Iterator otherIt = otherSet.iterator(); 44 | 45 | boolean myEmpty = !myIt.hasNext(); 46 | boolean otherEmpty = !otherIt.hasNext(); 47 | 48 | if (myEmpty || otherEmpty) { 49 | return newSet; 50 | } 51 | 52 | T myVal = myIt.next(); 53 | T otherVal = otherIt.next(); 54 | while (myIt.hasNext() && otherIt.hasNext()) { 55 | if (myVal == otherVal) { 56 | newSet.add(myVal); 57 | myVal = myIt.next(); 58 | otherVal = otherIt.next(); 59 | } else if (cmp.compare(myVal, otherVal) < 0) { 60 | while (cmp.compare(myVal, otherVal) < 0) { 61 | myVal = myIt.next(); 62 | } 63 | } else { 64 | while (cmp.compare(myVal, otherVal) > 0) { 65 | otherVal = otherIt.next(); 66 | } 67 | } 68 | } 69 | 70 | if (myVal == otherVal) { 71 | newSet.add(myVal); 72 | } 73 | 74 | return newSet; 75 | } 76 | 77 | public MySet difference(MySet otherSet) { 78 | MySet newSet = new MySet<>(cmp); 79 | Iterator myIt = iterator(); 80 | Iterator otherIt = otherSet.iterator(); 81 | 82 | boolean myEmpty = !myIt.hasNext(); 83 | boolean otherEmpty = !otherIt.hasNext(); 84 | 85 | if (myEmpty) { 86 | return newSet; 87 | } else if (otherEmpty) { 88 | while (myIt.hasNext()) { 89 | newSet.add(myIt.next()); 90 | } 91 | return newSet; 92 | } 93 | 94 | T myVal = myIt.next(); 95 | T otherVal = otherIt.next(); 96 | while (myIt.hasNext() && otherIt.hasNext()) { 97 | if (myVal.equals(otherVal)) { 98 | myVal = myIt.next(); 99 | otherVal = otherIt.next(); 100 | } else if (cmp.compare(myVal, otherVal) < 0) { 101 | while (cmp.compare(myVal, otherVal) < 0) { 102 | newSet.add(myVal); 103 | myVal = myIt.next(); 104 | } 105 | } else { 106 | while (cmp.compare(myVal, otherVal) > 0) { 107 | otherVal = otherIt.next(); 108 | } 109 | } 110 | } 111 | 112 | if (!myVal.equals(otherVal)) { 113 | newSet.add(myVal); 114 | } 115 | 116 | while (myIt.hasNext()) { 117 | newSet.add(myIt.next()); 118 | } 119 | 120 | return newSet; 121 | } 122 | 123 | public String toString() { 124 | StringBuilder sb = new StringBuilder(); 125 | sb.append("{ "); 126 | Iterator it = iterator(); 127 | while (it.hasNext()) { 128 | sb.append(it.next().toString()); 129 | sb.append(" "); 130 | } 131 | sb.append("}"); 132 | return sb.toString(); 133 | } 134 | 135 | public Iterator iterator() { 136 | return new MyIterator<>(root); 137 | } 138 | 139 | // private classes 140 | 141 | private class MyNode { 142 | public T1 data; 143 | public MyNode left; 144 | public MyNode right; 145 | 146 | public MyNode(T1 myData) { 147 | data = myData; 148 | left = null; 149 | right = null; 150 | } 151 | 152 | public void add(T1 newData, Comparator cmp) { 153 | int c = cmp.compare(data, newData); 154 | if (c > 0) { 155 | if (left == null) { 156 | left = new MyNode<>(newData); 157 | } else { 158 | left.add(newData, cmp); 159 | } 160 | } else if (c < 0) { 161 | if (right == null) { 162 | right = new MyNode<>(newData); 163 | } else { 164 | right.add(newData, cmp); 165 | } 166 | } 167 | } 168 | } 169 | 170 | // define an in-order iterator over the set 171 | private class MyIterator implements Iterator { 172 | private List> stack; 173 | private MyNode current; 174 | 175 | private MyIterator(MyNode root) { 176 | stack = new ArrayList<>(); 177 | if (root != null) { 178 | stack.add(root); 179 | while (root.left != null) { 180 | root = root.left; 181 | stack.add(0, root); 182 | } 183 | } 184 | current = null; 185 | } 186 | 187 | public boolean hasNext() { 188 | return stack.size() > 0 || current != null; 189 | } 190 | 191 | public T2 next() { 192 | while (stack.size() > 0 || current != null) { 193 | if (current != null) { 194 | stack.add(0, current); 195 | current = current.left; 196 | } else { 197 | current = stack.get(0); 198 | stack.remove(0); 199 | MyNode retVal = current; 200 | current = current.right; 201 | return retVal.data; 202 | } 203 | } 204 | throw new NoSuchElementException(); 205 | } 206 | } 207 | 208 | private static class IntComparator implements Comparator { 209 | public int compare(Integer i1, Integer i2) { 210 | return i1.compareTo(i2); 211 | } 212 | } 213 | 214 | private static class StringComparator implements Comparator { 215 | public int compare(String s1, String s2) { 216 | return s1.compareTo(s2); 217 | } 218 | } 219 | 220 | public static void testIntSet() { 221 | IntComparator cmp = new IntComparator(); 222 | MySet a = new MySet<>(cmp); 223 | a.add(1); 224 | a.add(2); 225 | a.add(3); 226 | System.out.println("Set A: " + a.toString()); 227 | 228 | MySet b = new MySet<>(cmp); 229 | b.add(2); 230 | b.add(3); 231 | System.out.println("Set B: " + b.toString()); 232 | 233 | System.out.println("Union: " + a.union(b).toString()); 234 | 235 | System.out.println("Intersection: " + a.intersection(b).toString()); 236 | 237 | System.out.println("Difference (A - B): " + a.difference(b).toString()); 238 | System.out.println("Difference (B - A): " + b.difference(a).toString()); 239 | } 240 | 241 | public static void testStringSet() { 242 | StringComparator cmp = new StringComparator(); 243 | MySet a = new MySet<>(cmp); 244 | a.add("One"); 245 | a.add("Two"); 246 | a.add("Three"); 247 | System.out.println("Set A: " + a.toString()); 248 | 249 | MySet b = new MySet<>(cmp); 250 | b.add("Two"); 251 | b.add("Three"); 252 | System.out.println("Set B: " + b.toString()); 253 | 254 | System.out.println("Union: " + a.union(b).toString()); 255 | 256 | System.out.println("Intersection: " + a.intersection(b).toString()); 257 | 258 | System.out.println("Difference (A - B): " + a.difference(b).toString()); 259 | System.out.println("Difference (B - A): " + b.difference(a).toString()); 260 | } 261 | 262 | public static void main(String[] args) { 263 | System.out.println("Int sets:\n"); 264 | testIntSet(); 265 | System.out.println("\n\nString sets:\n"); 266 | testStringSet(); 267 | 268 | } 269 | } 270 | -------------------------------------------------------------------------------- /Spring2016/questions/q15/Q15.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* THE NODE CLASS */ 4 | function TreeNode(data, left, right) { 5 | this.data = data; 6 | this.left = left || null; 7 | this.right = right || null; 8 | } 9 | 10 | TreeNode.prototype.add = function(newNode, cF) { 11 | var compVal = cF(this.data, newNode.data); 12 | 13 | if (compVal === 0) { 14 | // do nothing 15 | return; 16 | } 17 | else if (compVal < 0) { 18 | if (!this.left) { 19 | this.left = newNode; 20 | } else { 21 | this.left.add(newNode, cF); 22 | } 23 | } else { 24 | if (!this.right) { 25 | this.right = newNode; 26 | } else { 27 | this.right.add(newNode, cF); 28 | } 29 | } 30 | }; 31 | 32 | TreeNode.prototype.contains = function(data, cF) { 33 | var compVal = cF(this.data, data); 34 | 35 | if (compVal === 0) { 36 | return true; 37 | } else if (compVal < 0 && this.left) { 38 | return this.left.contains(data, cF); 39 | } else if (compVal > 0 && this.right) { 40 | return this.right.contains(data, cF); 41 | } else { 42 | return false; 43 | } 44 | }; 45 | 46 | /* THE SET CLASS */ 47 | function TreeSet(compareFunc) { 48 | this.root = null; 49 | this.compareFunc = compareFunc || function (a, b) { return a - b }; 50 | } 51 | 52 | TreeSet.prototype.add = function() { 53 | for (var dataKey in arguments) { 54 | var data = arguments[dataKey]; 55 | var newNode = new TreeNode(data); 56 | 57 | if (!this.root) { 58 | this.root = newNode; 59 | } else { 60 | this.root.add(newNode, this.compareFunc); 61 | } 62 | } 63 | 64 | return this; 65 | }; 66 | 67 | TreeSet.prototype.contains = function(data) { 68 | if (!this.root) { 69 | return false; 70 | } else { 71 | return this.root.contains(data, this.compareFunc); 72 | } 73 | } 74 | 75 | TreeSet.prototype.toList = function() { 76 | var queue = []; 77 | var list = []; 78 | 79 | queue.push(this.root); 80 | 81 | while (queue.length) { 82 | var curr = queue.shift(); 83 | 84 | if (curr) { 85 | queue.push(curr.left, curr.right); 86 | list.push(curr.data); 87 | } 88 | } 89 | 90 | return list.sort(this.compareFunc); 91 | }; 92 | 93 | /* REQUIRED METHODS */ 94 | TreeSet.prototype.union = function(other) { 95 | var newTree = new TreeSet(); 96 | this.toList().concat(other.toList()).forEach(function(data) { 97 | newTree.add(data); 98 | }); 99 | 100 | return newTree; 101 | }; 102 | 103 | TreeSet.prototype.intersection = function(other) { 104 | var newTree = new TreeSet(); 105 | 106 | this.toList().forEach(function(data) { 107 | if (other.contains(data) === true) { 108 | newTree.add(data); 109 | } 110 | }); 111 | 112 | return newTree; 113 | } 114 | 115 | TreeSet.prototype.difference = function(other) { 116 | var newTree = new TreeSet(); 117 | 118 | this.toList().forEach(function(data) { 119 | if (other.contains(data) === false) { 120 | newTree.add(data); 121 | } 122 | }); 123 | 124 | return newTree; 125 | }; 126 | 127 | /* TESTING (i.e. Q16) */ 128 | var a = new TreeSet(); 129 | a.add(1, 2, 3); 130 | 131 | var b = new TreeSet(); 132 | b.add(2, 3); 133 | 134 | var assert = function(actual, expected) { 135 | var aS = actual.toString(); 136 | var eS = expected.toString(); 137 | 138 | if (aS == eS) { 139 | console.log('Test passed'); 140 | } else { 141 | console.log('Expected ' + aS + ' to be ' + eS); 142 | } 143 | }; 144 | 145 | assert(a.union(b).toList(), [1, 2, 3]); 146 | assert(a.intersection(b).toList(), [2, 3]); 147 | assert(a.difference(b).toList(), [1]); 148 | assert(a.union(new TreeSet()).toList(), [1, 2, 3]); 149 | assert(b.intersection(new TreeSet()).toList(), []); 150 | assert((new TreeSet()).difference(a).toList(), []); 151 | -------------------------------------------------------------------------------- /Spring2016/questions/q18/Solution.java: -------------------------------------------------------------------------------- 1 | public class Solution { 2 | public static String lookAndSay(String s) { 3 | StringBuilder sb = new StringBuilder(); 4 | int i = 0; 5 | while (i < s.length()) { 6 | char cur = s.charAt(i); 7 | int j = i; 8 | while (j < s.length() && s.charAt(j) == cur) { 9 | j++; 10 | } 11 | sb.append(j - i); 12 | sb.append(cur); 13 | i = j; 14 | } 15 | return sb.toString(); 16 | } 17 | 18 | public static void main(String[] args) { 19 | String s = "1"; 20 | for (int i = 0; i < 10; i++) { 21 | System.out.println(s); 22 | s = lookAndSay(s); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Spring2016/questions/q18/look_and_say.py: -------------------------------------------------------------------------------- 1 | def look(num): 2 | s = str(num) 3 | l = len(s) 4 | res = '' 5 | rpt = 0 6 | chr = s[0] 7 | i = 0 8 | 9 | for i in range(l): 10 | if s[i] == chr: 11 | rpt += 1 12 | else: 13 | res += str(rpt) + chr 14 | rpt = 1 15 | chr = s[i] 16 | 17 | if rpt >= 1: 18 | res += str(rpt) + chr 19 | 20 | return int(res) 21 | 22 | def look_and_say(n): 23 | num = 1 # the initial number in the sequence 24 | ctr = 1 # goes up to n 25 | while ctr <= n: 26 | print(num) # i.e. say 27 | num = look(num) 28 | ctr += 1 29 | 30 | look_and_say(7) 31 | -------------------------------------------------------------------------------- /Spring2016/questions/q19/Solution.java: -------------------------------------------------------------------------------- 1 | public class Solution { 2 | public static IntPair PairyTime(int k, int[] A) { 3 | int[] found = new int[k+1]; 4 | for (int i = 0; i < k+1; i++) { 5 | found[i] = -1; 6 | } 7 | 8 | for (int i = 0; i < A.length; i++) { 9 | // the modulus operator computes the remainder, which 10 | // isn't what we want here (it does the wrong thing with 11 | // negative numbers). the difference is that we want the 12 | // division to round _towards zero_, not down. 13 | int a = Math.floorMod(A[i], k); 14 | if (found[k-a] != -1) { 15 | return new IntPair(found[k-a], i); 16 | } 17 | found[a] = i; 18 | 19 | // if we find another a that's equal to zero, found[k-a] 20 | // will not be filled as it should be in unless we also do this 21 | if (a == 0) { 22 | found[k] = i; 23 | } 24 | } 25 | 26 | return null; 27 | } 28 | 29 | public static void main(String[] args) { 30 | System.out.println(PairyTime(3, new int[]{-2, 2})); 31 | System.out.println(PairyTime(8, new int[]{1, -2, -9, 1, 1, 1})); 32 | System.out.println(PairyTime(7, new int[]{0, 3, 1, 1, 0})); 33 | System.out.println(PairyTime(4, new int[]{})); 34 | System.out.println(PairyTime(3, new int[]{1, 1})); 35 | } 36 | 37 | private static class IntPair { 38 | public int fst; 39 | public int snd; 40 | 41 | public IntPair(int f, int s) { 42 | fst = f; 43 | snd = s; 44 | } 45 | 46 | public String toString() { 47 | return "[" + fst + ", " + snd + "]"; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Spring2016/questions/q19/pairy-time.py: -------------------------------------------------------------------------------- 1 | def pairy_time(k, A): 2 | 3 | # Since we only want to find multiplies 4 | # (i.e. "n*k for some integer n") 5 | # let's mod the entire list 6 | 7 | A_mod = [(a % k) for a in A] 8 | 9 | # We will keep track of indices in this dictionary 10 | # Think of it as a map for a value mod k => index in A_mod 11 | 12 | dct = {} 13 | 14 | # I initially used an array, but the `k - v` trick causes 15 | # a bounds error. You could also argue that a dictionary 16 | # is more efficient/scalable for large but "sparse" input lists. 17 | 18 | for i, v in enumerate(A_mod): 19 | if dct.get(k - v) is not None: 20 | j = dct.get(k - v) 21 | return [i, j] 22 | else: 23 | dct[v] = i 24 | 25 | # Special check required for zero since 26 | # k - 0 = k, which will never appear because of the mod 27 | 28 | if v == 0: 29 | dct[k] = i 30 | 31 | # Unsuccessful search 32 | 33 | return [None, None] 34 | 35 | 36 | ### TESTS ### 37 | print(str(pairy_time(3, [-2, 2]))) 38 | print(str(pairy_time(8, [1, -2, -9, 1, 1, 1]))) 39 | print(str(pairy_time(7, [0, 3, 1, 1, 0]))) 40 | print(str(pairy_time(4, []))) 41 | print(str(pairy_time(3, [1, 1]))) 42 | -------------------------------------------------------------------------------- /Spring2016/questions/questions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UW-UPL/UPLInterviewPrep/689dfc090f13b37d84438880dd06e07cc73af559/Spring2016/questions/questions.pdf -------------------------------------------------------------------------------- /Spring2016/questions/questions.tex: -------------------------------------------------------------------------------- 1 | \documentclass[12pt,runningheads]{article} 2 | \usepackage[utf8]{inputenc} 3 | \usepackage{amsmath,amssymb,hyperref,array,xcolor,multicol,verbatim,mathpazo} 4 | \usepackage[normalem]{ulem} 5 | \usepackage[pdftex]{graphicx} 6 | \begin{document} 7 | 8 | %%%% In most cases you won't need to edit anything above this line %%%% 9 | 10 | \title{UPL Interview Prep} 11 | \author{Riccardo Mutschlechner, Leo Rudberg, Nick Heindl} 12 | \maketitle 13 | 14 | Complete the following questions as best as you can. Write out the answer (on paper) without looking anything up. A nice tip is to try to use pseudocode first to hammer out your algorithm, and then proceed to program it up in the language of your choice. Interviews often ask you to code on paper or a whiteboard, so it is essential to practice this! You should spend at most 20 minutes on each the coding/algorithmic questions. 15 | 16 | These are some common problems we've encountered interviewing with various companies (Microsoft, Google, Dropbox, Yahoo, Riot Games, Amazon, and Uber to name a few), as well as in Cracking the Coding Interview. 17 | 18 | The questions here cover a variety of topics, but are presented in no specific order. 19 | 20 | If any part of any question seems vague or under-described, please ask! 21 | 22 | \newpage 23 | 24 | \section{Liftoff} 25 | Write a function that finds the first occurrence (index) of an integer $k$ in a sorted list of integers $A$, with possible duplicates. 26 | 27 | \begin{comment} 28 | This can be done most efficiently using two binary searches: 29 | 1) First find any instance of k using binary search 30 | 2) Then use a second binary search to find the _first instance_ of k 31 | \end{comment} 32 | \newpage 33 | 34 | \section{Abbreviation I} 35 | Write a function that takes two string arguments and returns a boolean (true/false). The function should return true if and only if the second string is a valid abbreviation of the first. 36 | 37 | An abbreviation is defined as a substring of an original string where any missing characters are replaced a number signifying however many are missing. You can assume we will only deal with uppercase characters (case doesn't matter). 38 | 39 | For example, "LOCALIZATION" is often abbreviated as "L10N" (disregarding case). Following the same rule, we could also have "LOCALIZATIO1", "L11", "11N", "LOCALIZATION", "L1C1LIZATION", and "12" as valid abbreviations.\\ 40 | 41 | For example: 42 | 43 | \begin{verbatim} 44 | isAbbr("LOCALIZATION", "L10N") // True 45 | isAbbr("LOCALIZATION", "L9N") // False 46 | isAbbr("LOCALIZATION", "L10Q") // False 47 | \end{verbatim} 48 | 49 | \begin{comment} 50 | def isAbbr(orig, test): 51 | i = 0 52 | while i != len(orig): 53 | if orig[i] == test[i]: # TODO: fix indexing error 54 | i += 1 55 | elif test[i].isdigit(): 56 | # do stuff 57 | num_start = i 58 | num_end = i + 1 59 | while num_end < len(test) and test[num_end].isdigit(): 60 | num_end += 1 61 | numeric_slice = test[num_start:num_end] 62 | num = int(numeric_slice) 63 | i += num 64 | else: 65 | return False 66 | return True 67 | 68 | def takeWhile(pred, lst): 69 | res = [] 70 | for elem in lst: 71 | if pred(elem): 72 | res.append(elem) 73 | else: 74 | break 75 | return res 76 | 77 | def isAbbrRec(orig, test): 78 | if not orig and not test: 79 | return True 80 | elif (not orig) != (not test): 81 | return False 82 | elif orig[0] == test[0]: 83 | return isAbbrRec(orig[1:], test[1:]) 84 | elif orig[0] != test[0] and test[0].isdigit(): 85 | numeric_prefix = takeWhile(lambda c: c.isdigit(), test) 86 | num = int(''.join(numeric_prefix)) 87 | return isAbbrRec(orig[num:], test[1:]) 88 | else: 89 | return False 90 | \end{comment} 91 | 92 | \newpage 93 | 94 | \section{Abbreviation II} 95 | 96 | Using the same rule from Abbreviation I, write a function that produces a list of all valid abbreviations of string. (Hint: there are a lot.)\\ 97 | 98 | For example: 99 | 100 | \begin{verbatim} 101 | allAbbrs("DOG") = ["DOG", "D2", ...] // order not important 102 | \end{verbatim} 103 | 104 | \begin{comment} 105 | This can be reduced to a power-set problem. 106 | 107 | Theoretically, generate all n-length bit-strings, where n is the length of the argument string. 108 | For each bit at i in each string, if a bit i is 0, then, use the ith letter of the string there. 109 | Otherwise, it bit i is 1, then it is number (adjacent 1's are added together). 110 | 111 | Realistically, this involves a divide-and-conquer approach (trim each letter) and a lot of int <=> str conversions. 112 | 113 | Haskell solution: 114 | https://gist.github.com/LOZORD/eb7792aa6182624a28a2 115 | \end{comment} 116 | 117 | \newpage 118 | 119 | \section{The Grandfather of All Interview Questions} 120 | 121 | Given a tree of strings, write a function that determines if any grandparent has any two grandchildren that have the same value. As part of your solution, please write an accessor function for a node's grandchildren. 122 | \begin{comment} 123 | Interviewee should ask about how tree is implemented (BST, binary, etc.). 124 | Depending upon implementation, this question should be trivial. 125 | 126 | Basically: 127 | 128 | gchildren = node.getGrandchildren() # implemented by interviewee 129 | uniqGChildren = gchildren.uniqBy {node a, node b: a.data == b.data} # remove duplicates 130 | return gchildren != uniqGChidren # we removed at least one duplicate 131 | \end{comment} 132 | \newpage 133 | 134 | \section{Design I} 135 | 136 | How would you implement autocomplete for a messaging app on a mobile device? 137 | \begin{comment} 138 | Although a map or a set is good starting point, the best implementation is a trie (not tree). 139 | This is memory efficient, and also works well with user's typings. 140 | \end{comment} 141 | \newpage 142 | 143 | \section{Design II} 144 | 145 | How would you architect an Instagram-like offering? 146 | 147 | \begin{comment} 148 | Open to interpretation of correctness ;) 149 | Should mention front-end and back-end decisions. 150 | How would data be managed (internationally)? Example: sharding 151 | \end{comment} 152 | 153 | \newpage 154 | 155 | \section{Design III} 156 | 157 | If you could change a typical programming workflow, how would you do it? In other words, how would you design a new programming environment? 158 | 159 | %%% hello Interactive Dance Environment :^) 160 | 161 | \newpage 162 | 163 | \section{Let's Play a Game} 164 | In the two-player game “Two Ends”, $n$ cards are laid out in a row. On each card, face up, is written 165 | a positive integer. Players take turns removing a card from either end of the row and placing the card 166 | in their pile, until all cards are removed. The score of a player is the sum of the integers of the cards 167 | in his/her pile. 168 | Give an efficient algorithm that takes $A$, the sequence of n positive integers, and determines the score of 169 | each player when both play optimally. 170 | 171 | (Taken from Prof Dieter van Melkebeek's CS 577 final exam review) 172 | \begin{comment} 173 | This problem requires a dynamic programming solution. 174 | \end{comment} 175 | \newpage 176 | 177 | \section{Personality I} 178 | 179 | What project are you most proud of? Was it a success? 180 | 181 | \newpage 182 | 183 | \section{Personality II} 184 | 185 | What's the last math class you've taken? Could you apply it to software engineering? Why/why not? 186 | 187 | \newpage 188 | 189 | \section{Personality III} 190 | 191 | What's the hardest problem you've ever worked on? 192 | 193 | \newpage 194 | 195 | \section{Personality IV} 196 | 197 | What would you do if you didn't know how to do something on the job? 198 | 199 | \newpage 200 | 201 | \section{Personality V} 202 | 203 | What type of sense of humor do you have? What is funny to you? 204 | 205 | \newpage 206 | 207 | \section{Personality VI} 208 | 209 | What was the most world-changing invention in the last 100 years? 1000 years? What will the most world changing invention be in the next 100 years? 210 | 211 | \newpage 212 | 213 | \section{OOP is OP} 214 | 215 | Write a Set class that has the union, intersection, and difference operations. (Do not use a built-in Set class in your answer.) 216 | 217 | \newpage 218 | 219 | \section{Meta-testing} 220 | 221 | Write an overview of assertions you would run to test your Set implementation. You don't have to write code for this part; just the method name, the input, and the expected output of each test is fine. 222 | \begin{comment} 223 | Each method should be tested with: 224 | Identical sets, different sets, empty sets, null and garbage arguments, etc. 225 | \end{comment} 226 | 227 | \newpage 228 | 229 | \section{Ask Me Later} 230 | What is a \textbf{promise} in the context of programming? Can you explain their use in five or less sentences? Can you give an example of a promise in use? 231 | 232 | (The purpose of this question is to test your knowledge of a specific concept. Often, interviewers will ask you about topics you may never have heard of, like promises, which show up a lot front-end development as a way of handling data exchange. Please know that is OK to say "I don't know" in response to an interviewer's questions.) 233 | \newpage 234 | 235 | \section{Quine Time} 236 | Write a function that gives the $n$th element in the following sequence: 237 | 238 | The sequence begins with the element "1". The next item in the sequence is how that element is read: we see one "1", so the next element is "11". The element after that is "21" since we see two ones in the previous step. After that, we have "1211". The sequence continues following that pattern. 239 | 240 | (Bonus question: do we ever see a "4" in a step? Why/why not?) (Double bonus: the mathematician who identified this sequence also created one of the most famous computer simulations of all time. What is his name?) 241 | 242 | %%% 243 | \begin{comment} 244 | def read(num): 245 | s = str(num) 246 | l = len(s) 247 | res = '' 248 | rpt = 0 249 | chr = s[0] 250 | i = 0 251 | 252 | for i in range(l): 253 | if s[i] == chr: 254 | rpt += 1 255 | else: 256 | res += str(rpt) + chr 257 | rpt = 1 258 | chr = s[i] 259 | 260 | if rpt >= 1: 261 | res += str(rpt) + chr 262 | 263 | return int(res) 264 | 265 | num = 1 266 | ctr = 1 267 | lim = 15 268 | 269 | while ctr != lim: 270 | print(num) 271 | num = read(num) 272 | ctr += 1 273 | 274 | \end{comment} 275 | %%% 276 | 277 | \newpage 278 | 279 | \section{Pair-y Time} 280 | Given an integer $k$ and a list of integers $A$, find if there exists a pair $(i, j): A[i] + A[j] = nk$, for some $n \in Z$. 281 | \begin{comment} 282 | First mod everything by k. Then use a hash or array to find pairs that sum to "0" = k. 283 | \end{comment} 284 | \end{document} 285 | --------------------------------------------------------------------------------