def test_init(self): list_ = List(value=1, next_=List(value=2, next_=List(value=3))) self.assertEqual(list_.value, 1) self.assertEqual(list_.next_._value, 2) self.assertEqual(list_.next_.next_.value, 3) self.assertEqual(list_.next_.next_.next_, None)
def test1(self): l1 = List([1, 2, 3]) l2 = List([1, 2, 3]) expected = List([2, 4, 6]) actual = add_num_lists(l1, l2) self.assertEqual(expected, actual)
def test_append(self): list_ = List(value=1, next_=List(value=2, next_=List(value=3))) list_.append(4) self.assertEqual(list_.value, 1) self.assertEqual(list_.next_._value, 2) self.assertEqual(list_.next_.next_.value, 3) self.assertEqual(list_.next_.next_.next_.value, 4)
def test_iadd_list(self): list_ = List(value=1, next_=List(value=2, next_=List(value=3))) list_ += [5, 6] self.assertEqual(list_.value, 1) self.assertEqual(list_.next_._value, 2) self.assertEqual(list_.next_.next_.value, 3) self.assertEqual(list_.next_.next_.next_.value, 5) self.assertEqual(list_.next_.next_.next_.next_.value, 6) self.assertEqual(list_.next_.next_.next_.next_.next_, None)
def sort(array): if len(array) > 1: pivot = (min(array)+max(array))/2 left = List() right = List() equals = List() for x in array: if x < pivot: left.push(x) elif x > pivot: right.push(x) elif x == pivot: equals.push(x) return sort(left) + equals + sort(right) else: return array
def __ensure_capacity(self, min_capacity): """Ensures the number of possible positions in the hash table is at least as much as the number of nodes in the table. :param min_capacity: The minimum capacity required of the table. :return: None """ if len(self._table) >= min_capacity: return old_table = self._table new_capacity = int((len(self._table) * 3) / 2) + 1 if new_capacity < min_capacity: new_capacity = min_capacity # self._table = np.empty(new_capacity, dtype=object) self._table = [None] * new_capacity for i in range(0, new_capacity): self._table[i] = List() self._size = 0 for bucket in old_table: for node in bucket: self.insert(node.key, node.value)
def load_round(file_name, track): """Loads a round from resources. :param file_name: The filename to load. :param track: The track of the round to load. :return: All matches loaded from file. """ matches = List() with open(file_name, 'r') as the_file: header = True previous_lines = HashTable() for line in the_file: if handle_duplicates(file_name, previous_lines, line): continue if header: header = False continue csv = parse_csv_line(line) player_a = csv[0] score_a = int(csv[1]) player_b = csv[2] score_b = int(csv[3]) match = Match(track, player_a, score_a, player_b, score_b) matches.append(match) return matches
def select(self, index): """Finds the values of the node at the specified index. :param index: The position in this tree. :return: The node's values if found, otherwise None. """ if index < 0 or index >= self._size: raise ValueError('Index out of bounds') node = self._root while node is not None: size = node.left.size if node.left else 0 if index == size: return node.values if index < size: node = node.left else: index -= size + len(node.values) node = node.right return List()
def parse_csv_line(line): """Parses a CSV (comma separated values) line. :param line: The line to parse. :return: The array of values in this line. """ if line == '': # return np.empty(0) return [] values = List() value = '' quotes = False for character in line: if character == '\n': break elif character == '"': quotes = not quotes elif not quotes and character == ',': values.append(value.strip()) value = '' else: value += character values.append(value) return values.to_array()
def __init__(self, initial_capacity=10): # self._table = np.empty(initial_capacity, dtype=object) self._table = [None] * initial_capacity for i in range(0, initial_capacity): self._table[i] = List() self._size = 0
def __init__(self, key): self.key = key self.values = List() self.color = RED self.parent = None self.left = None self.right = None self.size = 1
def __init__(self, ordered_seasons=List(), seasons=HashTable(), men=HashTable(), women=HashTable(), tournament_types=HashTable(), ranking_points=List(), men_scoreboard=Tree(), women_scoreboard=Tree()): self.running = True self.seasons = seasons.clone() self.ordered_seasons = ordered_seasons.clone() self.current_season = self.ordered_seasons.last() self.men = men.clone() self.women = women.clone() self.tournament_types = tournament_types.clone() self.ranking_points = ranking_points.clone() self.men_scoreboard = men_scoreboard self.women_scoreboard = women_scoreboard
def test_iadd(self): list_ = List(value=1, next_=List(value=2, next_=List(value=3))) tail = List(value=5, next_=List(value=6)) list_ += tail self.assertEqual(list_.value, 1) self.assertEqual(list_.next_._value, 2) self.assertEqual(list_.next_.next_.value, 3) self.assertEqual(list_.next_.next_.next_.value, 5) self.assertEqual(list_.next_.next_.next_.next_.value, 6) self.assertEqual(list_.next_.next_.next_.next_.next_, None) tail._value = 0 self.assertEqual(list_.value, 1) self.assertEqual(list_.next_._value, 2) self.assertEqual(list_.next_.next_.value, 3) self.assertEqual(list_.next_.next_.next_.value, 5) self.assertEqual(list_.next_.next_.next_.next_.value, 6) self.assertEqual(list_.next_.next_.next_.next_.next_, None)
def sum_forward(lhs: List, rhs: List) -> List: reversed_lhs = List() reversed_rhs = List() current = lhs.head while current: reversed_lhs.insert(current.item) current = current.next current = rhs.head while current: reversed_rhs.insert(current.item) current = current.next reversed_total = sum_reverse(reversed_lhs, reversed_rhs) total = List() current = reversed_total.head while current: total.insert(current.item) current = current.next return total
def __run_back(self, x): """Continues appending to the front of the run if still running in reverse. Otherwise changes state to start creating forwards runs. :param x: The element to append to the run. :return: None """ if self._compare(x, self._previous) > 0: self._runs.insert(len(self._run), self._run) self._run = List() self._run.append(x) self._previous = x self.consume = self.__run_single else: self._run.append_front(x) self._previous = x
def sum_reverse(lhs: List, rhs: List) -> List: lhs_current = lhs.head rhs_current = rhs.head total = [] overflow = 0 while lhs_current and rhs_current: place_total = lhs_current.item + rhs_current.item + overflow if place_total >= 10: overflow = place_total // 10 place_total -= 10 else: overflow = 0 total.append(place_total) lhs_current = lhs_current.next rhs_current = rhs_current.next # Handle spots where only one side has a value current = None if lhs_current: current = lhs_current else: current = rhs_current while current: place_total = current.item + overflow if place_total >= 10: overflow = place_total // 10 place_total -= 10 else: overflow = 0 total.append(place_total) current = current.next # Handle case where result is larger in number of places than either list if overflow: total.append(overflow) result = List() for item in reversed(total): result.insert(item) return result
def __init__(self, player, season: SeasonStats, round_achieved=1, multiplier=1.0, points=0.0, wins=0, losses=0, scores=HashTable(), opponent_scores=List()): self.player = player self.season = season self.round_achieved = round_achieved self.multiplier = multiplier self.points = points self.wins = wins self.losses = losses self.scores = scores.clone() # <score, count> self.opponent_scores = opponent_scores.clone()
def add_num_lists(l1, l2): n1 = l1.head n2 = l2.head carry = 0 result = List() while n1 != None and n2 != None: value = n1.data + n2.data + carry result.add(value % 10) carry = int(value / 10) n1 = n1.next n2 = n2.next rest = n1 if n1 != None else n2 while rest != None: value = rest.data + carry result.add(value % 10) carry = int(value / 10) rest = rest.next if carry != 0: result.add(carry) return result
def sort(self): """Collects all runs and iteratively merges each, smallest first. :return: The sorted array. """ # Collect the final run. self._runs.insert(len(self._run), self._run) self._run = List() self.consume = self.__run_init # Iteratively merge each of the runs, smallest first. while len(self._runs) > 1: new_runs = Tree() iterator = iter(self._runs) run_a = next_run(iterator) run_b = next_run(iterator) while run_a is not None and run_b is not None: merged = self._merge(run_a, run_b) new_runs.insert(len(merged), merged) run_a = next_run(iterator) run_b = next_run(iterator) if run_a is not None: new_runs.insert(len(run_a), run_a) self._runs = new_runs sorted_run = next_run(iter(self._runs)) # Convert the run to an array if currently a linked list. if isinstance(sorted_run, List): sorted_run = sorted_run.to_array() # Return the final sorted run. return sorted_run
def list_vs_tree_vs_hash(): print('-' * 120) print( 'Pitting lists, trees and hash tables against each other for search.') print( 'Hashing is expected to be the fastest, followed by trees, then by lists.' ) print('All player statistics use hash tables for indexing.') print('Lists = Sequential search, average O(n)') print('Trees = Binary search, average O(log n)') print('Hash Tables = Hashing, average O(1)') print('-' * 120) linked_list = List() tree = Tree() hash_table = HashTable() for i in range(0, 5000): value = random.randint(0, 5000) linked_list.append(value) tree.insert(value, True) hash_table.insert(value, True) list_search(linked_list) tree_search(tree) hash_search(hash_table) prompt_next()
def create_track(self, tournament, gender): """Creates a new track for a given tournament and gender. Starts off with an empty scoreboard and mappings for the player stats. :param tournament: The tournament to create the track for. :param gender: The gender of the track to create. :return: The newly created track. """ stats = HashTable() for player_name, player_profile in self.circuit.get_players(gender): season_stats: SeasonStats = self.get_stats(gender).find( player_name) tournament_stats = TournamentStats(player_profile, season_stats) season_stats.tournament_stats.insert(tournament.type.name, tournament_stats) stats.insert(player_name, tournament_stats) winning_score = get_winning_score(gender) forfeit_score = get_forfeit_score(gender) previous_stats = None previous_season_scoreboard = None if tournament.previous is not None: previous_stats = tournament.previous.get_track(gender).stats previous_season_scoreboard = tournament.previous.season.get_scoreboard( gender) track_round = 1 remaining = stats.clone() scoreboard = List() return Track(gender, track_round, stats, remaining, winning_score, forfeit_score, scoreboard, previous_stats, previous_season_scoreboard)
for value, count in seen.items(): while count > 1: a_linked.delete(value) count -= 1 # O(n^2) def remove_dups_no_buffer(a_linked: List) -> None: current = a_linked.head # O(n) while current.next: searcher = a_linked.head while searcher: # O(2n = n) if searcher.item == current.item and searcher != current: a_linked.delete(searcher.item) # O(n) break searcher = searcher.next current = current.next if __name__ == '__main__': x = List([4, 2, 4, 4, 3, 1, 1, 1, 1, 2, 3, 4, 0, -1]) print(x) remove_dups(x) print(x) y = List([4, 2, 4, 4, 3, 1, 1, 1, 1, 2, 3, 4, 0, -1]) print(y) remove_dups_no_buffer(y) print(y)
def to_list(self, n): l = List() for i in map(int, reversed(str(n))): l.add(i) return l
node_before_partition_node = a_list.find_prev_node(partition_item) partition_node = None if not node_before_partition_node: partition_node = a_list.search(partition_item) if not partition_node: return else: partition_node = node_before_partition_node.next print("Node before partition: " + str(node_before_partition_node)) less_than_partition = a_list.find_node_less_than(partition_item, partition_node) print("< partition: " + str(less_than_partition)) while less_than_partition: a_list.delete_node(less_than_partition) print(a_list) a_list.insert_before(less_than_partition.item, partition_node) less_than_partition = a_list.find_node_less_than( partition_item, partition_node) print("< partition: " + str(less_than_partition)) if __name__ == '__main__': x = List([5, 2, 3, 6, 9, 0, 1]) print(x) partition(x, 6) print(x)
# linked list, given only access to that node. # Input: node c from linked list a -> b -> c -> d -> e -> f # Result: nothing is returned, but the new linked list looks like a -> b -> d -> e -> f from linked_list import List, Node # O(n) def delete_node(a_list: List, target: Node) -> None: if len(a_list) <= 2: return prev_node = a_list.head current_node = prev_node.next # O (n) while current_node.next: if current_node == target: prev_node.next = target.next a_list.size -= 1 return prev_node = current_node current_node = current_node.next if __name__ == '__main__': x = List([1, 2, 3, 4]) print(x) n = x.head.next delete_node(x, n) print(x)
# on reference, not value. That is, if the kth node of the first linked list # is the exact same node (by reference) as the jth node of the second linked # list, then they are intersecting from linked_list import List, Node # O(n^2) def intersection(lhs: List, rhs: List) -> Node: lhs_current = lhs.head while lhs_current: rhs_current = rhs.head while rhs_current: if lhs_current == rhs_current: return lhs_current rhs_current = rhs_current.next lhs_current = lhs_current.next if __name__ == '__main__': x = List([1, 2, 3, 4]) n = Node() n.item = 17 n.next = x.head.next x.insert_node(n) y = List([5, 6, 7]) y.insert_node(n, y.head.next.next) print(x) print(y) print(intersection(x, y))
# Output: C from linked_list import List, Node # O(n) def find_loop(a_list: List) -> Node: found = {} current = a_list.head while current: if found.get(current, False): return current else: found[current] = True current = current.next return None if __name__ == '__main__': x = List(['A', 'B', 'C', 'D', 'E']) n = x.head.next.next x.insert_node(n, prev_node=x.last_node()) print(n) print(x) y = List('f') print(find_loop(x)) print(find_loop(y))
def play_round(self, track: Track): """Plays a round in the tournament for a track. :param track: The track that is playing this round. """ if track.round > MAX_ROUNDS: print('This track is already complete') return print('Playing the %s\'s track' % track.name) winners = HashTable() winner = None matches = List() track.update_previous_winners() if self.previous is not None and next_bool( 'Should we seed the round for you?', True): if track.round == 1: self.seed_automatic_first(track, matches) else: self.seed_automatic_next(track, matches) else: input_type = next_input_type('How should data be entered?') if input_type == FILE: matches = self.seed_file(track) else: self.seed_manual(track, matches) # Run each match. for match in matches: # Find the winner and add them to the next batch. winner, winner_score, loser, loser_score = match.run( track.winning_score, track.remaining) winners.insert(winner.player.name, winner) winner: TournamentStats = winner loser: TournamentStats = loser # Update the winner profile. winner.win() winner.add_score(winner_score, loser_score) # Update the loser profile. loser.loss() loser.add_score(loser_score, winner_score) apply_multiplier(track.name, winner, loser_score) self.update_points(loser, track) if track.round == MAX_ROUNDS: print('Tournament %s successfully complete for the %s\'s track' % (self.type.name, track.name)) print('Winner for the final round: %s' % winner.player.name) track.round += 1 self.update_points(winner, track) self.print_scoreboard(track.name) return print('Winners for round %d:' % track.round) for name, stats in winners: print('- %s' % name) track.remaining = winners track.round += 1
def test_value(self): list_ = List(value=1, next_=List(value=2)) self.assertEqual(list_.value, 1) list_._value = 3 self.assertEqual(list_.value, 3)
while current: reversed_lhs.insert(current.item) current = current.next current = rhs.head while current: reversed_rhs.insert(current.item) current = current.next reversed_total = sum_reverse(reversed_lhs, reversed_rhs) total = List() current = reversed_total.head while current: total.insert(current.item) current = current.next return total if __name__ == '__main__': x = List([2, 9, 2]) # 617 y = List([2, 9, 2]) # 295 print(x) print(y) print(sum_reverse(x, y)) # 912 x = List([7, 1, 6]) # 617 y = List([5, 9, 2]) # 295 print(x) print(y) print(sum_forward(x, y)) # 912