Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
21f6377
B-1 (allvectors): hack version, using binary numbers.
LankyCyril Apr 10, 2014
8f5fb4d
B-1 (allvectors): proper version, using generators.
LankyCyril Apr 10, 2014
cba3bd7
B-2 (vectors): hack version, using binary numbers.
LankyCyril Apr 10, 2014
216ee4a
B-2 (vectors): proper version, using recursive generators.
LankyCyril Apr 10, 2014
6199725
B-3 (permutations) with recursive generators.
LankyCyril Apr 10, 2014
2d71062
Removed redundant str() conversion.
LankyCyril Apr 10, 2014
8e30325
B-4 (choose).
LankyCyril Apr 10, 2014
c8d8ed7
Moved generator call out of the with block.
LankyCyril Apr 10, 2014
f562ade
Moved generator call out of the with block.
LankyCyril Apr 10, 2014
b78cd74
B-5 (subsets).
LankyCyril Apr 10, 2014
d7a226c
B-6 (nextvector).
LankyCyril Apr 10, 2014
e2a12a1
Comments.
LankyCyril Apr 10, 2014
49d5ae8
B-7 (slow version, yields "Time limit exceeded (test 5)").
LankyCyril Apr 11, 2014
184a0a2
A-1 (components).
LankyCyril Apr 12, 2014
47b5f01
Refactoring and comments.
LankyCyril Apr 12, 2014
89bc494
Refactored version.
LankyCyril Apr 12, 2014
dc69a82
Comments, refactoring.
LankyCyril Apr 12, 2014
6a69ac7
A-5 (pathsg).
LankyCyril Apr 12, 2014
91ccc63
Changed all instances of join([comprehension]) into join(comprehension).
LankyCyril Apr 12, 2014
3dcb227
Vectors are traversed backwards in neighbor(), no need to inverse the…
LankyCyril Apr 12, 2014
51858a6
B-7 (nextperm) using factoradic / Lehmer code. Still too slow for PCMS2.
LankyCyril Apr 13, 2014
62ee83d
Comparing numbers instead of symbols/strings.
LankyCyril Apr 15, 2014
eefb8c2
B-7 (nextperm). Fast version, accepted by PCMS2!
LankyCyril Apr 15, 2014
d366a1c
Removed unused imports.
LankyCyril Apr 15, 2014
264508c
B-8 (nextchoose).
LankyCyril Apr 15, 2014
2042e55
Style fix.
LankyCyril Apr 15, 2014
1975b78
s/xrange/range/g
LankyCyril Apr 19, 2014
0ebe9a6
Solutions to the regression task (#3).
LankyCyril May 2, 2014
3d01265
C-1 that is too slow.
LankyCyril May 3, 2014
40e28b1
Ugly, but accepted by PCMS.
LankyCyril May 3, 2014
e9cb58c
Fast version de-uglified.
LankyCyril May 3, 2014
dce3567
Towers.
LankyCyril May 4, 2014
2a9b1d4
Harddrive.
LankyCyril May 5, 2014
c1cb2f5
airplane
LankyCyril May 7, 2014
d03150b
Maxpiece.
LankyCyril Jun 5, 2014
1ce53da
Olympic.
LankyCyril Jun 6, 2014
87f8d42
Final classification task.
LankyCyril Jun 6, 2014
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
68 changes: 68 additions & 0 deletions grigorev/A-1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/python
from __future__ import division
import sys
from collections import deque


""" Reads input line per line. Expects first line to contain the number of """
""" vertices and edges, all following lines are edges in format (u, v). """
""" Returns an adjacency list (actually a dictionary). """
def adjacencyListFromData(inputData):
# catch-all record
graph = lambda: None
# (V)ertices, (E)dges
[graph.V, graph.E] = [int(x) for x in inputData[0].split()]
# preload adjacency list
graph.body = {
vertex: []
for vertex in xrange(1, graph.V + 1)
}
# parse input
for edgeDescription in inputData[1:]:
# undirected graph, draw edges both ways
[start, end] = [int(x) for x in edgeDescription.split()]
graph.body[start].append(end )
graph.body[end ].append(start)
return graph


""" Perform a depth-first search on a graph. """
""" Return "components" (a dictionary of following structure): """
""" key = vertex """
""" value = number of component to which it belongs """
def depthFirstSearch(graph):
components = {}
currentComponent = 0
# NB! vertices start from 1 and go up to V inclusive
for vertex in range(1, graph.V + 1):
# if we haven't yet visited this vertex
if vertex not in components:
# it's a new component
currentComponent += 1
components[vertex] = currentComponent
# put it into the queue, as Fedor taught
queue = deque([vertex])
# queue up its immediate neighbors
while len(queue) > 0:
for neighbor in graph.body[queue[0]]:
# if we haven't yet visited the neighbor
if neighbor not in components:
# it's connected, so it's the same component
components[neighbor] = currentComponent
queue.append(neighbor)
queue.popleft()
return components


def main():
# using sys.std* handles for ease of local debugging
sys.stdin = open("components.in", "r")
sys.stdout = open("components.out", "w")
graph = adjacencyListFromData(sys.stdin.readlines())
components = depthFirstSearch(graph)
# number of components
print(max(components.values()))
# what vertex belongs where
print(" ".join(str(x) for x in components.values()))

main()
58 changes: 58 additions & 0 deletions grigorev/A-2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/python
from __future__ import division
import sys
from collections import deque

""" Reads input line per line. Expects first line to contain the number of """
""" vertices and edges, all following lines are edges in format (u, v). """
""" Returns an adjacency list (actually a dictionary). """
def adjacencyListFromData(inputData):
# catch-all record
graph = lambda: None
# (V)ertices, (E)dges
[graph.V, graph.E] = [int(x) for x in inputData[0].split()]
# preload adjacency list
graph.body = {
vertex: []
for vertex in xrange(1, graph.V + 1)
}
# parse input
for edgeDescription in inputData[1:]:
# undirected graph, draw edges both ways
[start, end] = [int(x) for x in edgeDescription.split()]
graph.body[start].append(end )
graph.body[end ].append(start)
return graph


""" Perform a breadth-first search on a graph. """
""" Return "distances" (a dictionary of following structure): """
""" key = vertex """
""" value = distance from startVertex """
def breadthFirstSearch(graph, startVertex):
# start lookup from the initial vertex
queue = deque([startVertex])
distances = {startVertex: 0}
# all edges are explicitly the same length (BFS won't work otherwise)
edgeLength = 1
# while there's still vertices to process
while len(queue):
# look up neighbors of current vertex
for neighbor in graph.body[queue[0]]:
# if we haven't visited the neighbor yet
if neighbor not in distances:
distances[neighbor] = distances[queue[0]] + edgeLength
queue.append(neighbor)
queue.popleft()
return distances


def main():
# using sys.std* handles for ease of local debugging
sys.stdin = open("pathbge1.in", "r")
sys.stdout = open("pathbge1.out", "w")
graph = adjacencyListFromData(sys.stdin.readlines())
distances = breadthFirstSearch(graph, 1)
print(" ".join(str(x) for x in distances.values()))

main()
94 changes: 94 additions & 0 deletions grigorev/A-3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/python
from __future__ import division
import sys
from collections import deque

""" Expects input as space-separated incidence matrix. Converts str to int. """
def incidenceMatrixFromData(inputData):
graph = lambda: None
graph.body = [
[int(x) for x in line.split()]
for line in inputData
]
graph.V = len(graph.body)
graph.E = None
return graph

""" Find weight of the shortest path from vertex "start" to vertex "finish" """
""" using Dijkstra's algorightm. """
""" Weights of paths are stored in the dictionary "distances" of structure: """
""" key = vertex """
""" value = distance from "start" """
""" Finishes as soon as distance is found for "finish". Returns one value. """
""" If no path found (i.e. all cycles passed without returning a value), """
""" returns -1. """
def dijkstra(graph, start, finish):
# begin lookup from "start"
distances = {
vertex: None
for vertex in xrange(graph.V)
}
distances[start] = 0
# keep track of visited vertices
visited = {
vertex: False
for vertex in xrange(graph.V)
}
# while there are unvisited vertices
while visited.values().count(False):
# find an unvisited vertex with a smallest tentative distance
indices = [ # indices of unvisited vertices
index
for (index, value) in visited.iteritems()
if not value
]
distancesToConsider = [ # distances of edges leading to these unvisited vertices
distance
for (index, distance) in distances.iteritems()
if (index in indices)
]
# if there's no more distances to consider, we've hit a brick wall
if distancesToConsider.count(None) == len(distancesToConsider):
break
# otherwise, find the next vertex to process
vertex = indices[
distancesToConsider.index(
min([
x for x in distancesToConsider
if x != None
])
)
]
# to prevent looping onto itself, do this before proceedin
visited[vertex] = True
# relax all immediate edges leading to unvisited vertices
for (neighbor, weight) in enumerate(graph.body[vertex]):
if weight >= 0:
if not visited[neighbor]:
# if there's a value that's been assigned during a previous iteration
if distances[neighbor]:
distances[neighbor] = min(
distances[vertex] + weight,
distances[neighbor]
)
else:
distances[neighbor] = (
distances[vertex] + weight
)
# if finish vertex has been reached already
if vertex == finish:
return distances[finish]
# if we haven't reached the finish vertex at all
return -1


def main():
# using sys.std* handles for ease of local debugging
sys.stdin = open("pathmgep.in", "r")
sys.stdout = open("pathmgep.out", "w")
inputData = sys.stdin.readlines()
[_, S, F] = [int(x)-1 for x in inputData[0].split()]
graph = incidenceMatrixFromData(inputData[1:])
print(dijkstra(graph, S, F))

main()
69 changes: 69 additions & 0 deletions grigorev/A-5.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/python
from __future__ import division
import sys
from collections import deque

""" Reads input line per line. Expects first line to contain the number of """
""" vertices and edges, all following lines are edges in format (u, v, w). """
""" Returns an adjacency list (actually a dictionary) of structure: """
""" key = vertex """
""" value = dict(neighbor, weight(vertex, neighbor)) """
def adjacencyListFromData(inputData):
# catch-all record
graph = lambda: None
# (V)ertices, (E)dges
[graph.V, graph.E] = [int(x) for x in inputData[0].split()]
# preinitialize adjacency list
graph.body = {
vertex: {}
for vertex in range(graph.V)
}
# parse input
for edgeDescription in inputData[1:]:
# NB! convert vertex numbers to 0 through V-1
[start, end, weight] = [int(x) for x in edgeDescription.split()]
graph.body[start-1][end-1] = weight
return graph


""" Returns initial approximation of distances. """
def initializeDistanceMatrix(graph):
# arbitrary infinity == 1e1000
distances = [[1e1000] * graph.V for _ in range(graph.V)]
# self-loops of zero length
for vertex in range(graph.V):
distances[vertex][vertex] = 0
# first approximation of distances between immediate neighbors
for start in range(graph.V):
for finish, weight in graph.body[start].iteritems():
distances[start][finish] = weight
return distances


""" Relax edges while possible, return resulting distance list. """
def floydWarshall(distances, graph):
for through in range(graph.V):
for start in range(graph.V):
for finish in range(graph.V):
if distances[start][finish]:
distances[start][finish] = min(
distances[start][finish],
distances[start][through] + distances[through][finish]
)
return distances


def main():
# using sys.std* handles for ease of local debugging
sys.stdin = open("pathsg.in", "r")
sys.stdout = open("pathsg.out", "w")
graph = adjacencyListFromData(sys.stdin.readlines())
distances = initializeDistanceMatrix(graph)
distances = floydWarshall(distances, graph)
for line in distances:
print(" ".join(
str(x)
for x in line
))

main()
22 changes: 22 additions & 0 deletions grigorev/B-1-proper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/python

def generator(subsequence, symbols, length):
if len(subsequence) < length:
for symbol in symbols:
for sequence in generator(subsequence + [symbol], symbols, length):
yield sequence
else:
yield subsequence

with open("allvectors.in", "r") as infile:
n = int(infile.readline().strip())

sequences = generator(
subsequence = [],
symbols = ["0", "1"],
length = n
)

with open("allvectors.out", "w") as outfile:
for sequence in sequences:
outfile.write("".join(sequence) + "\n")
9 changes: 9 additions & 0 deletions grigorev/B-1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/python

with open("allvectors.in", "r") as infile:
n = int(infile.readline().strip())

with open("allvectors.out", "w") as outfile:
for x in xrange(2**n):
s = bin(x).split("b")[1]
outfile.write("0" * (n-len(s)) + s + "\n")
25 changes: 25 additions & 0 deletions grigorev/B-2-proper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/python

def generator(subsequence, symbols, length):
if len(subsequence) < length:
for symbol in symbols:
if symbol == "1" and len(subsequence) > 0 and subsequence[-1] == "1":
continue
for sequence in generator(subsequence + [symbol], symbols, length):
yield sequence
else:
yield subsequence

with open("vectors.in", "r") as infile:
n = int(infile.readline().strip())

sequences = list(generator(
subsequence = [],
symbols = ["0", "1"],
length = n
))

with open("vectors.out", "w") as outfile:
outfile.write(str(len(sequences)) + "\n")
for sequence in sequences:
outfile.write("".join(sequence) + "\n")
15 changes: 15 additions & 0 deletions grigorev/B-2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/python

with open("vectors.in", "r") as infile:
n = int(infile.readline().strip())

vectors = [
bin(x).split("b")[1]
for x in xrange(2**n)
if bin(x).count("11") == 0
]

with open("vectors.out", "w") as outfile:
outfile.write(str(len(vectors)) + "\n")
for vector in vectors:
outfile.write("0" * (n - len(vector)) + vector + "\n")
24 changes: 24 additions & 0 deletions grigorev/B-3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/python
from __future__ import division

def generator(subsequence, symbols):
complete = True
for symbol in symbols:
if symbol not in subsequence:
complete = False
for sequence in generator(subsequence + [symbol], symbols):
yield sequence
if complete:
yield subsequence

with open("permutations.in", "r") as infile:
n = int(infile.readline().strip())

permutations = generator(
subsequence = [],
symbols = [str(x) for x in xrange(1, n + 1)]
)

with open("permutations.out", "w") as outfile:
for permutation in permutations:
outfile.write(" ".join(permutation) + "\n")
Loading