"params": { "bitonic_array": [-3, 9, 18, 20, 17, 5, 1], "value": 20 }, "expected": True }, "test_1": { "params": { "bitonic_array": [5, 6, 7, 8, 9, 10, 3, 2, 1], "value": 30 }, "expected": False }, "test_2": { "params": { "bitonic_array": [1, 2, 3, 1], "value": 2 }, "expected": True }, "test_3": { "params": { "bitonic_array": [23, 24, 69, 100, 99, 79, 78, 67, 36, 26, 19], "value": 67 }, "expected": True } } dynamically_generate_tests(functionality_test_data, optimal, timed=True) run_dynamic_tests()
def source_and_target_not_at_edges(n, m, source, target) -> bool: source_row, source_col = source target_row, target_column = target return (source_row, source_col) != (0, 0) and \ (target_row, target_column) != (n - 1, m - 1) def get_sub_grid_from_source_to_target(n, m, source, target) -> tuple: source_row: int = source[0] target_column: int = target[1] n_from_source_to_target: int = n - source_row m_from_source_to_target: int = m - target_column return n_from_source_to_target, m_from_source_to_target def get_neighbors(n, m, row, col) -> list: right: tuple = (row, col + 1) down: tuple = (row + 1, col) potential_neighbors: list = [right, down] actual_neighbors: list = [] for n_row, n_col in potential_neighbors: if not n_row > (n - 1) and \ not n_col > (m - 1): actual_neighbors.append((n_row, n_col)) return actual_neighbors if __name__ == '__main__': dynamically_generate_tests(time_complexity_test_data, optimal, timed=True) run_dynamic_tests()
return if self.tree_sizes[root_of_p] < self.tree_sizes[root_of_q]: # O(1) self.roots[root_of_p] = root_of_q self.tree_sizes[root_of_q] += self.tree_sizes[root_of_p] else: # O(1) self.roots[root_of_q] = root_of_p self.tree_sizes[root_of_p] += self.tree_sizes[root_of_p] def __get_root(self, node: int): # O(log(n)) while node != self.roots[node]: self.__compress_path(node) node = self.roots[node] return node def __compress_path(self, node: int): # Set node to point to it's grandparent self.roots[node] = self.roots[self.roots[node]] def __log_union_state(self, p: int, q: int): print(f"union({p}, {q})") print([index for index in range(len(self.roots))]) print(self.roots) def __log_connected_state(self, p: int, q: int): print(f"connected({p}, {q})") print(self.roots[p] == self.roots[q]) if __name__ == '__main__': dynamically_generate_tests(union_find_functionality_test_data, union_find_client, timed=True) run_dynamic_tests()
for k in numbers: if i + j + k == value: return i, j, k return -1, -1, -1 def optimal(numbers: list, value: int) -> tuple: # O(n^2) -> ~ n^2 hashed_numbers: dict = {} for number in numbers: hashed_numbers[number] = number for i in numbers: for j in numbers: difference: int = value - (i + j) if difference in hashed_numbers: return i, j, hashed_numbers[difference] return -1, -1, -1 if __name__ == '__main__': functionality_test_data: dict = { "test_0": { "params": { "numbers": [1, 2, 3, 4, 5, 6, 7, 8], "value": 11 }, "expected": (1, 2, 8) } } dynamically_generate_tests(functionality_test_data, optimal) run_dynamic_tests()
from test_utilities.dynamic_test_creator import \ run_dynamic_tests, dynamically_generate_tests from week_0.union_find.test_resources.social_network_connectivity_functionality_test_data import \ social_network_connectivity_functionality_test_data def earliest_network_was_connected_fully(connections: list, friends: int) -> int: # O(m*log(n)) """ 1. connect m[i].friend_1 with m[i].friend_2 2. update max_tree_size variable which keeps track of the largest tree in the graph 3. if max_tree_size() equals n, then return m[0].time, else continue looping through m. this algorithm takes m iterations at worst with log(n) work in each iteration, therefore O(m*log(n)) """ facebook_connector = FacebookFriendConnector(friends) for connection in connections: # O(m) facebook_connector.union(connection.friend_1, connection.friend_2) # O(log(n) if facebook_connector.all_connected(): # O(1) return connection.time_of_connection return -1 if __name__ == '__main__': dynamically_generate_tests( social_network_connectivity_functionality_test_data, earliest_network_was_connected_fully, timed=True) run_dynamic_tests()
def grid_traversal(row: int, column: int) -> int: if row == 0 or column == 0: return 0 elif row == 1 or column == 1: return 1 else: right_path_traversals: int = grid_traversal(row, column - 1) down_path_traversals: int = grid_traversal(row - 1, column) return right_path_traversals + down_path_traversals if not source_and_target_at_edges(n, m, source, target): source_row: int = source[0] target_column: int = target[1] n_from_source_to_target: int = n - source_row m_from_source_to_target: int = m - target_column return grid_traversal(n_from_source_to_target, m_from_source_to_target) else: return grid_traversal(n, m) def source_and_target_at_edges(n, m, source, target) -> bool: source_row, source_col = source target_row, target_column = target return (source_row, source_col) == (0, 0) and \ (target_row, target_column) == (n - 1, m - 1) if __name__ == '__main__': dynamically_generate_tests(functionality_test_data, brute_force) run_dynamic_tests()
else: # O(1) self.roots[root_of_q] = root_of_p self.tree_sizes[root_of_p] += self.tree_sizes[root_of_p] self.successor_roots[root_of_p] = self.successor_roots[root_of_q] # Successor mod def __get_root(self, node: int): # O(log(n)) while node != self.roots[node]: self.__compress_path(node) node = self.roots[node] return node def __compress_path(self, node: int): # Set node to point to it's grandparent self.roots[node] = self.roots[self.roots[node]] def __log_union_state(self, p: int, q: int): print(f"union({p}, {q})") print(f"Index: {[index for index in range(len(self.roots))]}") print(f"Roots: {self.roots}") print(f"Tree Sizes: {self.tree_sizes}") def __log_connected_state(self, p: int, q: int): print(f"connected({p}, {q})") print(self.roots[p] == self.roots[q]) if __name__ == '__main__': dynamically_generate_tests( union_find_with_successor_and_delete_functionality_test_data, successor_with_delete_client, timed=True) run_dynamic_tests()