├── LICENSE ├── README.md ├── code ├── 01_introduction_to_algorithms │ └── 01_binary_search.py ├── 02_selection_sort │ └── 01_selection_sort.py ├── 03_recursion │ ├── 01_countdown.js │ ├── 02_greet.js │ └── 03_factorial.js ├── 04_quicksort │ ├── 01_loop_sum.js │ ├── 02_recursive_sum.js │ ├── 03_recursive_count.js │ ├── 04_recursive_max.js │ └── 05_quicksort.js ├── 05_hash_tables │ ├── 01_price_of_groceries.js │ └── 02_check_voter.js ├── 06_breadth-first_search │ └── 01_breadth-first_search.py ├── 07_dijkstras_algorithm │ └── 01_dijkstras_algorithm.py ├── 08_greedy_algorithms │ └── 01_set_covering.py └── 09_dynamic_programming │ └── 01_longest_common_subsequence.py └── projects ├── 2_1 ├── Array │ └── contactapp.py ├── Solution │ ├── contactapp.py │ └── linkedlist.py ├── challenge.txt ├── contactapp.py └── linkedlist.py ├── 2_2 ├── LinkedList │ ├── contactapp.py │ └── linkedlist.py ├── Solution │ ├── contactapp.py │ ├── selectionsort.py │ └── selectionsort.pyc ├── challenge.txt ├── contactapp.py └── selectionsort.py ├── 3_1 ├── Solution │ ├── contactapp.py │ ├── selectionsort.py │ └── selectionsort.pyc ├── challenge.txt ├── contactapp.py └── selectionsort.py └── 4_2 ├── Solution ├── contactapp.py ├── quicksort.py ├── quicksort.pyc └── selectionsort.pyc ├── challenge.txt ├── contactapp.py └── quicksort.py /LICENSE: -------------------------------------------------------------------------------- 1 | Grokking Algorithms is copyrighted by Manning Publications. You are free to use the images in this repo for non-commercial use, but you need to add "copyright Manning Publications, drawn by adit.io". 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Grokking Algorithms 2 | 3 | This is the code and projects from my video course [Algorithms in Motion](https://www.manning.com/livevideo/algorithms-in-motion) based on the book [Grokking Algorithms](https://www.manning.com/bhargava). -------------------------------------------------------------------------------- /code/01_introduction_to_algorithms/01_binary_search.py: -------------------------------------------------------------------------------- 1 | def binary_search(list, item): 2 | # low and high keep track of which part of the list you'll search in. 3 | low = 0 4 | high = len(list) - 1 5 | 6 | # While you haven't narrowed it down to one element ... 7 | while low <= high: 8 | # ... check the middle element 9 | mid = (low + high) // 2 10 | guess = list[mid] 11 | # Found the item. 12 | if guess == item: 13 | return mid 14 | # The guess was too high. 15 | if guess > item: 16 | high = mid - 1 17 | # The guess was too low. 18 | else: 19 | low = mid + 1 20 | 21 | # Item doesn't exist 22 | return None 23 | 24 | my_list = [1, 3, 5, 7, 9] 25 | print binary_search(my_list, 3) # => 1 26 | 27 | # 'None' means nil in Python. We use to indicate that the item wasn't found. 28 | print binary_search(my_list, -1) # => None 29 | -------------------------------------------------------------------------------- /code/02_selection_sort/01_selection_sort.py: -------------------------------------------------------------------------------- 1 | # Finds the smallest value in an array 2 | def findSmallest(arr): 3 | # Stores the smallest value 4 | smallest = arr[0] 5 | # Stores the index of the smallest value 6 | smallest_index = 0 7 | for i in range(1, len(arr)): 8 | if arr[i] < smallest: 9 | smallest = arr[i] 10 | smallest_index = i 11 | return smallest_index 12 | 13 | # Sort array 14 | def selectionSort(arr): 15 | newArr = [] 16 | for i in range(len(arr)): 17 | # Finds the smallest element in the array and adds it to the new array 18 | smallest = findSmallest(arr) 19 | newArr.append(arr.pop(smallest)) 20 | return newArr 21 | 22 | print selectionSort([5, 3, 6, 2, 10]) 23 | -------------------------------------------------------------------------------- /code/03_recursion/01_countdown.js: -------------------------------------------------------------------------------- 1 | function countdown(i) { 2 | console.log(i); 3 | // base case 4 | if (i <= 0) { 5 | return; 6 | } else { 7 | countdown(i-1); 8 | } 9 | } 10 | 11 | countdown(5); 12 | -------------------------------------------------------------------------------- /code/03_recursion/02_greet.js: -------------------------------------------------------------------------------- 1 | function greet2(name) { 2 | console.log('how are you, ' + name + '?'); 3 | } 4 | 5 | function bye() { 6 | console.log('ok bye!'); 7 | } 8 | 9 | function greet(name) { 10 | console.log('hello, ' + name + '!'); 11 | greet2(name); 12 | console.log('getting ready to say bye...'); 13 | bye(); 14 | } 15 | 16 | greet('adit'); 17 | -------------------------------------------------------------------------------- /code/03_recursion/03_factorial.js: -------------------------------------------------------------------------------- 1 | function fact(x) { 2 | if (x === 1) { 3 | return 1; 4 | } else { 5 | return x * fact(x-1); 6 | } 7 | } 8 | 9 | console.log(fact(5)); 10 | -------------------------------------------------------------------------------- /code/04_quicksort/01_loop_sum.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function sum(arr) { 4 | let total = 0; 5 | for (let x = 0; x < arr.length; x++) { 6 | total += arr[x]; 7 | } 8 | return total; 9 | } 10 | 11 | console.log(sum([1, 2, 3, 4])) // 10 12 | -------------------------------------------------------------------------------- /code/04_quicksort/02_recursive_sum.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function sum(list) { 4 | if (list.length === 0) { 5 | return 0; 6 | } 7 | return list[0] + sum(list.slice(1)); 8 | } 9 | 10 | console.log(sum([1, 2, 3, 4])) // 10 11 | -------------------------------------------------------------------------------- /code/04_quicksort/03_recursive_count.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function count(list) { 4 | if (list.length === 0) { 5 | return 0; 6 | } 7 | return 1 + count(list.slice(1)); 8 | } 9 | 10 | console.log(count([0, 1, 2, 3, 4, 5])); // 6 11 | -------------------------------------------------------------------------------- /code/04_quicksort/04_recursive_max.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function max(list) { 4 | if (list.length === 2) { 5 | return list[0] > list[1] ? list[0] : list[1]; 6 | } 7 | let sub_max = max(list.slice(1)); 8 | return list[0] > sub_max ? list[0] : sub_max; 9 | } 10 | 11 | console.log(max([1, 5, 10, 25, 16, 1])); // 25 12 | -------------------------------------------------------------------------------- /code/04_quicksort/05_quicksort.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function quicksort(array) { 4 | if (array.length < 2) { 5 | // base case, arrays with 0 or 1 element are already "sorted" 6 | return array; 7 | } else { 8 | // recursive case 9 | let pivot = array[0]; 10 | // sub-array of all the elements less than the pivot 11 | let less = array.slice(1).filter(function(el) { return el <= pivot; }); 12 | // sub-array of all the elements greater than the pivot 13 | let greater = array.slice(1).filter(function(el) { return el > pivot; }); 14 | return quicksort(less).concat([pivot], quicksort(greater)); 15 | } 16 | } 17 | 18 | console.log(quicksort([10, 5, 2, 3])); // [2, 3, 5, 10] 19 | -------------------------------------------------------------------------------- /code/05_hash_tables/01_price_of_groceries.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const book = {}; 4 | // an apple costs 67 cents 5 | book['apple'] = 0.67; 6 | // milk costs $1.49 7 | book['milk'] = 1.49; 8 | book['avocado'] = 1.49; 9 | 10 | console.log(book); // { apple: 0.67, milk: 1.49, avocado: 1.49 } 11 | -------------------------------------------------------------------------------- /code/05_hash_tables/02_check_voter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const voted = {}; 4 | function check_voter(name) { 5 | if (voted[name]) { 6 | console.log('kick them out!'); 7 | } else { 8 | voted[name] = true; 9 | console.log('let them vote!'); 10 | } 11 | } 12 | 13 | 14 | check_voter("tom"); // let them vote! 15 | check_voter("mike"); // let them vote! 16 | check_voter("mike"); // kick them out! 17 | -------------------------------------------------------------------------------- /code/06_breadth-first_search/01_breadth-first_search.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | def person_is_seller(name): 4 | return name[-1] == 'm' 5 | 6 | graph = {} 7 | graph["you"] = ["alice", "bob", "claire"] 8 | graph["bob"] = ["anuj", "peggy"] 9 | graph["alice"] = ["peggy"] 10 | graph["claire"] = ["thom", "jonny"] 11 | graph["anuj"] = [] 12 | graph["peggy"] = [] 13 | graph["thom"] = [] 14 | graph["jonny"] = [] 15 | 16 | def search(name): 17 | search_queue = deque() 18 | search_queue += graph[name] 19 | # This array is how you keep track of which people you've searched before. 20 | searched = [] 21 | while search_queue: 22 | person = search_queue.popleft() 23 | # Only search this person if you haven't already searched them. 24 | if not person in searched: 25 | if person_is_seller(person): 26 | print person + " is a mango seller!" 27 | return True 28 | else: 29 | search_queue += graph[person] 30 | # Marks this person as searched 31 | searched.append(person) 32 | return False 33 | 34 | search("you") 35 | -------------------------------------------------------------------------------- /code/07_dijkstras_algorithm/01_dijkstras_algorithm.py: -------------------------------------------------------------------------------- 1 | # the graph 2 | graph = {} 3 | graph["start"] = {} 4 | graph["start"]["a"] = 6 5 | graph["start"]["b"] = 2 6 | 7 | graph["a"] = {} 8 | graph["a"]["fin"] = 1 9 | 10 | graph["b"] = {} 11 | graph["b"]["a"] = 3 12 | graph["b"]["fin"] = 5 13 | 14 | graph["fin"] = {} 15 | 16 | # the costs table 17 | infinity = float("inf") 18 | costs = {} 19 | costs["a"] = 6 20 | costs["b"] = 2 21 | costs["fin"] = infinity 22 | 23 | # the parents table 24 | parents = {} 25 | parents["a"] = "start" 26 | parents["b"] = "start" 27 | parents["fin"] = None 28 | 29 | processed = [] 30 | 31 | def find_lowest_cost_node(costs): 32 | lowest_cost = float("inf") 33 | lowest_cost_node = None 34 | # Go through each node. 35 | for node in costs: 36 | cost = costs[node] 37 | # If it's the lowest cost so far and hasn't been processed yet... 38 | if cost < lowest_cost and node not in processed: 39 | # ... set it as the new lowest-cost node. 40 | lowest_cost = cost 41 | lowest_cost_node = node 42 | return lowest_cost_node 43 | 44 | # Find the lowest-cost node that you haven't processed yet. 45 | node = find_lowest_cost_node(costs) 46 | # If you've processed all the nodes, this while loop is done. 47 | while node is not None: 48 | cost = costs[node] 49 | # Go through all the neighbors of this node. 50 | neighbors = graph[node] 51 | for n in neighbors.keys(): 52 | new_cost = cost + neighbors[n] 53 | # If it's cheaper to get to this neighbor by going through this node... 54 | if costs[n] > new_cost: 55 | # ... update the cost for this node. 56 | costs[n] = new_cost 57 | # This node becomes the new parent for this neighbor. 58 | parents[n] = node 59 | # Mark the node as processed. 60 | processed.append(node) 61 | # Find the next node to process, and loop. 62 | node = find_lowest_cost_node(costs) 63 | 64 | print "Cost from the start to each node:" 65 | print costs 66 | 67 | -------------------------------------------------------------------------------- /code/08_greedy_algorithms/01_set_covering.py: -------------------------------------------------------------------------------- 1 | # You pass an array in, and it gets converted to a set. 2 | states_needed = set(["mt", "wa", "or", "id", "nv", "ut", "ca", "az"]) 3 | 4 | stations = {} 5 | stations["kone"] = set(["id", "nv", "ut"]) 6 | stations["ktwo"] = set(["wa", "id", "mt"]) 7 | stations["kthree"] = set(["or", "nv", "ca"]) 8 | stations["kfour"] = set(["nv", "ut"]) 9 | stations["kfive"] = set(["ca", "az"]) 10 | 11 | final_stations = set() 12 | 13 | while states_needed: 14 | best_station = None 15 | states_covered = set() 16 | for station, states in stations.items(): 17 | covered = states_needed & states 18 | if len(covered) > len(states_covered): 19 | best_station = station 20 | states_covered = covered 21 | 22 | states_needed -= states_covered 23 | final_stations.add(best_station) 24 | 25 | print final_stations 26 | -------------------------------------------------------------------------------- /code/09_dynamic_programming/01_longest_common_subsequence.py: -------------------------------------------------------------------------------- 1 | if word_a[i] == word_b[j]: 2 | # The letters match. 3 | cell[i][j] = cell[i-1][j-1] + 1 4 | else: 5 | # The letters don't match. 6 | cell[i][j] = max(cell[i-1][j], cell[i][j-1]) 7 | -------------------------------------------------------------------------------- /projects/2_1/Array/contactapp.py: -------------------------------------------------------------------------------- 1 | # DO IT! CHALLENGE - 2.1 Linked List 2 | # Contact management app implemented using an array (technically a Python list). 3 | 4 | def print_menu(): 5 | print('1. Print Contacts') 6 | print('2. Add a Contact') 7 | print('3. Remove a Contact') 8 | print('4. Lookup a Contact') 9 | print('5. Quit') 10 | print('') 11 | 12 | people = [{'name' : 'Judah', 'age' : 2}, {'name' : 'Beau', 'age' : 33}, {'name' : 'Aditya', 'age' : 29}] 13 | 14 | menu_choice = 0 15 | print_menu() 16 | while menu_choice != 5: 17 | menu_choice = int(input("Type in a number (1-5): ")) 18 | if menu_choice == 1: 19 | for person in people: 20 | print(person) 21 | print('') 22 | elif menu_choice == 2: 23 | print("Add Contact") 24 | name = raw_input("Name: ") 25 | age = raw_input("Age: ") 26 | people.append({'name' : name, 'age' : int(age)}) 27 | elif menu_choice == 3: 28 | print("Remove Contact") 29 | name = raw_input("Name: ") 30 | removed = False 31 | for person in people : 32 | if person['name'] == name : 33 | people.remove(person) 34 | removed = True 35 | if removed: 36 | print(name + " was deleted") 37 | else: 38 | print(name + " was NOT found") 39 | elif menu_choice == 4: 40 | print("Lookup Contact") 41 | name = raw_input("Name: ") 42 | found = False 43 | for person in people : 44 | if person['name'] == name : 45 | print(person) 46 | found = True 47 | if not found: 48 | print(name + " was not found") 49 | 50 | elif menu_choice != 5: 51 | print_menu() -------------------------------------------------------------------------------- /projects/2_1/Solution/contactapp.py: -------------------------------------------------------------------------------- 1 | # DO IT! CHALLENGE - 2.1 Linked List 2 | 3 | import linkedlist 4 | 5 | def print_menu(): 6 | print('1. Print Contacts') 7 | print('2. Add a Contact') 8 | print('3. Remove a Contact') 9 | print('4. Lookup a Contact') 10 | print('5. Quit') 11 | print('') 12 | 13 | people = linkedlist.LinkedList() 14 | people.add({'name' : 'Judah', 'age' : 2}) 15 | people.add({'name' : 'Beau', 'age' : 33}) 16 | people.add({'name' : 'Aditya', 'age' : 29}) 17 | 18 | menu_choice = 0 19 | print_menu() 20 | while menu_choice != 5: 21 | menu_choice = int(input("Type in a number (1-5): ")) 22 | if menu_choice == 1: 23 | person = people.head 24 | while person != None: 25 | print(person.data) 26 | person = person.next 27 | print('') 28 | elif menu_choice == 2: 29 | print("Add Contact") 30 | name = raw_input("Name: ") 31 | age = raw_input("Age: ") 32 | people.add({'name' : name, 'age' : int(age)}) 33 | elif menu_choice == 3: 34 | print("Remove Contact") 35 | name = raw_input("Name: ") 36 | if people.remove(name): 37 | print(name + " was deleted") 38 | else: 39 | print(name + " was NOT found") 40 | elif menu_choice == 4: 41 | print("Lookup Contact") 42 | name = raw_input("Name: ") 43 | person = people.search(name) 44 | if person: 45 | print(person) 46 | else: 47 | print(name + " was not found") 48 | elif menu_choice != 5: 49 | print_menu() -------------------------------------------------------------------------------- /projects/2_1/Solution/linkedlist.py: -------------------------------------------------------------------------------- 1 | ''' 2 | DO IT! CHALLENGE - 2.1 Linked List 3 | 4 | SOLUTION 5 | ''' 6 | 7 | class Node: 8 | def __init__(self, data): 9 | self.data = data 10 | self.next = None 11 | 12 | class LinkedList: 13 | 14 | def __init__(self): 15 | self.head = None 16 | 17 | def add(self, data): 18 | temp = Node(data) 19 | temp.next = self.head 20 | self.head = temp 21 | 22 | def remove(self, name): 23 | current = self.head 24 | previous = None 25 | found = False 26 | while current != None and not found: 27 | if current.data['name'] == name: 28 | found = True 29 | else: 30 | previous = current 31 | current = current.next 32 | if found: 33 | if previous == None: 34 | self.head = current.next 35 | else: 36 | previous.next = current.next 37 | return found 38 | 39 | def search(self, name): 40 | current = self.head 41 | found = False 42 | while current != None and not found: 43 | if current.data['name'] == name: 44 | found = True 45 | else: 46 | current = current.next 47 | return current.data if found else None 48 | 49 | def selectionSort(self, sort_by): 50 | node1 = self.head 51 | while node1 != None : 52 | min = node1 53 | node2 = node1 54 | while node2 != None : 55 | if min.data[sort_by] > node2.data[sort_by] : 56 | min = node2 57 | node2 = node2.next 58 | temp = node1.data 59 | node1.data = min.data 60 | min.data = temp 61 | node1 = node1.next 62 | 63 | 64 | -------------------------------------------------------------------------------- /projects/2_1/challenge.txt: -------------------------------------------------------------------------------- 1 | DO IT! CHALLENGE - 2.1 Linked List 2 | 3 | Finish the add, remove, and search functions of a linked list data structure so it will work correctly. 4 | To check your work, run 'contactapp.py' and test if all the functions listed in the menu run properly. 5 | 6 | CHANGE THIS FILE 7 | /2.1/linkedlist.py 8 | 9 | RUN THIS FILE TO TEST 10 | /2.1/contactapp.py 11 | 12 | SOLUTION FILES 13 | /2.1/Solution/* 14 | (Don't open until you have tried the challenge yourself!) 15 | 16 | OTHER EXAMPLE FILES 17 | /2.1/Array/* 18 | (Note: These files are not used for the DO IT! CHALLENGE. The purpose is to demonstrate how the contact 19 | management program could work with an array instead of a linked list. -------------------------------------------------------------------------------- /projects/2_1/contactapp.py: -------------------------------------------------------------------------------- 1 | ''' 2 | DO IT! CHALLENGE - 2.1 Linked List 3 | Do not modify this file. Finish the Linked List in 'linkedlist.py'. 4 | To check your work, run this file and test if all the functions 5 | listed in the menu work correctly. 6 | ''' 7 | 8 | import linkedlist 9 | 10 | def print_menu(): 11 | print('1. Print Contacts') 12 | print('2. Add a Contact') 13 | print('3. Remove a Contact') 14 | print('4. Lookup a Contact') 15 | print('5. Quit') 16 | print('') 17 | 18 | people = linkedlist.LinkedList() 19 | people.add({'name' : 'Judah', 'age' : 2}) 20 | people.add({'name' : 'Beau', 'age' : 33}) 21 | people.add({'name' : 'Aditya', 'age' : 29}) 22 | 23 | menu_choice = 0 24 | print_menu() 25 | while menu_choice != 5: 26 | menu_choice = int(input("Type in a number (1-5): ")) 27 | if menu_choice == 1: 28 | person = people.head 29 | while person != None: 30 | print(person.data) 31 | person = person.next 32 | print('') 33 | elif menu_choice == 2: 34 | print("Add Contact") 35 | name = raw_input("Name: ") 36 | age = raw_input("Age: ") 37 | people.add({'name' : name, 'age' : int(age)}) 38 | elif menu_choice == 3: 39 | print("Remove Contact") 40 | name = raw_input("Name: ") 41 | if people.remove(name): 42 | print(name + " was deleted") 43 | else: 44 | print(name + " was NOT found") 45 | elif menu_choice == 4: 46 | print("Lookup Contact") 47 | name = raw_input("Name: ") 48 | person = people.search(name) 49 | if person: 50 | print(person) 51 | else: 52 | print(name + " was not found") 53 | elif menu_choice != 5: 54 | print_menu() -------------------------------------------------------------------------------- /projects/2_1/linkedlist.py: -------------------------------------------------------------------------------- 1 | ''' 2 | DO IT! CHALLENGE - 2.1 Linked List 3 | Finish the add, remove, and search functions so this LinkedList will work. 4 | To check your work, run 'contactapp.py' and test if all the functions 5 | listed in the menu work correctly. 6 | ''' 7 | 8 | class Node: 9 | def __init__(self, data): 10 | self.data = data 11 | self.next = None 12 | 13 | class LinkedList: 14 | 15 | def __init__(self): 16 | self.head = None 17 | 18 | def add(self, data): 19 | # Insert new node as head node 20 | 21 | def remove(self, name): 22 | # Go through entire list until node to remove is found 23 | # Once found set previous.next to equal current.next 24 | # Remember to check if current.data['name'] == name 25 | # Put your code between 'found = False' and 'return found' 26 | current = self.head 27 | previous = None 28 | found = False 29 | 30 | 31 | 32 | 33 | 34 | return found 35 | 36 | def search(self, name): 37 | # Go through entire list until node is found 38 | # Return full data of node once found, else return None 39 | current = self.head 40 | found = False 41 | 42 | 43 | -------------------------------------------------------------------------------- /projects/2_2/LinkedList/contactapp.py: -------------------------------------------------------------------------------- 1 | # DO IT! CHALLENGE - 2.2 Selection Sort 2 | 3 | import linkedlist 4 | 5 | def print_menu(): 6 | print('1. Print Contacts') 7 | print('2. Add a Contact') 8 | print('3. Remove a Contact') 9 | print('4. Lookup a Contact') 10 | print('5. Quit') 11 | print('') 12 | 13 | people = linkedlist.LinkedList() 14 | people.add({'name' : 'Judah', 'age' : 2}) 15 | people.add({'name' : 'Beau', 'age' : 33}) 16 | people.add({'name' : 'Aditya', 'age' : 29}) 17 | 18 | menu_choice = 0 19 | print_menu() 20 | while menu_choice != 5: 21 | menu_choice = int(input("Type in a number (1-5): ")) 22 | if menu_choice == 1: 23 | sort_by = raw_input("Sort by name or age: ") 24 | while not(sort_by == 'name' or sort_by == 'age'): 25 | sort_by = raw_input("Must enter 'name' or 'age': ") 26 | people.selectionSort(sort_by) 27 | person = people.head 28 | while person != None: 29 | print(person.data) 30 | person = person.next 31 | print('') 32 | elif menu_choice == 2: 33 | print("Add Contact") 34 | name = raw_input("Name: ") 35 | age = raw_input("Age: ") 36 | people.add({'name' : name, 'age' : int(age)}) 37 | elif menu_choice == 3: 38 | print("Remove Contact") 39 | name = raw_input("Name: ") 40 | if people.remove(name): 41 | print(name + " was deleted") 42 | else: 43 | print(name + " was NOT found") 44 | elif menu_choice == 4: 45 | print("Lookup Contact") 46 | name = raw_input("Name: ") 47 | person = people.search(name) 48 | if person: 49 | print(person) 50 | else: 51 | print(name + " was not found") 52 | elif menu_choice != 5: 53 | print_menu() -------------------------------------------------------------------------------- /projects/2_2/LinkedList/linkedlist.py: -------------------------------------------------------------------------------- 1 | # SPOILER ALERT: Contains solution to 2.1 challenge. Solve that challenge before looking at this code. 2 | 3 | # Selection sort is implemented at the end of the LinkedList class. 4 | 5 | class Node: 6 | def __init__(self, data): 7 | self.data = data 8 | self.next = None 9 | 10 | class LinkedList: 11 | 12 | def __init__(self): 13 | self.head = None 14 | self.length = 0 15 | 16 | def add(self, data): 17 | temp = Node(data) 18 | temp.next = self.head 19 | self.head = temp 20 | self.length += 1 21 | 22 | def remove(self, name): 23 | current = self.head 24 | previous = None 25 | found = False 26 | while current != None and not found: 27 | if current.data['name'] == name: 28 | found = True 29 | else: 30 | previous = current 31 | current = current.next 32 | if found: 33 | if previous == None: 34 | self.head = current.next 35 | else: 36 | previous.next = current.next 37 | return found 38 | 39 | def search(self, name): 40 | current = self.head 41 | found = False 42 | while current != None and not found: 43 | if current.data['name'] == name: 44 | found = True 45 | else: 46 | current = current.next 47 | return current.data if found else None 48 | 49 | def selectionSort(self, sort_by): 50 | node1 = self.head 51 | while node1 != None : 52 | min = node1 53 | node2 = node1 54 | while node2 != None : 55 | if min.data[sort_by] > node2.data[sort_by] : 56 | min = node2 57 | node2 = node2.next 58 | temp = node1.data 59 | node1.data = min.data 60 | min.data = temp 61 | node1 = node1.next 62 | 63 | 64 | -------------------------------------------------------------------------------- /projects/2_2/Solution/contactapp.py: -------------------------------------------------------------------------------- 1 | # DO IT! CHALLENGE - 2.2 Selection Sort 2 | 3 | import selectionsort 4 | 5 | def print_menu(): 6 | print('1. Print Contacts') 7 | print('2. Add a Contact') 8 | print('3. Remove a Contact') 9 | print('4. Lookup a Contact') 10 | print('5. Quit') 11 | print('') 12 | 13 | people = [{'name' : 'Judah', 'age' : 2}, {'name' : 'Beau', 'age' : 33}, {'name' : 'Aditya', 'age' : 29}] 14 | 15 | menu_choice = 0 16 | print_menu() 17 | while menu_choice != 5: 18 | menu_choice = int(input("Type in a number (1-5): ")) 19 | if menu_choice == 1: 20 | sort_by = raw_input("Sort by name or age: ") 21 | while not(sort_by == 'name' or sort_by == 'age'): 22 | sort_by = raw_input("Must enter 'name' or 'age': ") 23 | selectionsort.sort(people, sort_by) 24 | for person in people: 25 | print(person) 26 | print('') 27 | elif menu_choice == 2: 28 | print("Add Contact") 29 | name = raw_input("Name: ") 30 | age = raw_input("Age: ") 31 | people.append({'name' : name, 'age' : int(age)}) 32 | elif menu_choice == 3: 33 | print("Remove Contact") 34 | name = raw_input("Name: ") 35 | removed = False 36 | for person in people : 37 | if person['name'] == name : 38 | people.remove(person) 39 | removed = True 40 | if removed: 41 | print(name + " was deleted") 42 | else: 43 | print(name + " was NOT found") 44 | elif menu_choice == 4: 45 | print("Lookup Contact") 46 | name = raw_input("Name: ") 47 | found = False 48 | for person in people : 49 | if person['name'] == name : 50 | print(person) 51 | found = True 52 | if not found: 53 | print(name + " was not found") 54 | 55 | elif menu_choice != 5: 56 | print_menu() -------------------------------------------------------------------------------- /projects/2_2/Solution/selectionsort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | DO IT! CHALLENGE - 2.2 Selection Sort 3 | 4 | SOLUTION 5 | ''' 6 | 7 | def sort(list, sort_by): 8 | for i in range (len(list)): 9 | minIndex = i 10 | for j in range (i+1, len(list)): 11 | if list[j][sort_by] < list[minIndex][sort_by]: 12 | minIndex = j 13 | if minIndex != i: 14 | temp = list[i] 15 | list[i] = list[minIndex] 16 | list[minIndex] = temp -------------------------------------------------------------------------------- /projects/2_2/Solution/selectionsort.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beaucarnes/algorithms-in-motion/5bebbaa5308e0d51b578a3478dc677fa33cf518e/projects/2_2/Solution/selectionsort.pyc -------------------------------------------------------------------------------- /projects/2_2/challenge.txt: -------------------------------------------------------------------------------- 1 | DO IT! CHALLENGE - 2.2 Selection Sort 2 | 3 | Create a selection sort algorithm that sorts an array in place without creating another array. The function 4 | should sort the 'people' array from 'contactapp.py'. The algorithm should sort by 'name' or 'age', depending 5 | on what is passed in. To check, run 'contactapp.py' and verify that when you print contacts, the program 6 | accurately sorts the list based on the given parameter. 7 | 8 | CHANGE THIS FILE 9 | /2.2/selectionsort.py 10 | 11 | RUN THIS FILE TO TEST 12 | /2.2/contactapp.py 13 | 14 | SOLUTION FILES 15 | /2.2/Solution/* 16 | (Don't open until you have tried the challenge yourself!) 17 | 18 | OTHER EXAMPLE FILES 19 | /2.1/LinkedList/* 20 | (Note: These files are not used for the DO IT! CHALLENGE. The purpose is to demonstrate a selection sort 21 | with a linked list. In the challenge, you will be implementing selection sort with an array.) -------------------------------------------------------------------------------- /projects/2_2/contactapp.py: -------------------------------------------------------------------------------- 1 | ''' 2 | DO IT! CHALLENGE - 2.2 Selection Sort 3 | Do not modify this file. Create the selection sort function in 'selectionsort.py'. 4 | To check your work, run this file and test if all the print function in the menu 5 | works correctly. 6 | ''' 7 | 8 | import selectionsort 9 | 10 | def print_menu(): 11 | print('1. Print Contacts') 12 | print('2. Add a Contact') 13 | print('3. Remove a Contact') 14 | print('4. Lookup a Contact') 15 | print('5. Quit') 16 | print('') 17 | 18 | people = [{'name' : 'Judah', 'age' : 2}, {'name' : 'Beau', 'age' : 33}, {'name' : 'Aditya', 'age' : 29}] 19 | 20 | menu_choice = 0 21 | print_menu() 22 | while menu_choice != 5: 23 | menu_choice = int(input("Type in a number (1-5): ")) 24 | if menu_choice == 1: 25 | sort_by = raw_input("Sort by name or age: ") 26 | while not(sort_by == 'name' or sort_by == 'age'): 27 | sort_by = raw_input("Must enter 'name' or 'age': ") 28 | selectionsort.sort(people, sort_by) 29 | for person in people: 30 | print(person) 31 | print('') 32 | elif menu_choice == 2: 33 | print("Add Contact") 34 | name = raw_input("Name: ") 35 | age = raw_input("Age: ") 36 | people.append({'name' : name, 'age' : int(age)}) 37 | elif menu_choice == 3: 38 | print("Remove Contact") 39 | name = raw_input("Name: ") 40 | removed = False 41 | for person in people : 42 | if person['name'] == name : 43 | people.remove(person) 44 | removed = True 45 | if removed: 46 | print(name + " was deleted") 47 | else: 48 | print(name + " was NOT found") 49 | elif menu_choice == 4: 50 | print("Lookup Contact") 51 | name = raw_input("Name: ") 52 | found = False 53 | for person in people : 54 | if person['name'] == name : 55 | print(person) 56 | found = True 57 | if not found: 58 | print(name + " was not found") 59 | 60 | elif menu_choice != 5: 61 | print_menu() -------------------------------------------------------------------------------- /projects/2_2/selectionsort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | DO IT! CHALLENGE - 2.2 Selection Sort 3 | Create a selection sort algorithm that sorts an array in place without creating another array. This function 4 | should sort the people array from 'contactapp.py'. The algorithm should sort by 'name' or 'age', depending 5 | on what is passed in. To check, run 'contactapp.py' and verify that when you print contacts, the program 6 | accurately sorts list based on the given parameter. 7 | ''' 8 | 9 | def sort(list, sort_by): 10 | -------------------------------------------------------------------------------- /projects/3_1/Solution/contactapp.py: -------------------------------------------------------------------------------- 1 | # DO IT! CHALLENGE - 3.1 Recursion 2 | 3 | import selectionsort 4 | 5 | def print_menu(): 6 | print('1. Print Contacts') 7 | print('2. Add a Contact') 8 | print('3. Remove a Contact') 9 | print('4. Lookup a Contact') 10 | print('5. Quit') 11 | print('') 12 | 13 | people = [{'name' : 'Judah', 'age' : 2}, {'name' : 'Beau', 'age' : 33}, {'name' : 'Aditya', 'age' : 29}] 14 | 15 | menu_choice = 0 16 | print_menu() 17 | while menu_choice != 5: 18 | menu_choice = int(input("Type in a number (1-5): ")) 19 | if menu_choice == 1: 20 | sort_by = raw_input("Sort by name or age: ") 21 | while not(sort_by == 'name' or sort_by == 'age'): 22 | sort_by = raw_input("Must enter 'name' or 'age': ") 23 | selectionsort.sort(people, sort_by) 24 | for person in people: 25 | print(person) 26 | print('') 27 | elif menu_choice == 2: 28 | print("Add Contact") 29 | name = raw_input("Name: ") 30 | age = raw_input("Age: ") 31 | people.append({'name' : name, 'age' : int(age)}) 32 | elif menu_choice == 3: 33 | print("Remove Contact") 34 | name = raw_input("Name: ") 35 | removed = False 36 | for person in people : 37 | if person['name'] == name : 38 | people.remove(person) 39 | removed = True 40 | if removed: 41 | print(name + " was deleted") 42 | else: 43 | print(name + " was NOT found") 44 | elif menu_choice == 4: 45 | print("Lookup Contact") 46 | name = raw_input("Name: ") 47 | found = False 48 | for person in people : 49 | if person['name'] == name : 50 | print(person) 51 | found = True 52 | if not found: 53 | print(name + " was not found") 54 | 55 | elif menu_choice != 5: 56 | print_menu() -------------------------------------------------------------------------------- /projects/3_1/Solution/selectionsort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | DO IT! CHALLENGE - 3.1 Recursion 3 | 4 | SOLUTION 5 | ''' 6 | 7 | def sort(list, sort_by, startIndex = 0): 8 | if (startIndex >= len(list) - 1): 9 | return 10 | minIndex = startIndex 11 | for j in range(startIndex + 1, len(list)): 12 | if list[j][sort_by] < list[minIndex][sort_by]: 13 | minIndex = j 14 | temp = list[startIndex] 15 | list[startIndex] = list[minIndex] 16 | list[minIndex] = temp 17 | sort(list, sort_by, startIndex+1) 18 | 19 | -------------------------------------------------------------------------------- /projects/3_1/Solution/selectionsort.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beaucarnes/algorithms-in-motion/5bebbaa5308e0d51b578a3478dc677fa33cf518e/projects/3_1/Solution/selectionsort.pyc -------------------------------------------------------------------------------- /projects/3_1/challenge.txt: -------------------------------------------------------------------------------- 1 | DO IT! CHALLENGE - 3.1 Recursion 2 | 3 | Just like in challenge 2.2, you have to create a selection sort algorithm that sorts an array. This time, 4 | however, you must use recursion. In the iterative approach from challenge 2.2, there were two loops. 5 | That means there are two places you can use recursion. However, it is only required that you use 6 | recursion once to pass this challenge. The function should sort the people array from 'contactapp.py'. The 7 | algorithm should sort by 'name' or 'age', depending on what is passed in. To check, run 'contactapp.py' 8 | and verify that when you print contacts, the program accurately sorts list based on the given parameter. 9 | 10 | CHANGE THIS FILE 11 | /3.1/selectionsort.py 12 | 13 | RUN THIS FILE TO TEST 14 | /3.1/contactapp.py 15 | 16 | SOLUTION FILES 17 | /3.1/Solution/* 18 | (Don't open until you have tried the challenge yourself!) 19 | -------------------------------------------------------------------------------- /projects/3_1/contactapp.py: -------------------------------------------------------------------------------- 1 | ''' 2 | DO IT! CHALLENGE - 3.1 Recursion 3 | Do not modify this file. Create the recursive selection sort function in 'selectionsort.py'. 4 | To check your work, run this file and test if all the print function in the menu works correctly. 5 | ''' 6 | 7 | import selectionsort 8 | 9 | def print_menu(): 10 | print('1. Print Contacts') 11 | print('2. Add a Contact') 12 | print('3. Remove a Contact') 13 | print('4. Lookup a Contact') 14 | print('5. Quit') 15 | print('') 16 | 17 | people = [{'name' : 'Judah', 'age' : 2}, {'name' : 'Beau', 'age' : 33}, {'name' : 'Aditya', 'age' : 29}] 18 | 19 | menu_choice = 0 20 | print_menu() 21 | while menu_choice != 5: 22 | menu_choice = int(input("Type in a number (1-5): ")) 23 | if menu_choice == 1: 24 | sort_by = raw_input("Sort by name or age: ") 25 | while not(sort_by == 'name' or sort_by == 'age'): 26 | sort_by = raw_input("Must enter 'name' or 'age': ") 27 | selectionsort.sort(people, sort_by) 28 | for person in people: 29 | print(person) 30 | print('') 31 | elif menu_choice == 2: 32 | print("Add Contact") 33 | name = raw_input("Name: ") 34 | age = raw_input("Age: ") 35 | people.append({'name' : name, 'age' : int(age)}) 36 | elif menu_choice == 3: 37 | print("Remove Contact") 38 | name = raw_input("Name: ") 39 | removed = False 40 | for person in people : 41 | if person['name'] == name : 42 | people.remove(person) 43 | removed = True 44 | if removed: 45 | print(name + " was deleted") 46 | else: 47 | print(name + " was NOT found") 48 | elif menu_choice == 4: 49 | print("Lookup Contact") 50 | name = raw_input("Name: ") 51 | found = False 52 | for person in people : 53 | if person['name'] == name : 54 | print(person) 55 | found = True 56 | if not found: 57 | print(name + " was not found") 58 | 59 | elif menu_choice != 5: 60 | print_menu() -------------------------------------------------------------------------------- /projects/3_1/selectionsort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | DO IT! CHALLENGE - 3.1 Recursion 3 | Just like in challenge 2.2, you have to create a selection sort algorithm that sorts an array. This time, 4 | however, you must use recursion. In the iterative approach from challenge 2.2, there were two loops. 5 | That means there are two places you can use recursion. However, it is only required that you use 6 | recursion once to pass this challenge. The function should sort the people array from 'contactapp.py'. The 7 | algorithm should sort by 'name' or 'age', depending on what is passed in. To check, run 'contactapp.py' 8 | and verify that when you print contacts, the program accurately sorts list based on the given parameter. 9 | ''' 10 | 11 | def sort(list, sort_by): 12 | -------------------------------------------------------------------------------- /projects/4_2/Solution/contactapp.py: -------------------------------------------------------------------------------- 1 | # DO IT! CHALLENGE - 4.2 Quicksort 2 | 3 | import quicksort 4 | 5 | def print_menu(): 6 | print('1. Print Contacts') 7 | print('2. Add a Contact') 8 | print('3. Remove a Contact') 9 | print('4. Lookup a Contact') 10 | print('5. Quit') 11 | print('') 12 | 13 | people = [{'name' : 'Judah', 'age' : 2}, {'name' : 'Beau', 'age' : 33}, {'name' : 'Aditya', 'age' : 29}] 14 | 15 | menu_choice = 0 16 | print_menu() 17 | while menu_choice != 5: 18 | menu_choice = int(input("Type in a number (1-5): ")) 19 | if menu_choice == 1: 20 | sort_by = raw_input("Sort by name or age: ") 21 | while not(sort_by == 'name' or sort_by == 'age'): 22 | sort_by = raw_input("Must enter 'name' or 'age': ") 23 | sorted_people = quicksort.sort(people, sort_by) 24 | for person in sorted_people: 25 | print(person) 26 | print('') 27 | elif menu_choice == 2: 28 | print("Add Contact") 29 | name = raw_input("Name: ") 30 | age = raw_input("Age: ") 31 | people.append({'name' : name, 'age' : int(age)}) 32 | elif menu_choice == 3: 33 | print("Remove Contact") 34 | name = raw_input("Name: ") 35 | removed = False 36 | for person in people : 37 | if person['name'] == name : 38 | people.remove(person) 39 | removed = True 40 | if removed: 41 | print(name + " was deleted") 42 | else: 43 | print(name + " was NOT found") 44 | elif menu_choice == 4: 45 | print("Lookup Contact") 46 | name = raw_input("Name: ") 47 | found = False 48 | for person in people : 49 | if person['name'] == name : 50 | print(person) 51 | found = True 52 | if not found: 53 | print(name + " was not found") 54 | 55 | elif menu_choice != 5: 56 | print_menu() -------------------------------------------------------------------------------- /projects/4_2/Solution/quicksort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | DO IT! CHALLENGE - 4.2 Quicksort 3 | 4 | SOLUTION 5 | ''' 6 | 7 | def sort(list, sort_by): 8 | if len(list) < 2: 9 | return list 10 | else: 11 | pivot = list[0] 12 | less = [i for i in list[1:] if i[sort_by] <= pivot[sort_by]] 13 | greater = [i for i in list[1:] if i[sort_by] > pivot[sort_by]] 14 | return sort(less, sort_by) + [pivot] + sort(greater, sort_by) -------------------------------------------------------------------------------- /projects/4_2/Solution/quicksort.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beaucarnes/algorithms-in-motion/5bebbaa5308e0d51b578a3478dc677fa33cf518e/projects/4_2/Solution/quicksort.pyc -------------------------------------------------------------------------------- /projects/4_2/Solution/selectionsort.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beaucarnes/algorithms-in-motion/5bebbaa5308e0d51b578a3478dc677fa33cf518e/projects/4_2/Solution/selectionsort.pyc -------------------------------------------------------------------------------- /projects/4_2/challenge.txt: -------------------------------------------------------------------------------- 1 | DO IT! CHALLENGE - 4.2 Quicksort 2 | 3 | Now it's time to improve the sort algorithm! Implement the sort function below using quicksort. The 4 | function should sort the people array from 'contactapp.py'. The algorithm should sort by 'name' or 'age', 5 | depending on what is passed in. To check, run 'contactapp.py' and verify that when you print contacts, 6 | the program accurately sorts the list based on the given parameter. 7 | 8 | Note: To more closely align with the code shown in the video, this quicksort function should return 9 | a new sorted list instead of modifying the list passed in (like the previous challenges). 10 | 11 | CHANGE THIS FILE 12 | /4.2/quicksort.py 13 | 14 | RUN THIS FILE TO TEST 15 | /4.2/contactapp.py 16 | 17 | SOLUTION FILES 18 | /4.2/Solution/* 19 | (Don't open until you have tried the challenge yourself!) 20 | -------------------------------------------------------------------------------- /projects/4_2/contactapp.py: -------------------------------------------------------------------------------- 1 | ''' 2 | ASSIGNMENT - 4.2 Quicksort 3 | Do not modify this file. Create the quicksort function in 'quicksort.py'. 4 | To check your work, run this file and test if all the print function in the menu 5 | works correctly. 6 | ''' 7 | 8 | import quicksort 9 | 10 | def print_menu(): 11 | print('1. Print Contacts') 12 | print('2. Add a Contact') 13 | print('3. Remove a Contact') 14 | print('4. Lookup a Contact') 15 | print('5. Quit') 16 | print('') 17 | 18 | people = [{'name' : 'Judah', 'age' : 2}, {'name' : 'Beau', 'age' : 33}, {'name' : 'Aditya', 'age' : 29}] 19 | 20 | menu_choice = 0 21 | print_menu() 22 | while menu_choice != 5: 23 | menu_choice = int(input("Type in a number (1-5): ")) 24 | if menu_choice == 1: 25 | sort_by = raw_input("Sort by name or age: ") 26 | while not(sort_by == 'name' or sort_by == 'age'): 27 | sort_by = raw_input("Must enter 'name' or 'age': ") 28 | sorted_people = quicksort.sort(people, sort_by) 29 | for person in sorted_people: 30 | print(person) 31 | print('') 32 | elif menu_choice == 2: 33 | print("Add Contact") 34 | name = raw_input("Name: ") 35 | age = raw_input("Age: ") 36 | people.append({'name' : name, 'age' : int(age)}) 37 | elif menu_choice == 3: 38 | print("Remove Contact") 39 | name = raw_input("Name: ") 40 | removed = False 41 | for person in people : 42 | if person['name'] == name : 43 | people.remove(person) 44 | removed = True 45 | if removed: 46 | print(name + " was deleted") 47 | else: 48 | print(name + " was NOT found") 49 | elif menu_choice == 4: 50 | print("Lookup Contact") 51 | name = raw_input("Name: ") 52 | found = False 53 | for person in people : 54 | if person['name'] == name : 55 | print(person) 56 | found = True 57 | if not found: 58 | print(name + " was not found") 59 | 60 | elif menu_choice != 5: 61 | print_menu() -------------------------------------------------------------------------------- /projects/4_2/quicksort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | DO IT! CHALLENGE - 4.2 Quicksort 3 | Now it's time to improve the sort algorithm! Implement the sort function below using quicksort. The 4 | function should sort the people array from 'contactapp.py'. The algorithm should sort by 'name' or 'age', 5 | depending on what is passed in. To check, run 'contactapp.py' and verify that when you print contacts, 6 | the program accurately sorts the list based on the given parameter. 7 | 8 | Note: To more closely align with the code shown in the video, this quicksort function should return 9 | a new sorted list instead of modifying the list passed in (like the previous challenges). 10 | ''' 11 | 12 | def sort(list, sort_by): 13 | --------------------------------------------------------------------------------