Reputation: 11
I am doing this assignment, https://open.kattis.com/problems/borg?editresubmit=14545391, and my code solves the problem. I've researched other peoples solutions and it seems like I do what other people have done when solving this.
The problem is that my algorithm is too slow and I've been trying to optimize the code for a few hours but I realize I don't know enough about Pythons methods to know which are slow and what I should do instead and at this point I probely cause more harm than good when changing the code.
I could implement a faster sorting algorithm but since there's not that many elements to sort I don't think that will make much difference. My suspision is that the kruskal method could be improved but I don't have a clue where to start.
I've added a return to the bfs so that it stops when all aliens are found.
I've modified the first loop where I get the input for the maze so that I collect all the data that I need instead or relooping the mazes.
test_cases = int(input())
mazes = []
nodes_in_mazes = []
number_of_nodes_in_maze = []
for i in range(test_cases):
maze = []
rows = int(input().split()[1])
start = ()
aliens = []
for r in range(rows):
input_row = input()
if 'S' in input_row:
start = (r, input_row.index('S'))
if 'A' in input_row:
for char_index, char in enumerate(input_row):
if char == 'A':
aliens.append((r, char_index))
maze.append(input_row)
mazes.append(maze)
nodes_found = [start]
for alien in aliens:
nodes_found.append(alien)
nodes_in_mazes.append(nodes_found)
number_of_nodes_in_maze.append(len(nodes_found))
offsets = [[-1, 0], [0, -1], [1, 0], [0, 1]]
w_and_d_for_mazes = []
def bfs(origin, maze_nbr, alien_nodes):
queue = [(origin[0], origin[1])]
weight_and_distance = []
visited_nodes = [(origin[0], origin[1])]
in_queue = len(queue)
weight = 1
alien_counter = 0
while not len(queue) == 0:
current_square = queue.pop(0)
for off in offsets:
i = current_square[0] + off[0]
j = current_square[1] + off[1]
square = mazes[maze_nbr][i][j]
if square != '#' and (i, j) not in visited_nodes:
queue.append((i, j))
visited_nodes.append((i, j))
if (i, j) in alien_nodes:
weight_and_distance.append((weight, nodes_in_mazes[maze_nbr].index((origin[0], origin[1])),
nodes_in_mazes[maze_nbr].index((i, j))))
alien_counter += 1
if alien_counter == number_of_nodes_in_maze[maze_nbr] - 1:
return weight_and_distance
in_queue -= 1
if in_queue == 0:
weight += 1
in_queue = len(queue)
return weight_and_distance
for i in range(len(nodes_in_mazes)):
alien_nodes = nodes_in_mazes[i].copy()
alien_nodes.pop(0)
maze_w_and_d = []
for tupp in bfs(nodes_in_mazes[i][0], i, alien_nodes):
maze_w_and_d.append(tupp)
aliens_to_be_found = len(alien_nodes)
while len(alien_nodes) != 0:
for tupp in bfs(alien_nodes.pop(0), i, alien_nodes):
maze_w_and_d.append(tupp)
maze_w_and_d.sort()
w_and_d_for_mazes.append(maze_w_and_d)
def find(p, i_find):
if p[i_find] != i_find:
p[i_find] = find(p, p[i_find])
return p[i_find]
def union(p, ra, x, y):
if ra[x] < ra[y]:
p[x] = y
elif ra[x] > ra[y]:
p[y] = x
else:
p[y] = x
ra[x] += 1
def kruskal(nodes, length):
result = []
ind = 0
e = 0
p = []
rank = []
minimum = 0
for node in range(number_of_nodes_in_maze[length]):
p.append(node)
rank.append(0)
while e < len(p) - 1:
w, u, v = nodes[ind]
ind = ind + 1
x = find(p, u)
y = find(p, v)
if x != y:
e = e + 1
result.append([w, u, v])
union(p, rank, x, y)
minimum += w
print(minimum)
for index, m in enumerate(w_and_d_for_mazes):
kruskal(m, index)
Upvotes: 1
Views: 64