From 8db683821a5685eab13a3fe275bf2295d4cc5eba Mon Sep 17 00:00:00 2001 From: fromfall Date: Sun, 1 Nov 2015 13:43:08 +0300 Subject: [PATCH 01/25] Create lab10.py --- lab10/Petrov/lab10.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 lab10/Petrov/lab10.py diff --git a/lab10/Petrov/lab10.py b/lab10/Petrov/lab10.py new file mode 100644 index 0000000..2db0094 --- /dev/null +++ b/lab10/Petrov/lab10.py @@ -0,0 +1,20 @@ +from sys import stdin + +def f(A): + if len(A) == 0: + return [] + A.sort() + b = [] + for i in A: + if not i in b: + b.append(i) + A = b + res = 0 + for c in A: + l = len(A) - 1 + for a in A: + while (l > 0 and c ** 2 - a ** 2 < A[l] ** 2): + l -= 1 + if (c ** 2 - a ** 2 == A[l] ** 2 and A[l] < a): + res += 1 + return res From ddacc86973b1f1e2e67ccd4472a31ab52ff47dd1 Mon Sep 17 00:00:00 2001 From: fromfall Date: Sun, 1 Nov 2015 13:44:06 +0300 Subject: [PATCH 02/25] Create test10.py --- lab10/Petrov/test10.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 lab10/Petrov/test10.py diff --git a/lab10/Petrov/test10.py b/lab10/Petrov/test10.py new file mode 100644 index 0000000..8ffeb4e --- /dev/null +++ b/lab10/Petrov/test10.py @@ -0,0 +1,31 @@ +import unittest +import random +from lab10 import f + +class TestPythagoras(unittest.TestCase): + def testmain(self, c): + B = [] + for i in c: + if not i in B: + B.append(i) + expected = 0 + for i in range(len(B)): + for j in range(i + 1, len(B)): + for k in range(j + 1, len(B)): + if B[i]**2 + B[j]**2 == B[k]**2: + expected += 1 + res = f(B) + self.assertEqual(res, expected) + + def test_empty(self): + self.testmain([]) + + def test_std(self): + self.testmain([23, 247, 19, 96, 264, 265, 132, 265, 181]) + + def test_duplicates(self): + self.testmain([3, 4, 3, 3, 5, 4, 1, 1, 1, 4, 5, 3, 4, 2, 2, 2, 5, 5, 4, 3, 2]) + + def test_random(self): + c = [randint(-11111, 11111) for i in range(111)] + self.testmain(c) From e39508b28251c31a81b918fa30ddfd3b06b94857 Mon Sep 17 00:00:00 2001 From: fromfall Date: Sun, 1 Nov 2015 13:59:34 +0300 Subject: [PATCH 03/25] Create lab11.py --- lab11/Petrov/lab11.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 lab11/Petrov/lab11.py diff --git a/lab11/Petrov/lab11.py b/lab11/Petrov/lab11.py new file mode 100644 index 0000000..da35ccb --- /dev/null +++ b/lab11/Petrov/lab11.py @@ -0,0 +1,26 @@ +from sys import stdin +#a = list(map(int, stdin.readline().split())) + +def f(A): + res = 0 + c = -1 + s = 0 + for i in range(len(A)): + if A[i] >= c: + res = max(res, s) + s = 0 + c = A[i] + else: + s += c - A[i] + c = -1 + s = 0 + for i in range(0, len(A), -1): + if A[i] >= c: + res = max(res, s) + s = 0 + c = A[i] + else: + s += c - A[i] + return res + +#print(f(a)) From a36ed7ffe9ea80b0711a47e58a673a97585bbdce Mon Sep 17 00:00:00 2001 From: fromfall Date: Sun, 1 Nov 2015 14:00:12 +0300 Subject: [PATCH 04/25] Create test11.py --- lab11/Petrov/test11.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 lab11/Petrov/test11.py diff --git a/lab11/Petrov/test11.py b/lab11/Petrov/test11.py new file mode 100644 index 0000000..f13e8bd --- /dev/null +++ b/lab11/Petrov/test11.py @@ -0,0 +1,38 @@ +import unittest +import random +import lab11 + +class TestSorting(unittest.TestCase): + + def test_trivial(self): + arr = [1, 333, 22] + res = lab11.f(arr) + expected = 0 + self.assertEqual(expected, res) + + def test_empty(self): + arr = [] + res = lab11.f(arr) + expected = 0 + self.assertEqual(expected, res) + + def test_moun(self): + arr = ([1, 10, 0, 0, 0, 11]) + res = lab11.f(arr) + expected = 30 + self.assertEqual(expected, res) + + def test_std(self): + arr = [2, 5, 1, 2, 3, 4, 7, 7, 6] + res = lab11.f(arr) + expected = 10 + self.assertEqual(expected, res) + + def test_moun1(self): + arr = [10, 1, 1, 1, 1, 1, 1, 1, 1, 10] + res = lab11.f(arr) + expected = 72 + self.assertEqual(expected, res) + +if __name__ == '__main__': + unittest.main() From 4813fe54592301b937443abef0693f27ca4c45e1 Mon Sep 17 00:00:00 2001 From: fromfall Date: Fri, 13 Nov 2015 12:03:43 +0300 Subject: [PATCH 05/25] Create lab9.py --- lab9/lab9.py | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 lab9/lab9.py diff --git a/lab9/lab9.py b/lab9/lab9.py new file mode 100644 index 0000000..0ae33db --- /dev/null +++ b/lab9/lab9.py @@ -0,0 +1,88 @@ +import random + + +class Heap: + a = [] + def _down(self, i): + while 2 * i + 1 < len(self.a): + left = 2 * i + 1 + right = 2 * i + 2 + j = left + if right < len(self.a) and self.a[right] < self.a[left]: + j = right + if self.a[i] <= self.a[j]: + break + self.a[i], self.a[j] = self.a[j], self.a[i] + i = j + def _up(self, i): + while i > 0 and self.a[i] < self.a[(i - 1) // 2]: + self.a[i], self.a[(i - 1) // 2] = self.a[(i - 1) // 2], self.a[i] + i = (i - 1) // 2 + def min(self): + res = self.a[0] + if (len(self.a) > 1): + self.a[0] = self.a.pop() + else: + self.a.pop() + self._down(0) + return res + def insert(self, k): + self.a.append(k) + self._up(len(self.a) - 1) + +def part1(a, k): + h = Heap() + for i in a: + h.insert(i) + if (len(h.a) > k): + h.min() + return h.a + +def _partition(a, l, r): + t = [a[random.randint(l, r)], a[l], a[r]] + if t[0] > t[1]: + t[0], t[1] = t[1], t[0] + if t[1] > t[2]: + t[1], t[2] = t[2], t[1] + if t[0] > t[1]: + t[0], t[1] = t[1], t[0] + x = t[1] + i = l + j = r + while 1: + while a[i] < x: + i = i + 1 + while a[j] > x: + j = j - 1 + if i < j: + a[i], a[j] = a[j], a[i] + i += 1 + j -= 1 + else: + return j + + +def part2(a, n): + left = 0 + right = len(a) - 1 + k = len(a) - n - 1 + b = sorted(a) + while 1: + mid = _partition(a, left, right) + if mid == k: + return a[-n:] + elif k < mid: + right = mid + else: + left = mid + 1 + + +def test(): + a = random.sample(range(100), 50) + random.sample(range(100), 50) + r1 = part1(a, 40) + r2 = part2(a, 40) + r = sorted(a)[-40:] + print(r == sorted(r1)) + print(r == sorted(r2)) + +test() From 444ec115594c544352d664bb0e9ce1faf91640cb Mon Sep 17 00:00:00 2001 From: fromfall Date: Thu, 3 Dec 2015 19:55:45 +0300 Subject: [PATCH 06/25] Create lab14.py --- lab14/lab14.py | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 lab14/lab14.py diff --git a/lab14/lab14.py b/lab14/lab14.py new file mode 100644 index 0000000..78c442b --- /dev/null +++ b/lab14/lab14.py @@ -0,0 +1,40 @@ +class Graph: + def __init__(self): + self.vertices = {} + self.ids = [] + self.edges = [] + + def add_vertex(self, v): + self.edges.append([]) + self.ids.append(v) + self.vertices[v] = len(self.vertices) + + def add_directed_link(self, v1, v2): + v1 = self.vertices[v1] + v2 = self.vertices[v2] + self.edges[v1].append(v2) + + def dfs(self, v, res, used): + used[v] = 1 + circle = False + for to in self.edges[v]: + if used[to] == 0: + circle = circle or self.dfs(to, res, used) + elif used[to] == 1: + return True + res.append(v) + used[v] = 2 + return circle + + def topological_sort(self): + used = [] + for i in range(len(self.vertices)): + used.append(0) + res = [] + for i in range(len(self.vertices)): + if (used[i] == 0): + if self.dfs(i, res, used): + return None + for i in range(len(res)): + res[i] = self.ids[res[i]] + return res[::-1] From a6e74c3df41ed3ddcfa4d6179550fbea9c8d05fb Mon Sep 17 00:00:00 2001 From: fromfall Date: Thu, 3 Dec 2015 19:58:47 +0300 Subject: [PATCH 07/25] Create test14.py --- lab14/test14.py | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 lab14/test14.py diff --git a/lab14/test14.py b/lab14/test14.py new file mode 100644 index 0000000..4384c6b --- /dev/null +++ b/lab14/test14.py @@ -0,0 +1,50 @@ +import unittest +import lab14 + +class TestTopologicalSort(unittest.TestCase): + + def test_cycle(self): + graph = lab14.Graph() + graph.add_vertex(4) + graph.add_vertex(3) + graph.add_vertex(2) + graph.add_vertex(1) + graph.add_directed_link(2, 3) + graph.add_directed_link(3, 4) + graph.add_directed_link(1, 3) + graph.add_directed_link(4, 2) + graph.add_directed_link(1, 2) + res = graph.topological_sort() + expected = None + self.assertEquals(expected, res) + + def test_simple(self): + graph = lab14.Graph() + graph.add_vertex(4) + graph.add_vertex(3) + graph.add_vertex(2) + graph.add_vertex(1) + graph.add_directed_link(1, 2) + graph.add_directed_link(3, 4) + graph.add_directed_link(2, 3) + res = graph.topological_sort() + expected = [1, 2, 3, 4] + self.assertEquals(expected, res) + + + def test_simple1(self): + graph = lab14.Graph() + graph.add_vertex(4) + graph.add_vertex(3) + graph.add_vertex(2) + graph.add_vertex(1) + graph.add_directed_link(4, 2) + graph.add_directed_link(3, 4) + graph.add_directed_link(1, 3) + graph.add_directed_link(1, 2) + res = graph.topological_sort() + expected = [1, 3, 4, 2] + self.assertEquals(expected, res) + +if __name__ == '__main__': + unittest.main() From 38f9c7f31605d0d4a75ab8ccc6d4bf40a947c702 Mon Sep 17 00:00:00 2001 From: fromfall Date: Sat, 12 Dec 2015 21:57:28 +0300 Subject: [PATCH 08/25] Create lab18.py --- lab18/lab18.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 lab18/lab18.py diff --git a/lab18/lab18.py b/lab18/lab18.py new file mode 100644 index 0000000..e0ddf49 --- /dev/null +++ b/lab18/lab18.py @@ -0,0 +1,43 @@ +def dl(a, b): + if len(a) < len(b): + a, b = b, a + x = [[], [], []] + global i_shift + i_shift = 0 + + def d(i, j): + global i_shift + if i < -1 or j < -1: + return len(b) + len(a) + 1 + elif i == -1: + return j + 1 + elif j == -1: + return i + 1 + + i -= i_shift + return x[i][j] + + def d_new_line(): + global i_shift + i_shift += 1 + x[0] = x[1] + x[1] = x[2] + x[2] = [] + + def d_append(i, t): + global i_shift + i -= i_shift + x[i].append(t) + + for i in range(len(a)): + for j in range(len(b)): + res = min(d(i - 1, j), d(i, j - 1)) + 1 + res = min(res, d(i - 1, j - 1) + 1) + if a[i] == b[j]: + res = min(res, d(i - 1, j - 1)) + if i > 0 and j > 0 and a[i - 1] == b[j] and a[i] == b[j - 1]: + res = min(res, d(i - 2, j - 2) + 1) + d_append(i, res) + if i > 1: + d_new_line() + return d(len(a) - 1, len(b) - 1) From 43dae0ebb0dc0de9e29b39ae2d26ffd3e6784ed7 Mon Sep 17 00:00:00 2001 From: fromfall Date: Sat, 12 Dec 2015 21:57:42 +0300 Subject: [PATCH 09/25] Create test18.py --- lab18/test18.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 lab18/test18.py diff --git a/lab18/test18.py b/lab18/test18.py new file mode 100644 index 0000000..339ebbf --- /dev/null +++ b/lab18/test18.py @@ -0,0 +1,36 @@ +import lab18 +import unittest + +class TestLevi(unittest.TestCase): + def test_task(self): + res = lab18.dl("Levenshtien", "Frankenstein") + expected = 7 + self.assertEqual(expected, res) + + def test_trivial1(self): + res = lab18.dl("one", "two") + expected = 3 + self.assertEqual(expected, res) + + def test_trivial2(self): + res = lab18.dl("1", "2111") + expected = 3 + self.assertEqual(expected, res) + + def test_clear(self): + s1 = "" + s2 = "here's nothing interesting" + res = lab18.dl(s1, s2) + expected = 26 + self.assertEqual(expected, res) + + def test_hard(self): + s1 = "we will never be in Seattle anywhere and do not get tired to complain about this" + s2 = "morning evening Learn to be blind forever introverts with sets of contradictions" + res = lab18.dl(s1, s2) + expected = 62 + self.assertEqual(expected, res) + + +if __name__ == '__main__': + unittest.main() From 0fdb29d64a29ad28a194156e108ecb563bb29702 Mon Sep 17 00:00:00 2001 From: fromfall Date: Sat, 12 Dec 2015 22:43:36 +0300 Subject: [PATCH 10/25] Create lab19.py --- lab19/lab19.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 lab19/lab19.py diff --git a/lab19/lab19.py b/lab19/lab19.py new file mode 100644 index 0000000..57c3ff3 --- /dev/null +++ b/lab19/lab19.py @@ -0,0 +1,27 @@ +def palin(s): + d = [] + for i in range(len(s) + 1): + d.append([]) + for j in range(len(s) + 1): + d[i].append(0) + for i in range(len(s)): + for j in range(len(s)): + if s[i] == s[len(s) - j - 1]: + d[i + 1][j + 1] = d[i][j] + 1 + elif d[i][j + 1] < d[i + 1][j]: + d[i + 1][j + 1] = d[i + 1][j] + else: + d[i + 1][j + 1] = d[i][j + 1] + res = '' + i = len(s) + j = len(s) + while i > 0 and j > 0: + if s[i - 1] == s[len(s) - j]: + res += s[i - 1] + i -= 1 + j -= 1 + elif d[i][j - 1] <= d[i - 1][j]: + i -= 1 + else: + j -= 1 + return res From 375ad09a3dd70257d071d5ef3f200487b1ba1b8f Mon Sep 17 00:00:00 2001 From: fromfall Date: Sat, 12 Dec 2015 22:44:00 +0300 Subject: [PATCH 11/25] Create test19.py --- lab19/test19.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 lab19/test19.py diff --git a/lab19/test19.py b/lab19/test19.py new file mode 100644 index 0000000..465cfb5 --- /dev/null +++ b/lab19/test19.py @@ -0,0 +1,37 @@ +import lab19 +import unittest + +class TestLevi(unittest.TestCase): + def test_task(self): + res = lab19.palin("Levenshtien") + expected = "eve" + self.assertEqual(expected, res) + + def test_trivial1(self): + res = lab19.palin("babcad") + expected = "bab" + self.assertEqual(expected, res) + + def test_trivial2(self): + res = lab19.palin("abca") + expected = "aba" + self.assertEqual(expected, res) + + def test_random1(self): + res = lab19.palin("abcsdgsafghjaergfasgsv") + expected = "sgsafghgfasgs" + self.assertEqual(expected, res) + + def test_random2(self): + res = lab19.palin("vnbxcvbsdfhndfhdxfdsfgdszferyesrgssregerg") + expected = "sdfdfhfdfds" + self.assertEqual(expected, res) + + def test_random3(self): + res = lab19.palin("abcddcbadascbsbascd") + expected = "abcdddcba" + self.assertEqual(expected, res) + + +if __name__ == '__main__': + unittest.main() From 777c257e628f27dc30ad1cba02e184f11cb5dddb Mon Sep 17 00:00:00 2001 From: fromfall Date: Wed, 16 Dec 2015 19:07:33 +0300 Subject: [PATCH 12/25] Create lab20.py --- lab20/lab20.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 lab20/lab20.py diff --git a/lab20/lab20.py b/lab20/lab20.py new file mode 100644 index 0000000..3c20078 --- /dev/null +++ b/lab20/lab20.py @@ -0,0 +1,27 @@ +from sys import stdin + +if __name__ == '__main__': + n = int(input()) + num = list(map(int, stdin.readline().split())) + +def solve(n, num): + nmax = 1000003 + cur = nmax * [0] + pt = [] + res = 0 + + for x in range(len(num)): + cur[num[x]] += 1 + + for i in range(nmax - 3, 1, -1): + for j in range((((cur[i + 1] % 2) + cur[i]) // 2)): + pt.append(i) + if cur[i] > 0: + cur[i] += cur[i + 1] % 2 + + for i in range(1, len(pt), 2): + res += pt[i - 1] * pt[i] + return res + +if __name__ == '__main__': + print(solve(n, num)) From 9d19ed68f6662f631dd325230dd0edee99851b5c Mon Sep 17 00:00:00 2001 From: fromfall Date: Wed, 16 Dec 2015 19:07:53 +0300 Subject: [PATCH 13/25] Create test20.py --- lab20/test20.py | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 lab20/test20.py diff --git a/lab20/test20.py b/lab20/test20.py new file mode 100644 index 0000000..8fa08a3 --- /dev/null +++ b/lab20/test20.py @@ -0,0 +1,50 @@ +import lab20 +import unittest + +class TestLevi(unittest.TestCase): + + def test_std1(self): + n = 4 + m = [2, 4, 4, 2] + res = lab20.solve(n, m) + expected = 8 + self.assertEqual(expected, res) + + def test_std2(self): + n = 4 + m = [2, 2, 3, 5] + res = lab20.solve(n, m) + expected = 0 + self.assertEqual(expected, res) + + def test_std3(self): + n = 4 + m = [100003, 100004, 100005, 100006] + res = lab20.solve(n, m) + expected = 10000800015 + self.assertEqual(expected, res) + + def test_medium(self): + n = 8 + m = [10, 10, 10, 10, 11, 10, 11, 10] + res = lab20.solve(n, m) + expected = 210 + self.assertEqual(expected, res) + + def test_medium2(self): + n = 20 + m = [4, 4, 8, 4, 5, 6, 7, 4, 5, 4, 6, 4, 4, 5, 7, 6, 5, 8, 8, 4] + res = lab20.solve(n, m) + expected = 149 + self.assertEqual(expected, res) + + def test_hard(self): + n = 10 + m = [10519, 10519, 10520, 10520, 10520, 10521, 10521, 10521, 10522, 10523] + res = lab20.solve(n, m) + expected = 221372362 + self.assertEqual(expected, res) + + +if __name__ == '__main__': + unittest.main() From a31e86b832e5a7ab8cee17d8a4545f33b8c648b2 Mon Sep 17 00:00:00 2001 From: fromfall Date: Mon, 21 Dec 2015 11:20:10 +0300 Subject: [PATCH 14/25] Create kruskal.py --- lab17/kruskal.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 lab17/kruskal.py diff --git a/lab17/kruskal.py b/lab17/kruskal.py new file mode 100644 index 0000000..1a27795 --- /dev/null +++ b/lab17/kruskal.py @@ -0,0 +1,30 @@ +import operator +from union_find import DSU + +class WeightedGraph: + def __init__(self, vertices=0): + self.e = [] + self.vertices = vertices + + def add_vertex(self, v): + self.vertices += 1 + + def add_directed_link(self, v1, v2, w): + self.e.append([v1, v2, w]) + + def get_links(self, v): + res = [] + for edge in self.e: + if edge[0] == v: + res.append(edge) + return res + + def min_tree(self): + e = sorted(self.e, key=operator.itemgetter(2)) + dsu = DSU(self.vertices) + res = WeightedGraph(self.vertices) + for edge in e: + if dsu.find(edge[0]) != dsu.find(edge[1]): + dsu.unite(edge[0], edge[1]) + res.add_directed_link(edge[0], edge[1], edge[2]) + return res From 696be3c73024a0af6483584b9119a6dfb06067e1 Mon Sep 17 00:00:00 2001 From: fromfall Date: Mon, 21 Dec 2015 11:20:31 +0300 Subject: [PATCH 15/25] Create test17.py --- lab17/test17.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 lab17/test17.py diff --git a/lab17/test17.py b/lab17/test17.py new file mode 100644 index 0000000..87e4944 --- /dev/null +++ b/lab17/test17.py @@ -0,0 +1,44 @@ +import unittest +import union_find +import kruskal + +class TestTopologicalSort(unittest.TestCase): + + def test_dsu(self): + dsu = union_find.DSU() + dsu.append() + dsu.append() + dsu.append() + dsu.append() + dsu.append() + dsu.unite(0, 3) + dsu.unite(1, 3) + self.assertEqual(dsu.find(0), dsu.find(1)) + self.assertNotEqual(dsu.find(0), dsu.find(2)) + dsu.unite(1, 2) + self.assertEqual(dsu.find(0), dsu.find(2)) + dsu.unite(4, 4) + dsu.append() + dsu.unite(4, 5) + dsu.unite(0, 5) + for i in range(6): + self.assertEqual(dsu.find(3), dsu.find(i)) + + def test_kruskal(self): + g = kruskal.WeightedGraph(5) + g.add_directed_link(0, 1, 0) + g.add_directed_link(0, 2, 1) + g.add_directed_link(1, 2, 2) + g.add_directed_link(2, 3, 3) + g.add_directed_link(0, 3, 4) + g.add_directed_link(0, 4, 10) + t = g.min_tree() + w = 0 + for edge in t.e: + w += edge[2] + self.assertEqual(w, 14) + self.assertEqual(len(t.e), 4) + + +if __name__ == '__main__': + unittest.main() From 5c8792970df43d8e200d62cee6a5dd3a2e228537 Mon Sep 17 00:00:00 2001 From: fromfall Date: Mon, 21 Dec 2015 11:20:48 +0300 Subject: [PATCH 16/25] Create union_find.py --- lab17/union_find.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 lab17/union_find.py diff --git a/lab17/union_find.py b/lab17/union_find.py new file mode 100644 index 0000000..b41a7f2 --- /dev/null +++ b/lab17/union_find.py @@ -0,0 +1,26 @@ +from random import randint + + +class DSU: + def __init__(self, size = 0): + self.p = [] + for i in range(size): + self.p.append(i) + + def append(self): + self.p.append(len(self.p)) + + def find(self, v): + if v == self.p[v]: + return v + else: + self.p[v] = self.find(self.p[v]) + return self.p[v] + + def unite(self, a, b): + a = self.find(a) + b = self.find(b) + if randint(0, 1) == 0: + a, b = b, a + if a != b: + self.p[a] = b From c5ba764043219f0ec6b9eff2ac052d518bcfc275 Mon Sep 17 00:00:00 2001 From: fromfall Date: Mon, 21 Dec 2015 16:54:03 +0300 Subject: [PATCH 17/25] Create lab5.py --- lab5/lab5.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 lab5/lab5.py diff --git a/lab5/lab5.py b/lab5/lab5.py new file mode 100644 index 0000000..8a9552c --- /dev/null +++ b/lab5/lab5.py @@ -0,0 +1,41 @@ +from random import * +from sys import stdin +a = list(map(int, stdin.readline().split())) + +def partition(l, r): + x = a[randint(l, r)] + i = l + j = r + while 1: + while a[i] < x: + i += 1 + while a[j] > x: + j -= 1 + if i < j: + a[i], a[j] = a[j], a[i] + i += 1 + j -= 1 + else: + i = j + j = j + 1 + for k in range(i, l, -1): + if a[k] == x: + a[k], a[i] = a[i], a[k] + i -= 1 + for k in range(j, r): + if a[k] == x: + a[k], a[j] = a[j], a[k] + j += 1 + return (i, j) + +def quickSort(l, r): + if l < r: + q = partition(l, r) + quickSort(l, q[0]) + quickSort(q[1], r) + return a + +b = quickSort(0, len(a) - 1) + +for i in range(len(b)): + print(b[i], end = ' ') From 763016a04622a34ba02fbe572590d253b6b4b2a6 Mon Sep 17 00:00:00 2001 From: fromfall Date: Tue, 22 Dec 2015 15:29:53 +0300 Subject: [PATCH 18/25] Create lab16.py --- lab16/lab16.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 lab16/lab16.py diff --git a/lab16/lab16.py b/lab16/lab16.py new file mode 100644 index 0000000..86df5d3 --- /dev/null +++ b/lab16/lab16.py @@ -0,0 +1,41 @@ +import heapq + +class WeightedGraph: + def __init__(self): + self.g = [] + self.v_to_id = {} + self.id_to_v = [] + + def add_vertex(self, v): + self.g.append([]) + self.v_to_id[v] = len(self.v_to_id) + self.id_to_v.append(v) + + def add_direct_link(self, v1, v2, weight): + v1 = self.v_to_id[v1] + v2 = self.v_to_id[v2] + self.g[v1].append((v2, weight)) + + def paths(self, v): + v = self.v_to_id[v] + d = [] + f = [] + for i in range(len(self.g)): + d.append(1000000000000000000) + f.append(True) + d[v] = 0 + q = [] + heapq.heappush(q, (0, v)) + while len(q) > 0: + _, a = heapq.heappop(q) + if f[a] == False: + continue; + f[a] = False + for b, ab in self.g[a]: + if d[b] > d[a] + ab: + d[b] = d[a] + ab + heapq.heappush(q, (d[b], b)) + res = {} + for i in range(len(d)): + res[self.id_to_v[i]] = d[i] + return res From c93f932542e5e2d472d5961e1ca7780d66b90dd9 Mon Sep 17 00:00:00 2001 From: fromfall Date: Tue, 22 Dec 2015 15:30:41 +0300 Subject: [PATCH 19/25] Create test16.py --- lab16/test16.py | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 lab16/test16.py diff --git a/lab16/test16.py b/lab16/test16.py new file mode 100644 index 0000000..d88f5aa --- /dev/null +++ b/lab16/test16.py @@ -0,0 +1,59 @@ +from lab16 import WeightedGraph +import unittest + +class TestD(unittest.TestCase): + + def test_ending(self): + g = WeightedGraph() + g.add_vertex(1) + g.add_vertex(2) + g.add_vertex(3) + g.add_vertex(5) + g.add_vertex(4) + g.add_direct_link(1, 2, 1) + g.add_direct_link(1, 3, 3) + g.add_direct_link(1, 5, 4) + g.add_direct_link(1, 4, 5) + g.add_direct_link(2, 3, 1) + g.add_direct_link(3, 5, 1) + g.add_direct_link(5, 4, 1) + g.add_direct_link(4, 1, 0) + res = g.paths(1) + expected = {1: 0, 2: 1, 3: 2, 4: 4, 5: 3} + self.assertEqual(res, expected) + + def test_trivial(self): + g = WeightedGraph() + g.add_vertex(10) + g.add_vertex(20) + g.add_vertex(30) + g.add_direct_link(10, 20, 100) + g.add_direct_link(10, 30, 1) + g.add_direct_link(30, 20, 2) + res = g.paths(10) + expected = {10: 0, 20: 3, 30: 1} + self.assertEqual(res, expected) + + def test_lecture(self): + g = WeightedGraph() + g.add_vertex(1) + g.add_vertex(2) + g.add_vertex(3) + g.add_vertex(4) + g.add_vertex(5) + g.add_direct_link(1, 2, 10) + g.add_direct_link(1, 5, 5) + g.add_direct_link(2, 3, 1) + g.add_direct_link(2, 5, 2) + g.add_direct_link(3, 4, 4) + g.add_direct_link(4, 3, 6) + g.add_direct_link(4, 1, 7) + g.add_direct_link(5, 4, 2) + g.add_direct_link(5, 3, 9) + g.add_direct_link(5, 2, 3) + res = g.paths(1) + expected = {1: 0, 2: 8, 3: 9, 4: 7, 5: 5} + self.assertEqual(res, expected) + +if __name__ == '__main__': + unittest.main() From 2530501181a6f0f530a5dc5eb8acdf67d63cd3a8 Mon Sep 17 00:00:00 2001 From: fromfall Date: Wed, 23 Dec 2015 21:42:54 +0300 Subject: [PATCH 20/25] Create lab15.py --- lab15/lab15.py | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 lab15/lab15.py diff --git a/lab15/lab15.py b/lab15/lab15.py new file mode 100644 index 0000000..2a6c40d --- /dev/null +++ b/lab15/lab15.py @@ -0,0 +1,52 @@ +import math +import random + +class RMQ: + def __init__(self, a): + self.inf = max(a) + self.len = 2 ** int(math.log(len(a), 2) + 1) - 1 + self.a = [self.inf] * self.len + self.a += a + self.a += [self.inf] * (self.len + 1 - len(a)) + for i in range(len(self.a) - 1, 0, -1): + self.a[(i - 1) // 2] = min(self.a[(i - 1) // 2], self.a[i]) + + def m(self, l, r): + if l + 1 >= r: + return min(self.a[l], self.a[r]) + res = self.inf + if l % 2 == 0: + res = min(res, self.a[l]) + l += 1 + if r % 2 == 1: + res = min(res, self.a[r]) + r -= 1 + return min(res, self.m((l - 1) // 2, (r - 1) // 2)) + + + def min(self, l, r): + return self.m(l + self.len, r + self.len) + +class LCA: + def __init__(self, g, r): + a = [] + mn = [3 * len(g) for i in range(len(g))] + mx = [-1 for i in range(len(g))] + def dfs(v, d): + mx[v] = len(a) + mn[v] = mx[v] + a.append((d, v)) + for u in g[v]: + if mx[u] == -1: + dfs(u, d + 1) + mx[v] = len(a) + a.append((d, v)) + dfs(r, 0) + self.rmq = RMQ(a) + self.mn = mn + self.mx = mx + def lca(self, v1, v2): + if self.mn[v1] < self.mx[v2]: + return self.rmq.min(self.mn[v1], self.mx[v2])[1] + else: + return self.rmq.min(self.mn[v2], self.mx[v1])[1] From bbc9a2a72092fa5a347fe56e57bea67da561a70c Mon Sep 17 00:00:00 2001 From: fromfall Date: Wed, 23 Dec 2015 21:43:27 +0300 Subject: [PATCH 21/25] Create test15.py --- lab15/test15.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 lab15/test15.py diff --git a/lab15/test15.py b/lab15/test15.py new file mode 100644 index 0000000..ed1e6e3 --- /dev/null +++ b/lab15/test15.py @@ -0,0 +1,42 @@ +import unittest +from lab15 import LCA + +class Tester(unittest.TestCase): + + def test_example(self): + n = 9 + root = 3 + g = [[8], [7], [5, 6, 8], [7, 5], [7], [3, 2], [2], [1, 4, 3], [0, 2]] + lca = LCA(g, root) + self.assertEqual(lca.lca(1, 8), 3) + self.assertEqual(lca.lca(6, 2), 2) + self.assertEqual(lca.lca(2, 6), 2) + self.assertEqual(lca.lca(1, 4), 7) + + def test_simple(self): + n = 10 + root = 1 + g = [[9], [2, 3], [1, 4, 5], [1, 6, 7], [2], [2], [3, 8, 9], [3], [6], [0, 6]] + lca = LCA(g, root) + self.assertEqual(lca.lca(8, 9), 6) + self.assertEqual(lca.lca(6, 7), 3) + self.assertEqual(lca.lca(3, 2), 1) + self.assertEqual(lca.lca(8, 7), 3) + self.assertEqual(lca.lca(6, 9), 6) + self.assertEqual(lca.lca(4, 5), 2) + + def test_another(self): + n = 15 + root = 5 + g = [[13], [3], [3], [1, 2, 4], [3, 9], [6, 9, 10], [5, 7, 8], [6], [6], [4, 5], + [5, 11, 12], [10], [10, 13], [0, 12, 14], [13]] + lca = LCA(g, root) + self.assertEqual(lca.lca(0, 14), 13) + self.assertEqual(lca.lca(13, 11), 10) + self.assertEqual(lca.lca(11, 0), 10) + self.assertEqual(lca.lca(3, 7), 5) + self.assertEqual(lca.lca(7, 8), 6) + self.assertEqual(lca.lca(9, 10), 5) + +if __name__ == '__main__': + unittest.main() From 09f2069b33b05a2374706008273b41d21d37b035 Mon Sep 17 00:00:00 2001 From: fromfall Date: Thu, 24 Dec 2015 17:50:56 +0300 Subject: [PATCH 22/25] Update lab15.py --- lab15/lab15.py | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/lab15/lab15.py b/lab15/lab15.py index 2a6c40d..6b81a7b 100644 --- a/lab15/lab15.py +++ b/lab15/lab15.py @@ -1,3 +1,4 @@ +from sys import stdin, stdout import math import random @@ -45,8 +46,40 @@ def dfs(v, d): self.rmq = RMQ(a) self.mn = mn self.mx = mx + def lca(self, v1, v2): if self.mn[v1] < self.mx[v2]: return self.rmq.min(self.mn[v1], self.mx[v2])[1] else: - return self.rmq.min(self.mn[v2], self.mx[v1])[1] + return self.rmq.min(self.mn[v2], self.mx[v1])[1] + + def list_of_edges(n, v): + g = [] + for i in range(n): + g.append([]) + for i in range(n - 1): + l = int(v[i][0]) + r = int(v[i][1]) + g[l].append(r) + g[r].append(l) + + return g + +if __name__ == "__main__": + n = int(stdin.readline()) + root = int(stdin.readline()) + g = [] + for i in range(n): + g.append([]) + for i in range(n - 1): + l, r = stdin.readline().split() + l = int(l) + r = int(r) + g[l].append(r) + g[r].append(l) + + lca = LCA(g, root) + + for i in stdin: + l, r = i.split() + print(lca.lca(int(l), int(r))) From 00f733cda98728d33ae9e250a128d4528885488c Mon Sep 17 00:00:00 2001 From: fromfall Date: Thu, 24 Dec 2015 17:51:29 +0300 Subject: [PATCH 23/25] Update test15.py --- lab15/test15.py | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/lab15/test15.py b/lab15/test15.py index ed1e6e3..9922cd6 100644 --- a/lab15/test15.py +++ b/lab15/test15.py @@ -6,7 +6,8 @@ class Tester(unittest.TestCase): def test_example(self): n = 9 root = 3 - g = [[8], [7], [5, 6, 8], [7, 5], [7], [3, 2], [2], [1, 4, 3], [0, 2]] + v = [[1, 7], [4, 7], [7, 3], [5, 3], [2, 5], [6, 2], [8, 2], [0, 8]] + g = LCA.list_of_edges(n, v) lca = LCA(g, root) self.assertEqual(lca.lca(1, 8), 3) self.assertEqual(lca.lca(6, 2), 2) @@ -16,27 +17,29 @@ def test_example(self): def test_simple(self): n = 10 root = 1 - g = [[9], [2, 3], [1, 4, 5], [1, 6, 7], [2], [2], [3, 8, 9], [3], [6], [0, 6]] + v = [[1, 2], [1, 3], [2, 4], [2, 5], [3, 6], [3, 7], [6, 8], [6, 9], [9, 0]] + g = LCA.list_of_edges(n, v) lca = LCA(g, root) - self.assertEqual(lca.lca(8, 9), 6) - self.assertEqual(lca.lca(6, 7), 3) - self.assertEqual(lca.lca(3, 2), 1) - self.assertEqual(lca.lca(8, 7), 3) - self.assertEqual(lca.lca(6, 9), 6) - self.assertEqual(lca.lca(4, 5), 2) + self.assertEqual(lca.lca(0, 7), 3) + self.assertEqual(lca.lca(5, 3), 1) + self.assertEqual(lca.lca(7, 3), 3) + self.assertEqual(lca.lca(8, 0), 6) + self.assertEqual(lca.lca(9, 6), 6) def test_another(self): n = 15 root = 5 - g = [[13], [3], [3], [1, 2, 4], [3, 9], [6, 9, 10], [5, 7, 8], [6], [6], [4, 5], - [5, 11, 12], [10], [10, 13], [0, 12, 14], [13]] + v = [[5, 6], [5, 9], [5, 10], [6, 7], [6, 8], [9, 4], [4, 3], [3, 2], [3, 1], + [10, 11], [10, 12], [12, 13], [13, 14], [13, 0]] + g = LCA.list_of_edges(n, v) lca = LCA(g, root) - self.assertEqual(lca.lca(0, 14), 13) - self.assertEqual(lca.lca(13, 11), 10) - self.assertEqual(lca.lca(11, 0), 10) - self.assertEqual(lca.lca(3, 7), 5) - self.assertEqual(lca.lca(7, 8), 6) - self.assertEqual(lca.lca(9, 10), 5) + self.assertEqual(lca.lca(3, 4), 4) + self.assertEqual(lca.lca(14, 0), 13) + self.assertEqual(lca.lca(11, 10), 10) + self.assertEqual(lca.lca(2, 3), 3) + self.assertEqual(lca.lca(11, 13), 10) + self.assertEqual(lca.lca(0, 11), 10) + if __name__ == '__main__': unittest.main() From 853907d64d46926107f733452f56be59d2396591 Mon Sep 17 00:00:00 2001 From: fromfall Date: Sat, 26 Dec 2015 17:06:11 +0300 Subject: [PATCH 24/25] Update lab16.py --- lab16/lab16.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lab16/lab16.py b/lab16/lab16.py index 86df5d3..4ab0e77 100644 --- a/lab16/lab16.py +++ b/lab16/lab16.py @@ -20,9 +20,13 @@ def paths(self, v): v = self.v_to_id[v] d = [] f = [] + par = [] + path = [] for i in range(len(self.g)): d.append(1000000000000000000) f.append(True) + par.append(-1) + path.append([]) d[v] = 0 q = [] heapq.heappush(q, (0, v)) @@ -31,11 +35,17 @@ def paths(self, v): if f[a] == False: continue; f[a] = False + path[a] = path[par[a]] + [a] for b, ab in self.g[a]: if d[b] > d[a] + ab: d[b] = d[a] + ab heapq.heappush(q, (d[b], b)) + par[b] = a + res = {} for i in range(len(d)): - res[self.id_to_v[i]] = d[i] + p = [] + for j in path[i]: + p.append(self.id_to_v[j]) + res[self.id_to_v[i]] = p return res From 1fdb0c51797ee401d93b1c5142125dba7a94cca3 Mon Sep 17 00:00:00 2001 From: fromfall Date: Sat, 26 Dec 2015 17:08:40 +0300 Subject: [PATCH 25/25] Update test16.py --- lab16/test16.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/lab16/test16.py b/lab16/test16.py index d88f5aa..6fc5986 100644 --- a/lab16/test16.py +++ b/lab16/test16.py @@ -19,7 +19,7 @@ def test_ending(self): g.add_direct_link(5, 4, 1) g.add_direct_link(4, 1, 0) res = g.paths(1) - expected = {1: 0, 2: 1, 3: 2, 4: 4, 5: 3} + expected = {1: [1], 2: [1, 2], 3: [1, 2, 3], 4: [1, 2, 3, 5, 4], 5: [1, 2, 3, 5]} self.assertEqual(res, expected) def test_trivial(self): @@ -31,7 +31,7 @@ def test_trivial(self): g.add_direct_link(10, 30, 1) g.add_direct_link(30, 20, 2) res = g.paths(10) - expected = {10: 0, 20: 3, 30: 1} + expected = {10: [10], 20: [10, 30, 20], 30: [10, 30]} self.assertEqual(res, expected) def test_lecture(self): @@ -52,8 +52,20 @@ def test_lecture(self): g.add_direct_link(5, 3, 9) g.add_direct_link(5, 2, 3) res = g.paths(1) - expected = {1: 0, 2: 8, 3: 9, 4: 7, 5: 5} + expected = {1: [1], 2: [1, 5, 2], 3: [1, 5, 2, 3], 4: [1, 5, 4], 5: [1, 5]} self.assertEqual(res, expected) + def test_ending1(self): + g = WeightedGraph() + g.add_vertex(1) + g.add_vertex(2) + g.add_vertex(3) + g.add_vertex(5) + g.add_vertex(4) + g.add_direct_link(1, 2, 1) + res = g.paths(1) + expected = {1: [1], 2: [1, 2], 3: [], 4: [], 5: []} + self.assertEqual(res, expected) + if __name__ == '__main__': unittest.main()