Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions khudiakov/A1_components.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@

import sys
import threading



def main():

# read number of vertices
f = open('components.in')
first_string = f.readline().strip().split(' ')

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лучше делать .split() чем .split(' ')

n = int(first_string[0])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Видимо, вторым числом было количество рёбер, и оно наверное пригодилось бы, чтобы сделать дальнейший ввод проще


#read edges list
next_string = ' '
edges_list = []
inner_list = []
while next_string != ['']:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Очень сложное условие итерирования, можно было бы просто

for line in f:
    u, v = [int(x) for x in line.split()]
    edges_list.append((u, v))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вообще, надо стараться писать итерацию так, чтобы не писать один код дважды.

В этом цикле два дублированная: проверка next_string != [''] и присваивание inner_list = []

Присваивание можно было сделать один раз в начале цикла.

next_string = f.readline().strip().split(' ')
if next_string != ['']:
inner_list.append(int(next_string[0])-1)
inner_list.append(int(next_string[1])-1)
edges_list.append(inner_list)
inner_list = []
f.close()

# make full edges list with reverse edges
rev_edges_list = []

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вообще, это отлично переписывается через comprehension
rev_edges = [(v, u) for (u, v) in edges]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Кстати, вообще в питоне list и tuple почти одно и то же, но всё же тут логичнее использовать для рёбер tuple

for i in edges_list:
a = i[::-1]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

зачем тут эта переменная?

Можно было сразу написать rev_edges_list.append(i[::-1])

rev_edges_list.append(a)
full_edges_list = edges_list + rev_edges_list

#convert edges list to adjacency list
adjacency_list = []

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

опять же, comprehension

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Скажу поподробнее =)

Видимо, вначале тут был код adjecency_list = [[]] * n который не работает, потому что это n одинаковых списков. Правильно писать adjecency_list = [[] for _ in range(n)].

Просто для сравнения, матрицу из нулей удобно создавать так:

m = [[0] * n for _ in range(n)]


for i in range(n):
adjacency_list.append([])

for i in full_edges_list:
a = (i[0])
adjacency_list[a].append(i[1])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

загадочная индексация.

Проще так:

for edge in full_edges_list:
    u, v = edge
    adjacency_list[u].append(v)


#dfs
visited = [False] * n
comp_number = 0
components_list = [-1] * n

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нет необходимости хранить и visited и components_list, потому что visited[i] это то же самое, что и components[i] == -1


def dfs(v):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вообще это не очень хорошо -- объявлять большую функцию в середине огромной функции

components_list[v] = comp_number
visited[v] = True
for w in adjacency_list[v]:
if not visited[w]:
dfs(w)

#counting components
for v in range(n):
if not visited[v]:
dfs(v)
comp_number += 1


#write to file

ans = open('components.out', 'w')
ans.write(str(comp_number) + '\n')
for w in components_list:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Возможно лучше опять использовать comprehension =)

ans.write(' '.join(str(w + 1) for x in components_list))

ans.write(str(int(w) + 1) + ' ')

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int(w) == w?

ans.close()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вообще, main слишком огромная функция. Лучше сделать так

def read_input():
    ....
    return graph

def dfs(graph, v, components): # no global vars!
    ...

def find_components():
    ...
    return components

def print_answer():
    ....

def main():
    g = read_input()
    c = find_components()
    print_answer(c)



threading.stack_size(2 ** 26) # 64 MB stack size
sys.setrecursionlimit(1000000000) # recursion depth
thread = threading.Thread(target=main)
thread.start()
50 changes: 50 additions & 0 deletions khudiakov/A2_Shortest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

import sys
import threading

def main():

# read number of vertices
f = open('pathbge1.in')
v, e = (int(i) for i in f.readline().strip().split())

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.strip().split() эквивалентен .split()



#adjacency list
adjacency_list=[[] for i in range(v)]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍, только есть convention использовать _ вместо i если переменная не используется

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В смысле, for _ in range() ?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ога

for edge in f:
x, y = ((int(i) - 1) for i in edge.strip().split())
adjacency_list[x].append(y)
adjacency_list[y].append(x)

#bfs
visited = [False] * v
distance = [-1 for i in range(v)]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

опять же, достаточно только distance


def bfs(start, adjacency_list):
queue = [start]
visited[start] = True
distance[start] = 0 # distance from start vertex to current one
while len(queue) > 0:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while queue:


x = queue.pop(0)

for i in adjacency_list[x]:
if visited[i] == False:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if not visited[i]

Есть две вещи, которые не надо делать с booleanamи,:

if x == True:
if x:
    return True
else:
    return False

queue.append(i)
visited[i] = True
if distance[i] == -1:
distance[i] = distance[x] + 1
return distance

#write to file

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Каждый раз, когда чувствуется необходимость написать комментарий, лучше подумать, как бы переписать код так, чтобы он не был нужен.

В данном случае, #write to file намекает на необходимость функции def write_to_file(distances).

Коммент #bfs выше сигнализирует о том, что надо вынести bfs в отдельную глобальную функцию, и избавится от 'глобальных' переменных visited и distance


ans = open('pathbge1.out', 'w')
for w in bfs(0, adjacency_list):
ans.write(str(int(w)) + ' ')
ans.close()


threading.stack_size(2 ** 26) # 64 MB stack size
sys.setrecursionlimit(1000000000) # recursion depth

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Зачем, тут же нет рекурсии?

thread = threading.Thread(target=main)
thread.start()
45 changes: 45 additions & 0 deletions khudiakov/A3_Shortest_with_weight.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

import sys
sys.setrecursionlimit(1000000000)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

и тут не надо


#read number of vertices, star and stop points from file
file = open('pathmgep.in', 'r')

n, s, f = [int(i) for i in file.readline().split()]
s-= 1
f-= 1

#read weight matrix
path = []
for string in file.read().splitlines():
weight = [int(i) for i in string.split()]
path.append(weight)
file.close()

#mark nonexistent paths
for i in range(n):
for j in range(n):
if path[i][j] == -1:
path[i][j] = '-1'

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Строка '-1' это плохо -- её сложно отличить от числа -1. Если нужно специальное значение, то лучше использовать None.

А ещё лучше придумать, как сделать так, чтобы специальные значения не понадобились. В данном случае можно было вместо -1 использовать очень большое число(10**9, наример)


#may be slow but..
def FloydWarshall(path):
for k in range(n):
for i in range(n):
for j in range(n):
if path[i][j] != '-1'and path[i][k] != '-1'and path[k][j] != '-1':
path[i][j] = min(path[i][j], (path[i][k] + path[k][j]))
elif path[i][j] != '-1'and (path[i][k] == '-1'or path[k][j] == '-1'):
path[i][j] = path[i][j]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A is A

=)

Не нужно было рассматривать этот случай. Ну и если бы вместо -1 стояли бы бесконечности, то вообще не нужно было бы рассмотрение случаев

elif path[i][j] == '-1'and path[i][k] != '-1'and path[k][j] != '-1':
path[i][j] = path[i][k] + path[k][j]
else:
path[i][j] = '-1'
return path

FloydWarshall(path)


ans = open('pathmgep.out', 'w')
ans.write(str(path[s][f]))
ans.close()