├── .gitignore
├── .idea
├── .gitignore
├── algorithm.iml
├── codeStyles
│ └── codeStyleConfig.xml
├── dbnavigator.xml
├── encodings.xml
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
└── vcs.xml
├── Bellman_Ford_matrix.py
├── FengSort.c
├── Horner_rule.py
├── Johnson.py
├── Queue.py
├── README.md
├── SeekSum.c
├── activity_selection.py
├── add.c
├── all_pairs_shortest_paths.py
├── any_disks_intersect.py
├── any_segments_intersect.py
├── automaton_string_match.py
├── b_tree_example.py
├── bh_tree.py
├── binary_add.py
├── binary_search.py
├── binarycounter.py
├── btree.py
├── bubble_sort.py
├── closest_points.py
├── closest_points_l1_distance.py
├── closest_points_l_infinite_distance.py
├── common-matrix-multiply-Strassen.py
├── common-matrix-multiply-recursive.py
├── comparable.py
├── constraints.py
├── contains.py
├── counting_sort.py
├── cut_rod.py
├── depth_tree.py
├── deque.py
├── disjoint_sets_forest.py
├── disjoint_sets_linked_list.py
├── dynamic_array.py
├── eight_queen.py
├── euclid.py
├── extended_bottom_up_cut_rod.py
├── fft.py
├── fibonacciheap.py
├── gcd.py
├── graph.py
├── hamiltonian_path.py
├── hash.py
├── heap.py
├── huffman.py
├── insertion_sort.py
├── interpolation.py
├── interval_graph_coloring.py
├── interval_tree.py
├── inversion.py
├── inversion_tree.py
├── k_way_merge.py
├── kleene_star.py
├── knapsack_0_1.py
├── kth-Quantiles.py
├── linkedlist.py
├── longest_common_subsequence.py
├── longest_monotonically_increasing_subsequence.py
├── longest_palindrome_subsequence.py
├── lowest_common_multiple.py
├── matrix_chain_order.py
├── matrix_pow.c
├── max_subsequence_sum.c
├── maximum-subarray-brute-force.c
├── maximum-subarray-inline.c
├── maximum-subarray-recursive.c
├── memoized_cut_rod.py
├── merge.py
├── merge_sort.py
├── min_gap_tree.py
├── min_heap_with_linked_list.py
├── min_heap_with_linked_list_test.py
├── min_priority_queue_using_rb_tree.py
├── mod_exp.c
├── most_reliable_path.py
├── optimal_binary_search_tree.py
├── os_tree.py
├── parallel_fib.c
├── parallel_mat_vec.c
├── parallel_merge_sort.c
├── parallel_square_matrix_multiply.c
├── partition.py
├── pointer_tree.py
├── polar_angle.py
├── polygon_area.py
├── polynomial_multiply.py
├── pow.py
├── priority_queue.py
├── quicksort.py
├── random_array.py
├── randomized_permute.py
├── randomized_select.py
├── rank_tree.py
├── rb_tree.py
├── right_horizontal_ray_intersect.py
├── segment_intersect.py
├── selection_sort.py
├── simplex.py
├── single_edge.py
├── square-matrix-multiply-brute-force.c
├── square-matrix-multiply-brute-force2.c
├── square-matrix-multiply-recursive.c
├── square_matrix_multiply_Strassen.py
├── stack.py
├── synthetic_division.py
├── tests
├── Bellman_Ford_matrix_test.py
├── Horner_rule_test.py
├── Johnson_test.py
├── __init__.py
├── all_pairs_shortest_paths_test.py
├── bh_tree_test.py
├── binary_search_test.py
├── bubble_sort_test.py
├── constraints_test.py
├── contains_test.py
├── counting_sort_test.py
├── cut_rod_test.py
├── depth_tree_test.py
├── disjoint_sets_forest_test.py
├── disjoint_sets_test.py
├── graph_test.py
├── hamiltonian_path_test.py
├── heap_test.py
├── insertion_sort_test.py
├── interval_tree_test.py
├── inversion_test.py
├── k_way_merge_test.py
├── linked_list_test.py
├── longest_common_subsequence_test.py
├── longest_monotonically_increasing_subsequence_test.py
├── merge_sort_test.py
├── min_gap_tree_test.py
├── min_heap_with_linked_list_test.py
├── min_priority_queue_using_rb_tree_test.py
├── most_reliable_path_test.py
├── os_tree_test.py
├── partition_test.py
├── pointer_tree_test.py
├── polygon_area_test.py
├── priority_queue_test.py
├── quicksort_test.py
├── randomized_select_test.py
├── rank_tree_test.py
├── rb_tree_test.py
├── selection_sort_test.py
├── test_binary_add.py
├── test_deque.py
├── test_dynamic_array.py
├── test_euclid.py
├── test_gcd.py
├── test_lowest_common_multiple.py
├── test_merge.py
├── test_pow.py
├── test_queue.py
├── two_sum_test.py
├── universal_sink_test.py
├── vEB_tree_test.py
└── wrestlers_test.py
├── three_points_colinear.py
├── three_sum.py
├── tree.py
├── two_sum.py
├── universal_sink.py
├── vEB_tree.py
└── wrestlers.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 | a.out
9 | *.o
10 |
11 | # Distribution / packaging
12 | .Python
13 | env/
14 | build/
15 | develop-eggs/
16 | dist/
17 | downloads/
18 | eggs/
19 | .eggs/
20 | lib/
21 | lib64/
22 | parts/
23 | sdist/
24 | var/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 |
29 | # PyInstaller
30 | # Usually these files are written by a python script from a template
31 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
32 | *.manifest
33 | *.spec
34 |
35 | # Installer logs
36 | pip-log.txt
37 | pip-delete-this-directory.txt
38 |
39 | # Unit test / coverage reports
40 | htmlcov/
41 | .tox/
42 | .coverage
43 | .coverage.*
44 | .cache
45 | nosetests.xml
46 | coverage.xml
47 | *,cover
48 | .hypothesis/
49 |
50 | # Translations
51 | *.mo
52 | *.pot
53 |
54 | # Django stuff:
55 | *.log
56 |
57 | # Sphinx documentation
58 | docs/_build/
59 |
60 | # PyBuilder
61 | target/
62 |
63 | #Ipython Notebook
64 | .ipynb_checkpoints
65 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /workspace.xml
3 |
--------------------------------------------------------------------------------
/.idea/algorithm.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Bellman_Ford_matrix.py:
--------------------------------------------------------------------------------
1 |
2 | def Bellman_Ford_matrix(W, s):
3 | n = W.shape[0]
4 | d = [float("Inf")] * n
5 | p = [None] * n
6 | d[s - 1] = 0
7 | for k in range(1, n):
8 | for i in range(1, n + 1):
9 | for j in range(1, n + 1):
10 | if d[j - 1] > d[i - 1] + W[i - 1, j - 1]:
11 | d[j - 1] = d[i - 1] + W[i - 1, j - 1]
12 | p[j - 1] = i
13 | print(d)
14 | print(p)
15 | return d, p
16 |
17 |
18 | def extend_shortest_paths(L, W):
19 | n = W.shape[0]
20 | LW = [float("Inf")] * n
21 | for j in range(n):
22 | for k in range(n):
23 | LW[j] = min(LW[j], L[k] + W[k, j])
24 | return LW
25 |
26 |
27 | def slow_all_pairs_shortest_paths(W, s):
28 | n = W.shape[0]
29 | L = [0] * n
30 | for i in range(n):
31 | if i + 1 == s:
32 | L[i] = 0
33 | else:
34 | L[i] = float("Inf")
35 | print(L)
36 | for m in range(1, n):
37 | L = extend_shortest_paths(L, W)
38 | print(L)
39 | return L
40 |
41 |
42 | def extend_shortest_paths_with_predecessor_subgraph(s, L, P, W):
43 | n = W.shape[0]
44 | LW = [float("Inf")] * n
45 | PP = [None] * n
46 | for j in range(n):
47 | for k in range(n):
48 | if LW[j] > L[k] + W[k, j]:
49 | LW[j] = L[k] + W[k, j]
50 | PP[j] = k + 1
51 | if LW[j] == L[j]:
52 | PP[j] = P[j]
53 | return LW, PP
54 |
55 |
56 | def slow_all_pairs_shortest_paths_with_predecessor_subgraph(W, s):
57 | n = W.shape[0]
58 | L = [float("Inf")] * n
59 | L[s - 1] = 0
60 | P = [None] * n
61 | for m in range(1, n):
62 | L, P = extend_shortest_paths_with_predecessor_subgraph(s, L, P, W)
63 | print(L)
64 | print(P)
65 | return L, P
66 |
67 |
68 | def faster_all_pairs_shortest_paths(W):
69 | n = W.shape[0]
70 | L = W
71 | m = 1
72 | while m < n - 1:
73 | L = extend_shortest_paths(L, L)
74 | m = 2 * m
75 | print(m)
76 | print(L)
77 | return Ld, p
78 |
--------------------------------------------------------------------------------
/FengSort.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | void FengSort(int A[], int first, int end)
6 | {
7 | int length = end - first + 1;
8 | int MAX = 100;
9 | int *B = (int *)calloc(MAX + 1, sizeof(int));
10 | int i, j;
11 | int LIMIT = MAX + 1;
12 |
13 | for (i = 1; i <= MAX; i++)
14 | B[i] = LIMIT;
15 | for (i = 0; i < length; i++)
16 | B[A[i]] = A[i];
17 | j = 0;
18 | for (i = 1; i <= MAX; i++)
19 | if (B[i] != LIMIT)
20 | A[j++] = B[i];
21 | free(B);
22 | }
23 |
24 | int main()
25 | {
26 | int a[9] = { 3, 41, 52, 31, 31, 57, 9, 31, 100 };
27 | int b[2] = {100, 2};
28 | // int a[2] = {4,3};
29 | // int a[3] = {4, 3, 1};
30 | // Combine(a, 0, 3, 5);
31 | FengSort(a, 0, 8);
32 | printf("%d, %d, %d, %d, %d, %d, %d, %d, %d\n", a[0], a[1], a[2], a[3],
33 | a[4], a[5], a[6], a[7], a[8]);
34 | FengSort(b, 0, 1);
35 | printf("%d,%d\n", b[0], b[1]);
36 | exit(0);
37 | }
38 |
--------------------------------------------------------------------------------
/Horner_rule.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | import functools
4 |
5 |
6 | def Horner_rule(x, coefficients):
7 | """
8 | Implements Horner's rule
9 | :param x:
10 | :param coefficients:
11 | :return:
12 | """
13 | return functools.reduce(lambda accumulate, coefficient: coefficient + accumulate * x, reversed(coefficients), 0)
14 |
--------------------------------------------------------------------------------
/Johnson.py:
--------------------------------------------------------------------------------
1 | from graph import min_priority_queue, Vertex, Graph
2 | import numpy as np
3 |
4 |
5 | def Bellman_Ford(self, w, s):
6 | """
7 | The Bellman-Ford algorithm solves the single-source
8 | shortest-paths problem in the general case in which edge
9 | weights may be negative.
10 | If there is a negative-weight cycle that is reachable from
11 | the source s, this function returns False and indicates that
12 | no solution exists.
13 | If there is no such cycle, this function returns True and produces
14 | the shortest paths and their weights.
15 |
16 | :param self:
17 | :param w:
18 | :param s:
19 | :return:
20 | """
21 | initialize_single_source(self, s)
22 | for i in range(1, len(self.vertices)):
23 | for u, v in self.edges:
24 | relax(u, v, w)
25 | for u, v in self.edges:
26 | if v.d > u.d + w[(u, v)]:
27 | return False
28 | return True
29 |
30 |
31 | def initialize_single_source(self, s):
32 | for v in self.vertices:
33 | v.d = float("Inf")
34 | v.p = None
35 | s.d = 0
36 |
37 |
38 | def relax(u, v, w):
39 | if v.d > u.d + w[u, v]:
40 | v.d = u.d + w[u, v]
41 | v.p = u
42 |
43 |
44 | def Dijkstra(self, w, s):
45 | """
46 | Dijkstra's algorithm solves the single-source shortest-paths problem
47 | on a weighted, directed graph G = (V, E) for the case in which all edge
48 | weights are nonnegative.
49 | """
50 | initialize_single_source(self, s)
51 | S = set()
52 | Q = min_priority_queue(self.vertices, 'd')
53 | while Q.heap_size > 1:
54 | u = Q.heap_extract_min()
55 | S = S.union({u})
56 | for v in self.adj[u]:
57 | if v.d > u.d + w[u, v]:
58 | v.d = u.d + w[u, v]
59 | v.p = u
60 | Q.heap_decrease_key(v.index, u.d + w[u, v])
61 |
62 |
63 | def Johnson(self, w):
64 | G = self
65 | n = len(G.vertices)
66 | s = Vertex("s")
67 | GG = Graph(G.vertices.union({s}), G.edges | set((s, v) for v in G.vertices))
68 | for v in G.vertices:
69 | w[(s, v)] = 0
70 | if not Bellman_Ford(GG, w, s):
71 | print("the input graph contains a negative-weight cycle")
72 | else:
73 | h = dict()
74 | for v in GG.vertices:
75 | h[v] = v.d
76 | # for key,value in h.iteritems():
77 | # print(( "h({}) = {}".format(key, value)))
78 | ww = dict()
79 | for u, v in GG.edges:
80 | ww[(u, v)] = w[(u, v)] + h[u] - h[v]
81 | # for key,value in ww.iteritems():
82 | # print(( "ww({}) = {}".format(key, value)))
83 | D = np.empty((n, n))
84 | for u in G.vertices:
85 | Dijkstra(G, ww, u)
86 | for v in G.vertices:
87 | D[u.key - 1, v.key - 1] = v.d + h[v] - h[u]
88 | return D
89 |
--------------------------------------------------------------------------------
/Queue.py:
--------------------------------------------------------------------------------
1 | class FullException(Exception):
2 | def __init__(self):
3 | Exception.__init__(self)
4 |
5 |
6 | class EmptyException(Exception):
7 | def __init__(self):
8 | Exception.__init__(self)
9 |
10 |
11 | class Queue:
12 | def __init__(self, size):
13 | self.data = [0] * size
14 | self.size = size
15 | self.head = 0
16 | self.tail = 0
17 |
18 | def enqueue(self, x):
19 | if self.full():
20 | raise FullException()
21 | self.data[self.tail] = x
22 | if self.tail == self.size - 1:
23 | self.tail = 0
24 | else:
25 | self.tail = self.tail + 1
26 |
27 | def dequeue(self):
28 | if self.empty():
29 | raise EmptyException()
30 | x = self.data[self.head]
31 | if self.head == self.size - 1:
32 | self.head = 0
33 | else:
34 | self.head = self.head + 1
35 | return x
36 |
37 | def empty(self):
38 | return self.tail == self.head
39 |
40 | def full(self):
41 | return (self.tail + 1) % self.size == self.head
42 |
43 | def capacity(self):
44 | return self.size - 1
45 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # algorithm
2 | implementation of algorithms in CLRS
3 |
4 | ## note
5 | Since python2 is outdated, the original python2.7 code is moved to python2.7 branch.
6 | The master branch support python3 only.
7 |
8 | ## test
9 | Run testcase in tests folder
10 |
--------------------------------------------------------------------------------
/SeekSum.c:
--------------------------------------------------------------------------------
1 | #include
2 | //An algorithm that, given a set S of n integers and another integer x,
3 | //determines whether or not there exist two elements in S whose sum is
4 | //exactly x. The set S must be already sorted
5 |
6 | int BinSearch(int A[], int first, int end, int x) {
7 | int length = end - first;
8 | int inter;
9 |
10 | while (length >= 0) {
11 | inter = (first + end) / 2;
12 | if (x == A[inter] )
13 | return inter + 1;
14 | else if (x < A[inter])
15 | end = inter - 1;
16 | else
17 | first = inter + 1;
18 | length = end - first;
19 | }
20 | return -1;
21 | }
22 |
23 | void SeekSum(int A[], int first, int end, int x) {
24 | int i;
25 | int pos;
26 |
27 | for (i = first; i < end; i++)
28 | if ((pos = BinSearch(A, i + 1, end, x - A[i])) != -1) {
29 | printf("first = %d,end = %d\n",i + 1, pos);
30 | break;
31 | }
32 | }
33 |
34 |
35 | int main() {
36 | int A[10] = {2,3,4,6, 7, 8, 8, 10, 15 , 70};
37 |
38 | SeekSum(A, 0, 9, 15);
39 | SeekSum(A, 0, 9, 25);
40 | SeekSum(A, 0, 9, 12);
41 | SeekSum(A, 0, 9, 13);
42 | return 0;
43 | }
44 |
--------------------------------------------------------------------------------
/activity_selection.py:
--------------------------------------------------------------------------------
1 | from numpy import zeros
2 |
3 |
4 | def activity_selection(s, f, n):
5 | c = zeros((n + 2, n + 2))
6 | activities = zeros((n + 2, n + 2))
7 | s = [float("-Inf")] + s[0:n] + [float("Inf")]
8 | f = [float("-Inf")] + f[0:n] + [float("Inf")]
9 | for l in range(3, n + 3):
10 | for i in range(n + 3 - l):
11 | j = i + l - 1
12 | print("i = {}, j = {}".format(i, j))
13 | for k in range(i + 1, j):
14 | print("k = {}".format(k))
15 | print("s[{}] = {}, f[{}] = {}".format(k, s[k], k, f[k]))
16 | print("s[{}] = {}, f[{}] = {}".format(j, s[j], i, f[i]))
17 | if f[i] <= s[k] and f[k] <= s[j]:
18 | t = c[i, k] + c[k, j] + 1
19 | print("t = {}, c[{}, {}] = {}".format(t, i, j, c[i, j]))
20 | if t > c[i, j]:
21 | c[i, j] = t
22 | activities[i, j] = k
23 | return c, activities
24 |
25 |
26 | def activity_selection_with_weight(s, f, v, n):
27 | """
28 | This is a modification to the activity-selection problem in which each activity has,
29 | in addition to a start and finish time, a value v. Now the object is to maximize
30 | the total value of the activities scheduled. It can be solved by dynamic programming method
31 | """
32 | c = zeros((n + 2, n + 2))
33 | activities = zeros((n + 2, n + 2))
34 | s = [float("-Inf")] + s[0:n] + [float("Inf")]
35 | f = [float("-Inf")] + f[0:n] + [float("Inf")]
36 | for l in range(3, n + 3):
37 | for i in range(n + 3 - l):
38 | j = i + l - 1
39 | for k in range(i + 1, j):
40 | if f[i] <= s[k] and f[k] <= s[j]:
41 | t = c[i, k] + c[k, j] + v[k - 1]
42 | if t > c[i, j]:
43 | c[i, j] = t
44 | activities[i, j] = k
45 | return c, activities
46 |
47 |
48 | def recursive_activity_selector(s, f, n):
49 | f = [float("-Inf")] + f
50 | return recursive_activity_selector_aux(s, f, 0, n)
51 |
52 |
53 | def recursive_activity_selector_aux(s, f, k, n):
54 | m = k + 1
55 | while m <= n and s[m - 1] < f[k]:
56 | m = m + 1
57 | if m <= n:
58 | return {m}.union(recursive_activity_selector_aux(s, f, m, n))
59 | else:
60 | return {}
61 |
62 |
63 | def greedy_activity_selector(s, f):
64 | n = len(s)
65 | A = {1}
66 | k = 1
67 | for m in range(2, n + 1):
68 | if s[m - 1] >= f[k - 1]:
69 | A = A.union({m})
70 | k = m
71 | return A
72 |
73 |
74 | def greedy_activity_selector_last(s, f):
75 | """Instead of always selecting the first activity to finish,
76 | select the last activity to start that is compatible with all
77 | previously selected activities
78 | """
79 | n = len(s)
80 | A = {n}
81 | k = n
82 | for m in range(n - 1, 0, -1):
83 | if f[m - 1] <= s[k - 1]:
84 | A = A.union({m})
85 | k = m
86 | return A
87 |
88 |
89 | def print_activity(activities):
90 | m = activities.shape[0] - 1
91 | n = activities.shape[1] - 1
92 | print_activity_aux(activities, 0, n)
93 |
94 |
95 | def print_activity_aux(activities, m, n):
96 | a = activities[m, n]
97 | if a == 0:
98 | return
99 | print_activity_aux(activities, m, a)
100 | print(int(a))
101 | print_activity_aux(activities, a, n)
102 |
--------------------------------------------------------------------------------
/add.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #define N 2
4 | void submatrix_init(int *S, int S_row, int S_col, int *T, int T_row, int T_col, int row_start, int col_start);
5 |
6 | int main() {
7 | int A[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
8 | int B[4] = {1, 2, 3, 4};
9 | int C[4] = {1, 0, 2, 1};
10 | int D[4];
11 | int E[4];
12 | int i, j;
13 |
14 |
15 | //submatrix_init(A, 4, 4, B, 2, 2, 1, 1);
16 | //submatrix_init(A, 4, 4, C, 2, 2, 1, 3);
17 | //submatrix_init(A, 4, 4, D, 2, 2, 3, 1);
18 | //submatrix_init(A, 4, 4, E, 2, 2, 3, 3);
19 | //printf("Matrix A:\n");
20 | //for (i = 0; i < 4; i++) {
21 | //for (j = 0; j < 4; j++)
22 | //printf("%d\t", *(A + 4 * i + j));
23 | //printf("\n");
24 | //}
25 | //printf("\n");
26 | //printf("Matrix B:\n");
27 | //for (i = 0; i < N; i++) {
28 | //for (j = 0; j < N; j++)
29 | //printf("%d\t", *(B + N * i + j));
30 | //printf("\n");
31 | //}
32 | //printf("\n");
33 | //printf("Matrix C:\n");
34 | //for (i = 0; i < N; i++) {
35 | //for (j = 0; j < N; j++)
36 | //printf("%d\t", *(C + N * i + j));
37 | //printf("\n");
38 | //}
39 | //printf("\n");
40 | //printf("Matrix D:\n");
41 | //for (i = 0; i < N; i++) {
42 | //for (j = 0; j < N; j++)
43 | //printf("%d\t", *(D + N * i + j));
44 | //printf("\n");
45 | //}
46 | //printf("\n");
47 | //printf("Matrix E:\n");
48 | //for (i = 0; i < N; i++) {
49 | //for (j = 0; j < N; j++)
50 | //printf("%d\t", *(E + N * i + j));
51 | //printf("\n");
52 | //}
53 | //printf("\n");
54 | square_matrix_multiply(B, C, E, 2);
55 | printf("Matrix E:\n");
56 | for (i = 0; i < N; i++) {
57 | for (j = 0; j < N; j++)
58 | printf("%d\t", *(E + N * i + j));
59 | printf("\n");
60 | }
61 | printf("\n");
62 | }
63 |
--------------------------------------------------------------------------------
/automaton_string_match.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 |
4 | def finite_automaton_matcher(T, s, m):
5 | n = len(T)
6 | q = 0
7 | for i in range(1, n + 1):
8 | q = s[(q, T[i - 1])]
9 | if q == m:
10 | print("Pattern occurs with shift {}".format(i - m))
11 |
12 |
13 | def compute_transition_function(P, domain):
14 | m = len(P)
15 | s = dict()
16 | for a in domain:
17 | for q in range(m + 1):
18 | k = min(q + 1, m)
19 | while not (P[0:q] + a).endswith(P[0:k]):
20 | k = k - 1
21 | s[(q, a)] = k
22 | return s
23 |
24 |
25 | def automaton_string_match(P, T, domain):
26 | s = compute_transition_function(P, domain)
27 | m = len(P)
28 | finite_automaton_matcher(T, s, m)
29 |
--------------------------------------------------------------------------------
/b_tree_example.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import btree as bt
4 |
5 | a = bt.BTreeNode(3, True, 2)
6 | a.key[0] = 'A'
7 | a.key[1] = 'B'
8 | b = bt.BTreeNode(3, True, 3)
9 | b.key[0] = 'D'
10 | b.key[1] = 'E'
11 | b.key[2] = 'F'
12 | c = bt.BTreeNode(3, True, 3)
13 | c.key[0] = 'J'
14 | c.key[1] = 'K'
15 | c.key[2] = 'L'
16 | d = bt.BTreeNode(3, True, 2)
17 | d.key[0] = 'N'
18 | d.key[1] = 'O'
19 | x = bt.BTreeNode(3, True, 3)
20 | x.key[0] = 'Q'
21 | x.key[1] = 'R'
22 | x.key[2] = 'S'
23 | y = bt.BTreeNode(3, True, 2)
24 | y.key[0] = 'U'
25 | y.key[1] = 'V'
26 | z = bt.BTreeNode(3, True, 2)
27 | z.key[0] = 'Y'
28 | z.key[1] = 'Z'
29 | e = bt.BTreeNode(3, False, 3)
30 | e.key[0] = 'C'
31 | e.key[1] = 'G'
32 | e.key[2] = 'M'
33 | e.c[0] = a
34 | e.c[1] = b
35 | e.c[2] = c
36 | e.c[3] = d
37 | v = bt.BTreeNode(3, False, 2)
38 | v.key[0] = 'T'
39 | v.key[1] = 'X'
40 | v.c[0] = x
41 | v.c[1] = y
42 | v.c[2] = z
43 | t = bt.BTree(3)
44 | t.root.key[0] = 'P'
45 | t.root.c[0] = e
46 | t.root.c[1] = v
47 | t.root.n = 1
48 | t.root.leaf = False
49 | t.root.delete(t, 'F')
50 | t.root.print_child_first()
51 | print()
52 | t.root.delete(t, 'M')
53 | t.root.print_child_first()
54 | print()
55 | t.root.delete(t, 'G')
56 | t.root.print_child_first()
57 | print()
58 | t.root.delete(t, 'D')
59 | t.root.print_child_first()
60 | print()
61 | t.root.delete(t, 'B')
62 | t.root.print_child_first()
63 | print()
64 | t.root.delete(t, 'C')
65 | t.root.print_child_first()
66 | print()
67 | t.root.delete(t, 'P')
68 | t.root.print_child_first()
69 | print()
70 | t.root.delete(t, 'V')
71 | t.root.print_child_first()
72 | print()
73 |
--------------------------------------------------------------------------------
/bh_tree.py:
--------------------------------------------------------------------------------
1 | # A variant of red black tree that has black_height attribute
2 | # !/usr/bin/env python
3 |
4 | from rb_tree import RbNode, RbTree
5 |
6 |
7 | class bh_node(RbNode):
8 | def __init__(self, key, p, left, right, color, bh):
9 | RbNode.__init__(self, key, p, left, right, color)
10 | self.bh = bh
11 |
12 |
13 | class bh_tree(RbTree):
14 | nil = bh_node(None, None, None, None, 1, 0)
15 | root = nil
16 |
17 | def __init__(self, values):
18 | if isinstance(values, list):
19 | for i in values:
20 | self.insert(bh_node(i, None, None, None, 0, 1))
21 | else:
22 | print("Not invalid argument")
23 |
24 | def insert_fixed(self, z):
25 | while z.p.color == 0:
26 | if z.p.p.left == z.p:
27 | y = z.p.p.right
28 | if y.color == 0:
29 | z.p.color = 1
30 | y.color = 1
31 | z.p.p.color = 0
32 | z = z.p.p
33 | z.bh = z.bh + 1
34 | else:
35 | if z.p.right == z:
36 | z = z.p
37 | self.left_rotate(z)
38 | z = z.p.p
39 | self.right_rotate(z)
40 | z.color = 0
41 | z.p.color = 1
42 | else:
43 | y = z.p.p.left
44 | if y.color == 0:
45 | z.p.color = 1
46 | y.color = 1
47 | z.p.p.color = 0
48 | z = z.p.p
49 | z.bh = z.bh + 1
50 | else:
51 | if z.p.left == z:
52 | z = z.p
53 | self.right_rotate(z)
54 | z = z.p.p
55 | self.left_rotate(z)
56 | z.color = 0
57 | z.p.color = 1
58 | self.root.color = 1
59 |
60 | def delete_fixup(self, x):
61 | while x != self.root and x.color == 1:
62 | if x == x.p.left:
63 | w = x.p.right
64 | if w.color == 0:
65 | w.color = 1
66 | x.p.color = 0
67 | self.left_rotate(x.p)
68 | w = x.p.right
69 | if w.left.color == 1 and w.right.color == 1:
70 | w.color = 0
71 | x = x.p
72 | x.bh = x.bh - 1
73 | else:
74 | if w.left.color == 0 and w.right.color == 1:
75 | w.left.color = 1
76 | w.color = 0
77 | self.right_rotate(w)
78 | w = x.p.right
79 | w.color = x.p.color
80 | x.p.color = 1
81 | w.right.color = 1
82 | self.left_rotate(x.p)
83 | w.bh = w.bh + 1
84 | x = self.root
85 | else:
86 | w = x.p.left
87 | if w.color == 0:
88 | w.color = 1
89 | x.p.color = 0
90 | self.right_rotate(x.p)
91 | w = x.p.left
92 | if w.left.color == 1 and w.right.color == 1:
93 | w.color = 0
94 | x = x.p
95 | else:
96 | if w.left.color == 1 and w.right.color == 0:
97 | w.right.color = 1
98 | w.color = 0
99 | self.left_rotate(w)
100 | w = x.p.left
101 | w.color = x.p.color
102 | w.left.color = 1
103 | x.p.color = 1
104 | self.right_rotate(x.p)
105 | w.bh = w.bh + 1
106 | x = self.root
107 | x.color = 1
108 |
--------------------------------------------------------------------------------
/binary_add.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 |
5 | def binary_add(array1, array2):
6 | """
7 | Consider the problem of adding two n-bit binary integers, stored in two n-element arrays A and B,
8 | in big-endian order.
9 | The sum of the two integers should be stored in binary form in a (n + 1)-element array C.
10 | :param array1: n-element array A
11 | :param array2: n-element array B
12 | :return: (n + 1)-element array C
13 | """
14 | assert len(array1) == len(array2)
15 | n = len(array1)
16 | promote = 0
17 | array3 = [0] * (n + 1)
18 | for i in range(n - 1, -1, -1):
19 | result = array1[i] + array2[i] + promote
20 | promote = result // 2
21 | array3[i + 1] = result % 2
22 | array3[0] = promote
23 | return array3
24 |
--------------------------------------------------------------------------------
/binary_search.py:
--------------------------------------------------------------------------------
1 | def binary_search(target, array):
2 | """
3 | find target in sorted array.
4 | If found, return the index, otherwise return -1.
5 | :param target:
6 | :param array: list
7 | :return:
8 | """
9 | low = 0
10 | high = len(array) - 1
11 | while low <= high:
12 | mid = (low + high) // 2
13 | if target < array[mid]:
14 | high = mid - 1
15 | elif target > array[mid]:
16 | low = mid + 1
17 | else:
18 | return mid
19 | return -1
20 |
21 |
22 | def bisect_left(array, x, low=0, high=None):
23 | """
24 | Locate the insertion point for x in a to maintain sorted order.
25 | If x is already present in a,
26 | the insertion point will be before (to the left of) any existing entries.
27 | The return value is suitable for use as the first parameter to list.insert() assuming that a is already sorted.
28 | Optional args lo (default 0) and hi (default len(a)) bound the
29 | slice of a to be searched.
30 |
31 | :param array: sorted list
32 | :param x:
33 | :param low:
34 | :param high:
35 | :return:
36 | """
37 | if high is None:
38 | high = len(array)
39 | assert low <= high
40 | while low < high:
41 | mid = (low + high) // 2
42 | if array[mid] < x:
43 | low = mid + 1
44 | else:
45 | high = mid
46 | return low
47 |
48 |
49 | def bisect_right(array, x, low=0, high=None):
50 | """
51 | Return the index where to insert item x in list a, assuming a is sorted.
52 |
53 | The return value i is such that all e in a[:i] have e <= x, and all e in
54 | a[i:] have e > x. So if x already appears in the list, a.insert(x) will
55 | insert just after the rightmost x already there.
56 |
57 | Optional args lo (default 0) and hi (default len(a)) bound the
58 | slice of a to be searched.
59 | :param array:
60 | :param x:
61 | :param low:
62 | :param high:
63 | :return:
64 | """
65 | if high is None:
66 | high = len(array)
67 | assert low <= high
68 | while low < high:
69 | mid = (low + high) // 2
70 | if array[mid] <= x:
71 | low = mid + 1
72 | else:
73 | high = mid
74 | return low
75 |
--------------------------------------------------------------------------------
/binarycounter.py:
--------------------------------------------------------------------------------
1 | class BinaryCounter(list):
2 | def __init__(self, size):
3 | self.leftmost_1 = -1
4 | super(BinaryCounter, self).__init__([0] * size)
5 |
6 | def increment(self):
7 | i = 0
8 | while i < len(self) and self[i] == 1:
9 | self[i] = 0
10 | i = i + 1
11 | if i < len(self):
12 | self[i] = 1
13 | if self.leftmost_1 < i:
14 | self.leftmost_1 = i
15 | else:
16 | self.leftmost_1 = -1
17 |
18 | def reset(self):
19 | for i in range(self.leftmost_1 + 1):
20 | self[i] = 0
21 | self.leftmost_1 = -1
22 |
23 | def print_bits(self):
24 | print(self[::-1])
25 |
--------------------------------------------------------------------------------
/bubble_sort.py:
--------------------------------------------------------------------------------
1 | def bubble_sort(array):
2 | """
3 | O(n ^ 2) inplace sort
4 | :param array: list
5 | :return:
6 | """
7 | n = len(array)
8 | for i in range(n):
9 | for j in range(n - 1, i, -1):
10 | if array[j] < array[j - 1]:
11 | array[j], array[j - 1] = array[j - 1], array[j]
12 |
--------------------------------------------------------------------------------
/closest_points.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from math import ceil, sqrt
4 | from heap import MaxHeap
5 |
6 |
7 | def x_sort(S):
8 | X = MaxHeap(S)
9 | X.heapsort()
10 | return X
11 |
12 |
13 | def y_sort(S):
14 | Y = []
15 | for p in S:
16 | Y.append((p[1], p[0]))
17 | YY = MaxHeap(Y)
18 | YY.heapsort()
19 | Y = []
20 | for i in range(len(YY)):
21 | Y.append((YY[i][1], YY[i][0]))
22 | return Y
23 |
24 |
25 | def distance(p1, p2):
26 | return sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)
27 |
28 |
29 | def brute_force(P):
30 | P = list(P)
31 | d = float("Inf")
32 | for i in range(len(P)):
33 | for j in range(i + 1, len(P)):
34 | d = min(d, distance(P[i], P[j]))
35 | return d
36 |
37 |
38 | def closest_points(S):
39 | X = x_sort(S)
40 | Y = y_sort(S)
41 | return closest_points_aux(S, X, Y)
42 |
43 |
44 | def closest_points_aux(P, X, Y):
45 | length = len(P)
46 | half = int(ceil(length / 2))
47 | if length <= 3:
48 | return brute_force(P)
49 | XL = X[:half]
50 | XR = X[half:]
51 | PL = set(XL)
52 | PR = set(XR)
53 | l = X[half - 1][0]
54 | YL = []
55 | YR = []
56 | for i in range(len(Y)):
57 | if Y[i] in PL:
58 | YL.append(Y[i])
59 | else:
60 | YR.append(Y[i])
61 | dl = closest_points_aux(PL, XL, YL)
62 | dr = closest_points_aux(PR, XR, YR)
63 | d1 = min(dl, dr)
64 | YY = []
65 | for i in range(len(Y)):
66 | if abs(Y[i][0] - l) < d1:
67 | YY.append(Y[i])
68 | d2 = float("Inf")
69 | for i in range(len(YY)):
70 | for j in range(1, 10):
71 | if i + j < len(YY):
72 | d2 = min(distance(YY[i], YY[i + j]), d2)
73 | return min(d1, d2)
74 |
--------------------------------------------------------------------------------
/closest_points_l1_distance.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from math import ceil, sqrt
4 | from heap import MaxHeap
5 |
6 |
7 | def x_sort(S):
8 | X = MaxHeap(S)
9 | X.heapsort()
10 | return X
11 |
12 |
13 | def y_sort(S):
14 | Y = []
15 | for p in S:
16 | Y.append((p[1], p[0]))
17 | YY = MaxHeap(Y)
18 | YY.heapsort()
19 | Y = []
20 | for i in range(len(YY)):
21 | Y.append((YY[i][1], YY[i][0]))
22 | return Y
23 |
24 |
25 | def distance(p1, p2):
26 | return abs(p1[0] - p2[0]) + abs(p1[1] - p2[1])
27 |
28 |
29 | def brute_force(P):
30 | P = list(P)
31 | d = float("Inf")
32 | for i in range(len(P)):
33 | for j in range(i + 1, len(P)):
34 | d = min(d, distance(P[i], P[j]))
35 | return d
36 |
37 |
38 | def closest_points(S):
39 | X = x_sort(S)
40 | Y = y_sort(S)
41 | return closest_points_aux(S, X, Y)
42 |
43 |
44 | def closest_points_aux(P, X, Y):
45 | length = len(P)
46 | half = int(ceil(length / 2))
47 | if length <= 3:
48 | return brute_force(P)
49 | XL = X[:half]
50 | XR = X[half:]
51 | PL = set(XL)
52 | PR = set(XR)
53 | l = X[half - 1][0]
54 | YL = []
55 | YR = []
56 | for i in range(len(Y)):
57 | if Y[i] in PL:
58 | YL.append(Y[i])
59 | else:
60 | YR.append(Y[i])
61 | dl = closest_points_aux(PL, XL, YL)
62 | dr = closest_points_aux(PR, XR, YR)
63 | d1 = min(dl, dr)
64 | YY = []
65 | for i in range(len(Y)):
66 | if abs(Y[i][0] - l) < d1:
67 | YY.append(Y[i])
68 | d2 = float("Inf")
69 | for i in range(len(YY)):
70 | for j in range(1, 10):
71 | if i + j < len(YY):
72 | d2 = min(distance(YY[i], YY[i + j]), d2)
73 | return min(d1, d2)
74 |
--------------------------------------------------------------------------------
/closest_points_l_infinite_distance.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from math import ceil, sqrt
4 | from heap import MaxHeap
5 |
6 |
7 | def x_sort(S):
8 | X = MaxHeap(S)
9 | X.heapsort()
10 | return X
11 |
12 |
13 | def y_sort(S):
14 | Y = []
15 | for p in S:
16 | Y.append((p[1], p[0]))
17 | YY = MaxHeap(Y)
18 | YY.heapsort()
19 | Y = []
20 | for i in range(len(YY)):
21 | Y.append((YY[i][1], YY[i][0]))
22 | return Y
23 |
24 |
25 | def distance(p1, p2):
26 | return max(abs(p1[0] - p2[0]), abs(p1[1] - p2[1]))
27 |
28 |
29 | def brute_force(P):
30 | P = list(P)
31 | d = float("Inf")
32 | for i in range(len(P)):
33 | for j in range(i + 1, len(P)):
34 | d = min(d, distance(P[i], P[j]))
35 | return d
36 |
37 |
38 | def closest_points(S):
39 | X = x_sort(S)
40 | Y = y_sort(S)
41 | return closest_points_aux(S, X, Y)
42 |
43 |
44 | def closest_points_aux(P, X, Y):
45 | length = len(P)
46 | half = int(ceil(length / 2))
47 | if length <= 3:
48 | return brute_force(P)
49 | XL = X[:half]
50 | XR = X[half:]
51 | PL = set(XL)
52 | PR = set(XR)
53 | l = X[half - 1][0]
54 | YL = []
55 | YR = []
56 | for i in range(len(Y)):
57 | if Y[i] in PL:
58 | YL.append(Y[i])
59 | else:
60 | YR.append(Y[i])
61 | dl = closest_points_aux(PL, XL, YL)
62 | dr = closest_points_aux(PR, XR, YR)
63 | d1 = min(dl, dr)
64 | YY = []
65 | for i in range(len(Y)):
66 | if abs(Y[i][0] - l) < d1:
67 | YY.append(Y[i])
68 | d2 = float("Inf")
69 | for i in range(len(YY)):
70 | for j in range(1, 7):
71 | if i + j < len(YY):
72 | d2 = min(distance(YY[i], YY[i + j]), d2)
73 | return min(d1, d2)
74 |
--------------------------------------------------------------------------------
/common-matrix-multiply-Strassen.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/python2.7
2 |
3 | # AUTHOR: WangQiang
4 | # CREATE DATE: 20140803
5 | # LAST UPDATE DATE: 20140803
6 | # EMAIL: cntqrxj@gmail.com
7 |
8 | from numpy import *
9 | from square_matrix_multiply_Strassen import square_matrix_multiply
10 |
11 |
12 | def common_matrix_multiply(A, B):
13 | if A.shape[1] != B.shape[0]:
14 | print("The width of matrix A not equal the height of matrix B.\nHence no matrix multiplication allowed")
15 | return
16 | shape = A.shape[0], B.shape[1]
17 | # shape = A.shape
18 | length = shape[0]
19 | half = length / 2
20 | A_width = A.shape[1]
21 | B_width = B.shape[1]
22 | A_height = A.shape[0]
23 | B_height = B.shape[0]
24 | half_A_width = A_width / 2
25 | half_A_height = A_height / 2
26 | half_B_width = B_width / 2
27 | half_B_height = B_height / 2
28 |
29 | C = zeros(shape, dtype=int64)
30 | if A_height == 1 or B_width == 1:
31 | C = dot(A, B)
32 | # if length == 1:
33 | # C[0, 0] = A[0, 0] * B[0, 0]
34 | # return C
35 |
36 | S1 = zeros((half, half), dtype=int64)
37 | S2 = zeros((half, half), dtype=int64)
38 | S3 = zeros((half, half), dtype=int64)
39 | S4 = zeros((half, half), dtype=int64)
40 | S5 = zeros((half, half), dtype=int64)
41 | S6 = zeros((half, half), dtype=int64)
42 | S7 = zeros((half, half), dtype=int64)
43 | S8 = zeros((half, half), dtype=int64)
44 | S9 = zeros((half, half), dtype=int64)
45 | S10 = zeros((half, half), dtype=int64)
46 |
47 | P1 = zeros((half, half), dtype=int64)
48 | P2 = zeros((half, half), dtype=int64)
49 | P3 = zeros((half, half), dtype=int64)
50 | P4 = zeros((half, half), dtype=int64)
51 | P5 = zeros((half, half), dtype=int64)
52 | P6 = zeros((half, half), dtype=int64)
53 | P7 = zeros((half, half), dtype=int64)
54 |
55 | S1 = B[0:half, half:length] - B[half:length, half:length]
56 | S2 = A[0:half, 0:half] + A[0:half, half:length]
57 | S3 = A[half:length, 0:half] + A[half:length, half:length]
58 | S4 = B[half:length, 0:half] - B[0:half, 0:half]
59 | S5 = A[0:half, 0:half] + A[half:length, half:length]
60 | S6 = B[0:half, 0:half] + B[half:length, half:length]
61 | S7 = A[0:half, half:length] - A[half:length, half:length]
62 | S8 = B[half:length, 0:half] + B[half:length, half:length]
63 | S9 = A[0:half, 0:half] - A[half:length, 0:half]
64 | S10 = B[0:half, 0:half] + B[0:half, half:length]
65 |
66 | P1 = square_matrix_multiply(A[0:half, 0:half], S1)
67 | P2 = square_matrix_multiply(S2, B[half:length, half:length])
68 | P3 = square_matrix_multiply(S3, B[0:half, 0:half])
69 | P4 = square_matrix_multiply(A[half:length, half:length], S4)
70 | P5 = square_matrix_multiply(S5, S6)
71 | P6 = square_matrix_multiply(S7, S8)
72 | P7 = square_matrix_multiply(S9, S10)
73 |
74 | C[0:half, 0:half] = P5 + P4 - P2 + P6
75 | C[0:half, half:length] = P1 + P2
76 | C[half:length, 0:half] = P3 + P4
77 | C[half:length, half:length] = P5 + P1 - P3 - P7
78 |
79 | return C
80 |
81 |
82 | # A = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
83 | # B = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
84 | # A = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
85 | # B = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
86 | A = array([[1, 3], [7, 5]])
87 | B = array([[6, 8], [4, 2]])
88 | # A = array([[1, 2, 3], [4, 5, 6]])
89 | # B = array([[1, 2], [4, 5]])
90 | print(square_matrix_multiply(A, B))
91 | # print( dot(A, B))
92 |
--------------------------------------------------------------------------------
/common-matrix-multiply-recursive.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/python2.7
2 |
3 | from numpy import *
4 |
5 |
6 | def common_matrix_multiply(A, B):
7 | if A.shape[1] != B.shape[0]:
8 | print("The width of matrix A not equal the height of matrix B.\nHence no matrix multiplication allowed")
9 | return
10 | shape = (A.shape[0], B.shape[1])
11 | C = zeros(shape, dtype=int64)
12 | A_width = A.shape[1]
13 | B_width = B.shape[1]
14 | A_height = A.shape[0]
15 | B_height = B.shape[0]
16 | half_A_width = A_width / 2
17 | half_A_height = A_height / 2
18 | half_B_width = B_width / 2
19 | half_B_height = B_height / 2
20 | if A_height == 1 or B_width == 1:
21 | C = dot(A, B)
22 | # else if
23 | else:
24 | C[0:half_A_height, 0:half_B_width] = common_matrix_multiply(A[0:half_A_height, 0:half_A_width],
25 | B[0:half_B_height,
26 | 0:half_B_width]) + common_matrix_multiply(
27 | A[0:half_A_height, half_A_width:A_width], B[half_B_height:B_height, 0:half_B_width])
28 | C[0:half_A_height, half_B_width:B_width] = common_matrix_multiply(A[0:half_A_height, 0:half_A_width],
29 | B[0:half_B_height,
30 | half_B_width:B_width]) + common_matrix_multiply(
31 | A[0:half_A_height, half_A_width:A_width], B[half_B_height:B_height, half_B_width:B_width])
32 | C[half_A_height:A_height, 0:half_B_width] = common_matrix_multiply(A[half_A_height:A_height, 0:half_A_width],
33 | B[0:half_B_height,
34 | 0:half_B_width]) + common_matrix_multiply(
35 | A[half_A_height:A_height, half_A_width:A_width], B[half_B_height:B_height, 0:half_B_width])
36 | C[half_A_height:A_height, half_B_width:B_width] = common_matrix_multiply(
37 | A[half_A_height:A_height, 0:half_A_width],
38 | B[0:half_B_height, half_B_width:B_width]) + common_matrix_multiply(
39 | A[half_A_height:A_height, half_A_width:A_width], B[half_B_height:B_height, half_B_width:B_width])
40 | return C
41 |
42 |
43 | A = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
44 | B = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
45 | # A = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
46 | # B = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
47 | # A = array([[1, 2, 3], [4, 5, 6]])
48 | # B = array([[1, 2], [4, 5]])
49 | print(common_matrix_multiply(A, B))
50 | # print( dot(A, B))
51 |
--------------------------------------------------------------------------------
/comparable.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | def comparable(a, b, x):
4 | """
5 | Given two segments a and b that are comparable at x, determine whether a is above b or not. Assume that neither segment is vertical
6 | """
7 |
8 | p1 = a[0]
9 | p2 = a[1]
10 | p3 = b[0]
11 | p4 = b[1]
12 | x4 = p4[0]
13 | x3 = p3[0]
14 | v1 = (p2[0] - p1[0], p2[1] - p1[1])
15 | v2 = (
16 | (x4 - x3) * (p2[0] - p4[0]) + (x4 - x) * (p4[0] - p3[0]),
17 | (x4 - x3) * (p2[1] - p4[1]) + (x4 - x) * (p4[1] - p3[1]))
18 | result = v1[0] * v2[1] - v2[0] * v1[1]
19 | if result == 0:
20 | print("a intersects b at the vertical line")
21 | elif result > 0:
22 | print("a is above b")
23 | else:
24 | print("b is above a")
25 |
--------------------------------------------------------------------------------
/contains.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | def contains(x, n):
4 | """
5 | CLRS Exercise 16.2-5
6 | An algorithm that, given a set {x1, x2, ... ,xn} of points on the
7 | real line, determines the smallest set of unit-length closed intervals that contains
8 | all of the given points.
9 | :param x:
10 | :param n:
11 | :return:
12 | """
13 | x.sort()
14 | print(x)
15 | i = 0
16 | a = float("-Inf")
17 | S = set()
18 | while i < n:
19 | if x[i] > a:
20 | S = S.union({(x[i], x[i] + 1)})
21 | a = x[i] + 1
22 | i = i + 1
23 | print(S)
24 | return S
25 |
--------------------------------------------------------------------------------
/counting_sort.py:
--------------------------------------------------------------------------------
1 | def counting_sort(A, B, k):
2 | C = []
3 | for i in range(k + 1):
4 | C.append(0)
5 | for j in range(len(A)):
6 | C[A[j]] = C[A[j]] + 1
7 | for i in range(1, k + 1):
8 | C[i] = C[i] + C[i - 1]
9 | for j in range(len(A) - 1, -1, -1):
10 | B[C[A[j]] - 1] = A[j]
11 | C[A[j]] = C[A[j]] - 1
12 |
--------------------------------------------------------------------------------
/cut_rod.py:
--------------------------------------------------------------------------------
1 | def bottom_up_cut_rod(p, n):
2 | r = [0] * (n + 1)
3 | for j in range(1, n + 1):
4 | q = float("-Inf")
5 | for i in range(1, j + 1):
6 | q = max(q, p[i - 1] + r[j - i])
7 | r[j] = q
8 | return r[n]
9 |
10 |
11 | def bottom_up_cut_rod_two_subproblem(p, n):
12 | r = [0] * (n + 1)
13 | for i in range(1, n + 1):
14 | r[i] = p[i - 1]
15 | for j in range(1, n + 1):
16 | q = float("-Inf")
17 | for i in range(1, j + 1):
18 | q = max(q, r[i] + r[j - i])
19 | r[j] = q
20 | return r[n]
21 |
22 |
23 | def memoized_cut_rod(p, n):
24 | r = [float("-Inf")] * n
25 | return memoized_cut_rod_aux(p, n, r)
26 |
27 |
28 | def memoized_cut_rod_aux(p, n, r):
29 | if n == 0:
30 | return 0
31 | if r[n - 1] >= 0:
32 | return r[n - 1]
33 | q = float("-Inf")
34 | for i in range(1, n + 1):
35 | q = max(q, p[i - 1] + memoized_cut_rod_aux(p, n - i, r))
36 | r[n - 1] = q
37 | return q
38 |
39 |
40 | def extended_bottom_up_cut_rod(p, n):
41 | r = [0] * (n + 1)
42 | s = [0] * (n + 1)
43 | for j in range(1, n + 1):
44 | q = float("-Inf")
45 | for i in range(1, j + 1):
46 | if q < p[i - 1] + r[j - i]:
47 | q = p[i - 1] + r[j - i]
48 | s[j] = i
49 | r[j] = q
50 | return r, s
51 |
52 |
53 | def print_cut_rod_solution(p, n, cut):
54 | r, s = cut(p, n)
55 | while n != 0:
56 | print(s[n])
57 | n = n - s[n]
58 |
59 |
60 | def bottom_up_cut_rod_with_fixed_cut_cost(p, n, c):
61 | r = [0] * (n + 1)
62 | for j in range(1, n + 1):
63 | q = float("-Inf")
64 | for i in range(1, j):
65 | q = max(q, r[i] + r[j - i] - c)
66 | q = max(q, p[j - 1])
67 | r[j] = q
68 | return r[n]
69 |
70 |
71 | def extended_memoized_cut_rod(p, n):
72 | r = [float("-Inf")] * n
73 | s = [0] * (n + 1)
74 | extended_memoized_cut_rod_aux(p, n, r, s)
75 | return r, s
76 |
77 |
78 | def extended_memoized_cut_rod_aux(p, n, r, s):
79 | if n == 0:
80 | return 0
81 | if r[n - 1] >= 0:
82 | return r[n - 1]
83 | q = float("-Inf")
84 | for i in range(1, n + 1):
85 | value = p[i - 1] + extended_memoized_cut_rod_aux(p, n - i, r, s)
86 | if q < value:
87 | q = value
88 | s[n] = i
89 | r[n - 1] = q
90 | return q
91 |
--------------------------------------------------------------------------------
/depth_tree.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # A variant of red black tree that has depth attribute
4 |
5 | from rb_tree import RbNode, RbTree
6 |
7 |
8 | class depth_node(RbNode):
9 | def __init__(self, key, p, left, right, color, depth):
10 | RbNode.__init__(self, key, p, left, right, color)
11 | self.depth = depth
12 |
13 | def update_depth_whole_tree(self, amount):
14 | if self.depth != -1:
15 | self.left.update_depth_whole_tree(amount)
16 | self.depth = self.depth + amount
17 | self.right.update_depth_whole_tree(amount)
18 |
19 |
20 | class depth_tree(RbTree):
21 | nil = depth_node(None, None, None, None, 1, -1)
22 | root = nil
23 |
24 | def __init__(self, values):
25 | if isinstance(values, list):
26 | for i in values:
27 | self.insert(depth_node(i, None, None, None, 0, 0))
28 | else:
29 | print("Not invalid argument")
30 |
31 | def left_rotate(self, x):
32 | y = x.right
33 | x.right = y.left
34 | if y.left != self.nil:
35 | y.left.p = x
36 | y.p = x.p
37 | if x.p == self.nil:
38 | self.root = y
39 | elif x.p.left == x:
40 | x.p.left = y
41 | else:
42 | x.p.right = y
43 | y.left = x
44 | x.p = y
45 | x.depth = x.depth + 1
46 | y.depth = y.depth - 1
47 | x.left.update_depth_whole_tree(1)
48 | y.right.update_depth_whole_tree(-1)
49 |
50 | def right_rotate(self, y):
51 | x = y.left
52 | y.left = x.right
53 | if x.right != self.nil:
54 | x.right.p = y
55 | x.p = y.p
56 | if y.p == self.nil:
57 | self.root = x
58 | elif y.p.right == y:
59 | y.p.right = x
60 | else:
61 | y.p.left = x
62 | x.right = y
63 | y.p = x
64 | x.depth = x.depth - 1
65 | y.depth = y.depth + 1
66 | x.left.update_depth_whole_tree(-1)
67 | y.right.update_depth_whole_tree(1)
68 |
69 | def insert(self, z):
70 | y = self.nil
71 | x = self.root
72 | depth = 0
73 | while x != self.nil:
74 | depth = depth + 1
75 | y = x
76 | if z.key <= x.key:
77 | x = x.left
78 | else:
79 | x = x.right
80 | z.depth = depth
81 | if y == self.nil:
82 | self.root = z
83 | elif z.key <= y.key:
84 | y.left = z
85 | else:
86 | y.right = z
87 | z.p = y
88 | z.left = self.nil
89 | z.right = self.nil
90 | z.color = 0 # red
91 | self.insert_fixed(z)
92 |
93 | def delete(self, z):
94 | y = z
95 | y_original_color = y.color
96 | if z.left == self.nil:
97 | x = z.right
98 | self.transplant(z, z.right)
99 | elif z.right == self.nil:
100 | x = z.left
101 | self.transplant(z, z.left)
102 | else:
103 | y = z.right.minimum()
104 | y_original_color = y.color
105 | x = y.right
106 | if y.p == z:
107 | x.p = y
108 | else:
109 | self.transplant(y, y.right)
110 | y.right = z.right
111 | y.right.p = y
112 | self.transplant(z, y)
113 | y.left = z.left
114 | y.left.p = y
115 | y.color = z.color
116 | y.depth = z.depth
117 | if x != self.nil:
118 | x.update_depth_whole_tree(-1)
119 | if y_original_color == 1:
120 | self.delete_fixup(x)
121 |
--------------------------------------------------------------------------------
/deque.py:
--------------------------------------------------------------------------------
1 | from Queue import Queue, FullException, EmptyException
2 |
3 |
4 | class Deque(Queue):
5 | """
6 | whereas a Queue allows insertion at one end and deletion at the other end,
7 | a Deque(double-ended Queue) allows insertion and deletion at both ends
8 | """
9 |
10 | def __init__(self, size):
11 | super().__init__(size)
12 |
13 | def enqueue_tail(self, x):
14 | self.enqueue(x)
15 |
16 | def dequeue_head(self):
17 | return self.dequeue()
18 |
19 | def enqueue_head(self, x):
20 | if self.full():
21 | raise FullException()
22 | else:
23 | if self.head == 0:
24 | self.head = self.size - 1
25 | else:
26 | self.head = self.head - 1
27 | self.data[self.head] = x
28 |
29 | def dequeue_tail(self):
30 | if self.empty():
31 | raise EmptyException()
32 | else:
33 | if self.tail == 0:
34 | self.tail = self.size - 1
35 | else:
36 | self.tail = self.tail - 1
37 |
38 | return self.data[self.tail]
39 |
--------------------------------------------------------------------------------
/disjoint_sets_forest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 |
4 | class node:
5 | def __init__(self, key):
6 | self.key = key
7 | # key.index = self
8 | self.p = self
9 | self.rank = 0
10 | self.child = []
11 |
12 | def union(self, y):
13 | self.find_set().link(y.find_set())
14 |
15 | def link(self, y):
16 | x = self
17 | if x.rank > y.rank:
18 | x.child.append(y)
19 | y.p = x
20 | else:
21 | y.child.append(x)
22 | x.p = y
23 | if x.rank == y.rank:
24 | y.rank = y.rank + 1
25 |
26 | def find_set(self):
27 | y = self
28 | x = self
29 | while y != y.p:
30 | y = y.p
31 | while x != x.p:
32 | z = x
33 | x = x.p
34 | z.p = y
35 | # print( y.key)
36 | return y
37 |
38 | def print_set(self):
39 | x = self
40 | while x != x.p:
41 | x = x.p
42 | x.print_set_aux()
43 |
44 | def print_set_aux(self):
45 | print(self.key)
46 | if len(self.child) == 0:
47 | return
48 | for child in self.child:
49 | child.print_set_aux()
50 |
--------------------------------------------------------------------------------
/disjoint_sets_linked_list.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | class node:
4 | def __init__(self, key):
5 | self.key = key
6 | self.set = None
7 | self.next = None
8 |
9 | def find_set(self):
10 | return self.set.head
11 |
12 | def union(self, y):
13 | if self.set.length < y.set.length:
14 | x = y
15 | y = self
16 | else:
17 | x = self
18 | xs = x.set
19 | ys = y.set
20 | xs.tail.next = ys.head
21 | element = ys.head
22 | for i in range(1, ys.length + 1):
23 | element.set = xs
24 | element = element.next
25 | xs.tail = ys.tail
26 | xs.length = xs.length + ys.length
27 | return x
28 |
29 |
30 | class header:
31 | def __init__(self, element):
32 | self.length = 1
33 | self.head = element
34 | element.set = self
35 | self.tail = self.head
36 |
37 |
38 | class node_notail(node):
39 | def union(self, y):
40 | if self.set.length < y.set.length:
41 | x = y
42 | y = self
43 | else:
44 | x = self
45 | xs = x.set
46 | ys = y.set
47 | element = ys.head
48 | for i in range(1, ys.length + 1):
49 | element.set = xs
50 | tail = element
51 | element = element.next
52 | tail.next = xs.head
53 | xs.head = ys.head
54 | xs.length = xs.length + ys.length
55 | return y
56 |
57 |
58 | class header_notail:
59 | def __init__(self, element):
60 | self.length = 1
61 | self.head = element
62 | element.set = self
63 |
--------------------------------------------------------------------------------
/dynamic_array.py:
--------------------------------------------------------------------------------
1 | class DynamicArray:
2 | def __init__(self, capacity):
3 | assert capacity > 0
4 | self._capacity = capacity
5 | self._size = 0
6 | self._data = [None] * capacity
7 |
8 | def add(self, element):
9 | if self._size == self._capacity:
10 | temp = self._data
11 | self._data = [None] * (self._capacity * 2)
12 | self._data[:self._capacity] = temp[:]
13 | self._capacity *= 2
14 | self._data[self._size] = element
15 | self._size += 1
16 |
17 | def size(self):
18 | return self._size
19 |
20 | def get(self, index):
21 | return self._data[index]
22 |
--------------------------------------------------------------------------------
/eight_queen.py:
--------------------------------------------------------------------------------
1 | N = 8
2 | counter = 0
3 |
4 |
5 | def print_solution(chess_board):
6 | for row in range(N):
7 | for col in range(N):
8 | if chess_board[row] != col:
9 | print('-', end=' ')
10 | else:
11 | print('X', end=' ')
12 | print('\n')
13 | print('\n')
14 |
15 |
16 | def isplaceok(chess_board, row, col):
17 | return not any(
18 | (chess_board[i] == col) or (chess_board[i] - col == row - i) or (chess_board[i] - col == i - row) for i in
19 | range(row))
20 |
21 |
22 | def add_queen(chess_board, row):
23 | global counter
24 | if row >= N:
25 | print_solution(chess_board)
26 | counter += 1
27 | else:
28 | for col in range(N):
29 | if isplaceok(chess_board, row, col):
30 | chess_board[row] = col
31 | add_queen(chess_board, row + 1)
32 |
33 |
34 | if __name__ == "__main__":
35 | chess_board = [-1] * N
36 | add_queen(chess_board, 0)
37 | print(counter)
38 |
--------------------------------------------------------------------------------
/euclid.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding=utf-8
3 |
4 |
5 | def euclid(a, b):
6 | if b == 0:
7 | return a
8 | else:
9 | return euclid(b, a % b)
10 |
11 |
12 | def extended_euclid(a, b):
13 | if b == 0:
14 | return a, 1, 0
15 | else:
16 | d, x, y = extended_euclid(b, a % b)
17 | return d, y, x - (a / b) * y
18 |
--------------------------------------------------------------------------------
/extended_bottom_up_cut_rod.py:
--------------------------------------------------------------------------------
1 | def extended_bottom_up_cut_rod(p, n):
2 | r = [0] * (n + 1)
3 | s = [0] * (n + 1)
4 | for j in range(1, n + 1):
5 | q = float("-Inf")
6 | for i in range(1, j + 1):
7 | if q < p[i - 1] + r[j - i]:
8 | q = p[i - 1] + r[j - i]
9 | s[j] = i
10 | r[j] = q
11 | return r, s
12 |
13 |
14 | def print_cut_rod_solution(p, n):
15 | r, s = extended_bottom_up_cut_rod(p, n)
16 | while n > 0:
17 | print(s[n])
18 | n = n - s[n]
19 |
--------------------------------------------------------------------------------
/fft.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import math
4 |
5 |
6 | def recursive_fft(a):
7 | n = len(a)
8 | if n == 1:
9 | return a
10 | wn = complex(math.cos(2 * math.pi / n), math.sin(2 * math.pi / n))
11 | w = 1.0
12 | a0 = [a[i] for i in range(0, n, 2)]
13 | a1 = [a[i] for i in range(1, n, 2)]
14 | y0 = recursive_fft(a0)
15 | y1 = recursive_fft(a1)
16 | y = [0.0] * n
17 | for k in range(n // 2):
18 | y[k] = y0[k] + w * y1[k]
19 | y[k + n // 2] = y0[k] - w * y1[k]
20 | w = w * wn
21 | return y
22 |
23 |
24 | def recursive_inverse_fft(y):
25 | n = len(y)
26 | result = recursive_inverse_fft_aux(y)
27 | return [result[i] / n for i in range(n)]
28 |
29 |
30 | def recursive_inverse_fft_aux(y):
31 | n = len(y)
32 | if n == 1:
33 | return y
34 | wn = 1.0 / complex(math.cos(2 * math.pi / n), math.sin(2 * math.pi / n))
35 | w = 1.0
36 | y0 = [y[i] for i in range(0, n, 2)]
37 | y1 = [y[i] for i in range(1, n, 2)]
38 | a0 = recursive_inverse_fft_aux(y0)
39 | a1 = recursive_inverse_fft_aux(y1)
40 | a = [0.0] * n
41 | for k in range(n // 2):
42 | a[k] = (a0[k] + w * a1[k])
43 | a[k + n // 2] = (a0[k] - w * a1[k])
44 | w = w * wn
45 | return a
46 |
--------------------------------------------------------------------------------
/gcd.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 |
5 | def gcd(m: int, n: int):
6 | """
7 | compute the greatest common divisor of m and n;
8 | :param m:
9 | :param n:
10 | :return:
11 | """
12 | while n > 0:
13 | rem = m % n
14 | m = n
15 | n = rem
16 | return m
17 |
--------------------------------------------------------------------------------
/hamiltonian_path.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 |
4 | def hamiltonian_path(G, u, v):
5 | """
6 | An algorithm to the hamiltonian-path problem on directed acyclic graphs
7 | """
8 | we = dict()
9 | for i in G.edges:
10 | we[i] = -1
11 |
12 | def w(x, y):
13 | return we[(x, y)]
14 |
15 | G.dag_shortest_paths(w, u)
16 | return abs(v.d) == len(G.vertices) - 1
17 |
--------------------------------------------------------------------------------
/hash.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 |
4 | def hash_insert(T, k, h):
5 | i = 0
6 | while i < len(T):
7 | j = h(k, i)
8 | if T[j] is None:
9 | T[j] = k
10 | return j
11 | else:
12 | i = i + 1
13 |
14 |
15 | def linear_probe(k, i):
16 | return (aux(k) + i) % len(T)
17 |
18 |
19 | def quad_probe(k, i):
20 | return (aux(k) + i + 3 * i * i) % len(T)
21 |
22 |
23 | def aux(k):
24 | return k
25 |
26 |
27 | def double_hashing(k, i):
28 | return (k + i * (1 + k % (len(T) - 1))) % len(T)
29 |
30 |
31 | T = [None] * 11
32 | print("length of T is ", len(T))
33 | for i in 10, 22, 31, 4, 15, 28, 17, 88, 59:
34 | hash_insert(T, i, double_hashing)
35 |
36 | print(T)
37 |
--------------------------------------------------------------------------------
/heap.py:
--------------------------------------------------------------------------------
1 | class MaxHeap(list):
2 | def __init__(self, data):
3 | super().__init__(data)
4 | self.length = len(self)
5 | self.heap_size = self.length
6 | self.build_max_heap()
7 |
8 | @staticmethod
9 | def left(i):
10 | return 2 * i + 1
11 |
12 | @staticmethod
13 | def right(i):
14 | return 2 * i + 2
15 |
16 | @staticmethod
17 | def parent(i):
18 | return (i - 1) // 2
19 |
20 | def max_heapify(self, i):
21 | left = self.left(i)
22 | right = self.right(i)
23 | if left < self.heap_size and self[left] > self[i]:
24 | largest = left
25 | else:
26 | largest = i
27 | if right < self.heap_size and self[right] > self[largest]:
28 | largest = right
29 | if largest != i:
30 | self[i], self[largest] = self[largest], self[i]
31 | self.max_heapify(largest)
32 |
33 | def build_max_heap(self):
34 | self.heap_size = self.length
35 | for i in range(self.length // 2 - 1, -1, -1):
36 | self.max_heapify(i)
37 |
38 | def heapsort(self):
39 | self.build_max_heap()
40 | for i in range(self.length - 1, 0, -1):
41 | self[0], self[i] = self[i], self[0]
42 | self.heap_size = self.heap_size - 1
43 | self.max_heapify(0)
44 |
45 |
46 | class MinHeap(list):
47 | def __init__(self, data):
48 | super().__init__(data)
49 | self.length = len(self)
50 | self.heap_size = self.length
51 | self.build_min_heap()
52 |
53 | def __contains__(self, y):
54 | return y in self[:self.heap_size]
55 |
56 | @staticmethod
57 | def left(i):
58 | return 2 * i + 1
59 |
60 | @staticmethod
61 | def right(i):
62 | return 2 * i + 2
63 |
64 | @staticmethod
65 | def parent(i):
66 | return (i - 1) // 2
67 |
68 | def min_heapify(self, i):
69 | l = self.left(i)
70 | r = self.right(i)
71 | if (l <= (self.heap_size - 1)) and (self[l] < self[i]):
72 | smallest = l
73 | else:
74 | smallest = i
75 | if (r <= (self.heap_size - 1)) and (self[r] < self[smallest]):
76 | smallest = r
77 | if smallest != i:
78 | self[i], self[smallest] = self[smallest], self[i]
79 | self.min_heapify(smallest)
80 |
81 | def build_min_heap(self):
82 | self.heap_size = self.length
83 | for i in range(self.length // 2 - 1, -1, -1):
84 | self.min_heapify(i)
85 |
--------------------------------------------------------------------------------
/insertion_sort.py:
--------------------------------------------------------------------------------
1 | from binary_search import bisect_right
2 |
3 |
4 | def insert_with_linear_search(array, left_index, right_index):
5 | """
6 | Use linear search to find a position in already sorted array[left_index...right_index-1] to insert array[right_index] into,
7 | making array[left_index...right_index] a sorted array.
8 | :param array:
9 | :param left_index:
10 | :param right_index: right_index > 0
11 | :return:
12 | """
13 | key = array[right_index]
14 | i = right_index - 1
15 | while i >= left_index and key < array[i]:
16 | array[i + 1] = array[i]
17 | i = i - 1
18 | array[i + 1] = key
19 |
20 |
21 | def insert_with_binary_search(array, left_index, right_index):
22 | """
23 | Use binary search to find a position in already sorted array[left_index...right_index-1] to insert array[right_index] into,
24 | making array[left_index...right_index] a sorted array.
25 | :param array:
26 | :param left_index:
27 | :param right_index: right_index > 0
28 | :return:
29 | """
30 | x = array[right_index]
31 | index = bisect_right(array, x, left_index, right_index)
32 | array[index + 1: right_index + 1] = array[index: right_index]
33 | array[index] = x
34 |
35 |
36 | def insertion_sort(array, left=0, right=None, insert_method=insert_with_linear_search):
37 | """
38 | inplace sort O(n ^ 2) sort
39 | :param array:
40 | :param left:
41 | :param right:
42 | :param insert_method:
43 | :return:
44 | """
45 | if right is None:
46 | right = len(array) - 1
47 | for j in range(left, right + 1):
48 | insert_method(array, 0, j)
49 |
50 |
51 | def _insertion_sort_recursive(array, length, insert_method):
52 | if length > 1:
53 | _insertion_sort_recursive(array, length - 1, insert_method)
54 | insert_method(array, 0, length - 1)
55 |
56 |
57 | def insertion_sort_recursive(array, insert_method=insert_with_linear_search):
58 | """
59 | recursive version of insertion sort
60 | :param array:
61 | :param insert_method:
62 | :return:
63 | """
64 | _insertion_sort_recursive(array, len(array), insert_method)
65 |
--------------------------------------------------------------------------------
/interpolation.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import synthetic_division as di
4 |
5 |
6 | def roots_interpolation(roots, n):
7 | A = [0] * (n + 1)
8 | if n == 1:
9 | A[0] = -1 * roots[n - 1]
10 | A[1] = 1
11 | return A
12 | else:
13 | B = roots_interpolation(roots, n - 1)
14 | x = roots[n - 1]
15 | A[n] = B[n - 1]
16 | for i in range(n - 1, 0, -1):
17 | A[i] = B[i - 1] - x * B[i]
18 | A[0] = -1 * x * B[0]
19 | return A
20 |
21 |
22 | def Lagrange_interpolation(X, Y, n):
23 | R = roots_interpolation(X, n)
24 | # print( "length of R is {}".format(len(R)))
25 | A = [0] * n
26 | for k in range(n):
27 | q, re = di.synthetic_division(R, n + 1, X[k])
28 | # print( q)
29 | # print( "length of q is {}".format(len(q)))
30 | m = 1.0
31 | for j in range(n):
32 | if j != k:
33 | m = m * (X[k] - X[j])
34 | # print( "m = {}".format(m))
35 | m = Y[k] / m
36 | # print( "m = {}".format(m))
37 | for j in range(n):
38 | A[j] = A[j] + q[j] * m
39 | return A
40 |
--------------------------------------------------------------------------------
/interval_graph_coloring.py:
--------------------------------------------------------------------------------
1 | def interval_graph_coloring(graph):
2 | """
3 | The input graph is represented as an adjacency matrix since all we need is edge information about the graph
4 | """
5 | m = graph.shape[0]
6 | color = [1] * m
7 | number = 1
8 | for i in range(m):
9 | for j in range(m):
10 | if graph[i, j] == 1 and color[i] == color[j]:
11 | color[j] = color[i] + 1
12 | if color[j] > number:
13 | number = color[j]
14 | return color,number
15 |
--------------------------------------------------------------------------------
/inversion.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 |
5 | def inversion_with_insertion_sort(array):
6 | """
7 | Count number of inversions of an array using insertion sort
8 |
9 | Let A[1...n] be an array of n numbers. If i < j and A[i] > A[j] ,
10 | then the pair (i, j) is called an inversion_with_insertion_sort of A
11 | :param array:
12 | :return:
13 | """
14 | array = array[:]
15 | return _inversion_with_insertion_sort(array)
16 |
17 |
18 | def _inversion_with_insertion_sort(array):
19 | """
20 | :param array:
21 | :return:
22 | """
23 | inverse = 0
24 | for j in range(1, len(array)):
25 | key = array[j]
26 | i = j - 1
27 | while i >= 0 and key < array[i]:
28 | inverse += 1
29 | array[i + 1] = array[i]
30 | i = i - 1
31 | array[i + 1] = key
32 | return inverse
33 |
34 |
35 | def inversion_with_merge_sort(array):
36 | """
37 | Count number of inversions of an array using merge sort
38 |
39 | Let A[1...n] be an array of n numbers. If i < j and A[i] > A[j] ,
40 | then the pair (i, j) is called an inversion_with_insertion_sort of A
41 | :param array:
42 | :return:
43 | """
44 | array = array[:]
45 | return _inversion_with_merge_sort(array, 0, len(array) - 1)
46 |
47 |
48 | def _inversion_with_merge_sort(array, left, right):
49 | if left < right:
50 | mid = (left + right) // 2
51 | left_inverse = _inversion_with_merge_sort(array, left, mid)
52 | right_inverse = _inversion_with_merge_sort(array, mid + 1, right)
53 | inter_inverse = _merge(array, left, mid, right)
54 | return left_inverse + right_inverse + inter_inverse
55 | else:
56 | return 0
57 |
58 |
59 | def _merge(array, left, mid, right):
60 | """
61 |
62 | :param array:
63 | :param left:
64 | :param mid:
65 | :param right:
66 | :return:
67 | """
68 | left_part = array[left: mid + 1]
69 | left_part.append(float("Inf"))
70 | right_part = array[mid + 1: right + 1]
71 | right_part.append(float("Inf"))
72 | i = 0
73 | j = 0
74 | inverse = 0
75 | for k in range(left, right + 1):
76 | if left_part[i] <= right_part[j]:
77 | array[k] = left_part[i]
78 | i = i + 1
79 | else:
80 | array[k] = right_part[j]
81 | j = j + 1
82 | inverse += (mid - left + 1 - i)
83 | return inverse
84 |
85 |
--------------------------------------------------------------------------------
/inversion_tree.py:
--------------------------------------------------------------------------------
1 | from rank_tree import rank_tree, rank_node
2 |
3 |
4 | def inversion(A):
5 | inversion = 0
6 | i = 0
7 | T = rank_tree([])
8 | if isinstance(A, list):
9 | for key in A:
10 | i = i + 1
11 | x = rank_node(key, None, None, None, 0, 1)
12 | T.insert(x)
13 | # print( 'x.key = {}, x.rank = {}'.format(x.key, x.rank))
14 | inversion = inversion + i - x.rank
15 | return inversion
16 | else:
17 | print("Not invalid argument")
18 |
--------------------------------------------------------------------------------
/k_way_merge.py:
--------------------------------------------------------------------------------
1 | def merge(list1, list2):
2 | length1 = len(list1)
3 | length2 = len(list2)
4 | n = length1 + length2
5 | i = 0
6 | j = 0
7 | k = 0
8 | result = [0] * n
9 | while i < length1 and j < length2:
10 | if list1[i] <= list2[j]:
11 | result[k] = list1[i]
12 | i += 1
13 | else:
14 | result[k] = list2[j]
15 | j += 1
16 | k += 1
17 | if i == length1:
18 | while j < length2:
19 | result[k] = list2[j]
20 | k += 1
21 | j += 1
22 | elif j == length2:
23 | while i < length1:
24 | result[k] = list1[i]
25 | k += 1
26 | i += 1
27 | return result
28 |
29 |
30 | def k_way_merge(lists):
31 | """
32 | Merge k sorted lists and return it as one sorted list
33 | :param lists:
34 | :return:
35 | """
36 | length = len(lists)
37 | if length == 1:
38 | return lists[0]
39 | elif length == 2:
40 | return merge(lists[0], lists[1])
41 | else:
42 | list1 = k_way_merge(lists[:length // 2])
43 | list2 = k_way_merge(lists[length // 2:])
44 | return merge(list1, list2)
45 |
--------------------------------------------------------------------------------
/kleene_star.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from numpy import zeros
4 |
5 |
6 | def kleene_star(x, L, A):
7 | length = len(x)
8 | m = zeros((length, length))
9 | for l in range(1, length + 1):
10 | for i in range(1, length - l + 2):
11 | j = i + l - 1
12 | for k in range(i, j):
13 | if m[i - 1, k - 1] == 1 and m[k, j - 1] == 1:
14 | m[i - 1, j - 1] = 1
15 | if m[i - 1, j - 1] != 1:
16 | m[i - 1, j - 1] = A(x[i - 1:j], L)
17 | return m[0, length - 1] != 0
18 |
--------------------------------------------------------------------------------
/knapsack_0_1.py:
--------------------------------------------------------------------------------
1 | from numpy import zeros
2 |
3 |
4 | def knapsack_0_1(W, w, v):
5 | n = len(w)
6 | return knapsack_0_1_aux(W, w, v, 1, n)
7 |
8 |
9 | def knapsack_0_1_aux(W, w, v, m, n):
10 | """
11 | m: the first item
12 | n: the last item
13 | W: total weight
14 | w: the list of weights of items
15 | v: the list of values of items
16 | """
17 |
18 | # if m > n, then we have scanned all the items
19 | if m > n:
20 | return 0
21 | # if W <= 0, then we can't take any more items
22 | if W <= 0:
23 | return 0
24 | # We have two choices: take item m or not take item m
25 | if W < w[m - 1]:
26 | return knapsack_0_1_aux(W, w, v, m + 1, n)
27 | else:
28 | return max(knapsack_0_1_aux(W - w[m - 1], w, v, m + 1, n) + v[m - 1], knapsack_0_1_aux(W, w, v, m + 1, n))
29 |
30 |
31 | def knapsack_0_1_memoized(W, w, v):
32 | m = 1
33 | n = len(w)
34 | value = zeros((W + 1, n + 1))
35 | solution = zeros((W + 1, n + 1))
36 | for i in range(W + 1):
37 | for j in range(n + 1):
38 | value[i, j] = float("-Inf")
39 | knapsack_0_1_memoized_aux(W, w, v, m, n, value, solution)
40 | return value, solution
41 |
42 |
43 | def knapsack_0_1_memoized_aux(W, w, v, m, n, value, solution):
44 | if m > n:
45 | return 0
46 | if value[W, m] >= 0:
47 | return value[W, m]
48 | if W < w[m - 1]:
49 | value[W, m] = knapsack_0_1_memoized_aux(W, w, v, m + 1, n, value, solution)
50 | solution[W, m] = 0
51 | else:
52 | s = knapsack_0_1_memoized_aux(W - w[m - 1], w, v, m + 1, n, value, solution) + v[m - 1]
53 | t = knapsack_0_1_memoized_aux(W, w, v, m + 1, n, value, solution)
54 | if s > t:
55 | solution[W, m] = 1
56 | value[W, m] = max(s, t)
57 | return value[W, m]
58 |
59 |
60 | def print_knapsack_solution(solution, w):
61 | W = solution.shape[0] - 1
62 | n = solution.shape[1] - 1
63 | i = 1
64 | while W != 0 and i <= n:
65 | if solution[W, i] == 1:
66 | print(i)
67 | W = W - w[i - 1]
68 | i = i + 1
69 |
--------------------------------------------------------------------------------
/kth-Quantiles.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 |
3 | import math
4 | import random
5 | from randomized_select import randomized_select
6 | from quicksort import randomized_quicksort
7 |
8 |
9 | def kth_quantiles(A, B, k, p, r):
10 | if k > 0:
11 | n = r - p + 1
12 | location = math.floor(k / 2) * math.ceil(n / k)
13 | B[math.floor(k / 2)] = randomized_select(A, p, r, location)
14 | kth_quantiles(A, B, p, math.floor(k / 2) - 1, location - 1)
15 | kth_quantiles(A, B, math.floor(k / 2), location + 1, r)
16 |
17 |
18 | def median_of_two_arrays(X, x_start, x_end, Y, y_start, y_end, size):
19 | print(X[x_start:x_end + 1], '\t', Y[y_start:y_end + 1], '\t', size)
20 | if size == 1:
21 | return min(X[x_start], Y[y_start])
22 | xc = X[x_start + int(math.floor(size / 2)) - 1]
23 | yc = Y[y_start + int(math.ceil(size / 2)) - 1]
24 | print(xc, yc)
25 | if xc == yc:
26 | return xc
27 | elif xc < yc:
28 | return median_of_two_arrays(X, x_start + int(math.floor(size / 2)), x_end, Y, y_start, y_end,
29 | math.ceil(size / 2))
30 | else:
31 | return median_of_two_arrays(X, x_start, x_end, Y, y_start + int(math.ceil(size / 2)), y_end,
32 | math.floor(size / 2))
33 |
34 |
35 | if __name__ == '__main__':
36 | A = [random.randint(1, 100) for i in range(15)]
37 | print(A)
38 | randomized_quicksort(A, 0, 14)
39 | print(A)
40 | B = [random.randint(1, 100) for i in range(15)]
41 | print(B)
42 | randomized_quicksort(B, 0, 14)
43 | print(B)
44 | print(median_of_two_arrays(A, 0, 14, B, 0, 14, 3.0))
45 | # randomized_select(A, 0, 14, 7)
46 | # print( A)
47 | # for i in range(1, 16):
48 | # randomized_select(A, 0, 14, i)
49 | # print( i, '\t', A)
50 | # print( randomized_select(A, 0, 14, i))
51 |
--------------------------------------------------------------------------------
/linkedlist.py:
--------------------------------------------------------------------------------
1 | from typing import Any, Optional
2 |
3 |
4 | class LinkedListNode:
5 | def __init__(self, key: Any):
6 | self.key: Any = key
7 | self.prev: Optional[LinkedListNode] = None
8 | self.next: Optional[LinkedListNode] = None
9 |
10 |
11 | class LinkedList:
12 | def __init__(self, key=None):
13 | self.head: Optional[LinkedListNode] = None
14 | self.size: int = 0
15 | self.key = key
16 |
17 | def empty(self) -> bool:
18 | return self.size == 0
19 |
20 | def search(self, key: Any) -> Optional[LinkedListNode]:
21 | node = self.head
22 | while node and node.key != key:
23 | node = node.next
24 | return node
25 |
26 | def insert(self, node: LinkedListNode) -> None:
27 | self.size = self.size + 1
28 | node.next = self.head
29 | if self.head:
30 | self.head.prev = node
31 | self.head = node
32 | node.prev = None
33 |
34 | def delete(self, node: LinkedListNode) -> None:
35 | self.size = self.size - 1
36 | if node.prev:
37 | node.prev.next = node.next
38 | else:
39 | self.head = node.next
40 | if node.next:
41 | node.next.prev = node.prev
42 |
43 | def extract(self, node: LinkedListNode) -> LinkedListNode:
44 | self.delete(node)
45 | return node
46 |
--------------------------------------------------------------------------------
/longest_common_subsequence.py:
--------------------------------------------------------------------------------
1 | from numpy import zeros
2 |
3 |
4 | def lcs_length(X, Y):
5 | m = len(X)
6 | n = len(Y)
7 | c = zeros((m + 1, n + 1))
8 | b = zeros((m + 1, n + 1))
9 |
10 | for i in range(1, m + 1):
11 | for j in range(1, n + 1):
12 | if X[i - 1] == Y[j - 1]:
13 | c[i, j] = c[i - 1, j - 1] + 1
14 | b[i, j] = 0
15 | elif c[i - 1, j] >= c[i, j - 1]:
16 | c[i, j] = c[i - 1, j]
17 | b[i, j] = 1
18 | else:
19 | c[i, j] = c[i, j - 1]
20 | b[i, j] = 2
21 | return c, b
22 |
23 |
24 | def lcs_length_one_row(X, Y):
25 | m = len(X)
26 | n = len(Y)
27 | c = [0] * (n + 1)
28 |
29 | for i in range(1, m + 1):
30 | a = 0
31 | for j in range(1, n + 1):
32 | if X[i - 1] == Y[j - 1]:
33 | value = a + 1
34 | elif c[j] >= c[j - 1]:
35 | value = c[j]
36 | else:
37 | value = c[j - 1]
38 | a = c[j]
39 | c[j] = value
40 | return c[n]
41 |
42 |
43 | def print_lcs(b, X, i, j):
44 | if i == 0 or j == 0:
45 | return
46 | if b[i, j] == 0:
47 | print_lcs(b, X, i - 1, j - 1)
48 | print(X[i - 1], )
49 | elif b[i, j] == 1:
50 | print_lcs(b, X, i - 1, j)
51 | else:
52 | print_lcs(b, X, i, j - 1)
53 |
--------------------------------------------------------------------------------
/longest_monotonically_increasing_subsequence.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding=utf-8
3 |
4 | from longest_common_subsequence import lcs_length_one_row
5 |
6 | def longest_monotonically_increasing_subsequence(A):
7 | C = sorted(set(A))
8 | return lcs_length_one_row(A, C)
9 |
--------------------------------------------------------------------------------
/longest_palindrome_subsequence.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding=utf-8
3 |
4 | from longest_common_subsequence import lcs_length, print_lcs
5 |
6 |
7 | def longest_palindrome_subsequence(s):
8 | # c, b = lcs_length(s, s[::-1])
9 | # print(_lcs(b, s, len(s), len(s)))
10 | n = len(s)
11 | c = [[0] * n for _ in range(n)]
12 | for i in range(n):
13 | c[i][i] = 1
14 | for i in range(n - 1):
15 | if s[i] == s[i + 1]:
16 | c[i][i + 1] = 2
17 | else:
18 | c[i][i + 1] = 1
19 | for length in range(3, n + 1):
20 | for i in range(n - length + 1):
21 | j = i + length - 1
22 | if s[i] == s[j]:
23 | print(i, j, c[i + 1][j - 1])
24 | c[i][j] = 2 + c[i + 1][j - 1]
25 | else:
26 | c[i][j] = max(c[i][j - 1], c[i + 1][j])
27 | return c
28 |
29 |
30 | def print_lps(c, s):
31 | start = 0
32 | end = len(s) - 1
33 | l = []
34 | idx = []
35 | index = 0
36 | while start < end:
37 | if s[start] == s[end]:
38 | l.insert(index, s[end])
39 | l.insert(index, s[start])
40 | idx.insert(index, end)
41 | idx.insert(index, start)
42 | index += 1
43 | start += 1
44 | end -= 1
45 | elif c[start + 1][end] >= c[start][end - 1]:
46 | start += 1
47 | else:
48 | end -= 1
49 | if start == end:
50 | l.insert(index, s[start])
51 | idx.insert(index, start)
52 | return ''.join(l), idx
53 |
--------------------------------------------------------------------------------
/lowest_common_multiple.py:
--------------------------------------------------------------------------------
1 | from gcd import gcd
2 |
3 |
4 | def lcm(num1: int, num2: int):
5 | return num1 * num2 // gcd(num1, num2)
6 |
--------------------------------------------------------------------------------
/matrix_chain_order.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from numpy import zeros
4 |
5 |
6 | def bottom_up_matrix_chain_order(p):
7 | n = len(p) - 1
8 | m = zeros((n + 1, n + 1))
9 | s = zeros((n + 1, n + 1))
10 | for l in range(2, n + 1):
11 | for i in range(1, n - l + 2):
12 | j = i + l - 1
13 | m[i, j] = float("Inf")
14 | for k in range(i, j):
15 | q = m[i, k] + m[k + 1, j] + p[i - 1] * p[k] * p[j]
16 | if q < m[i, j]:
17 | m[i, j] = q
18 | s[i, j] = k
19 | return m, s
20 |
21 |
22 | def memoized_matrix_chain_order(p):
23 | n = len(p) - 1
24 | m = zeros((n + 1, n + 1))
25 | for i in range(1, n + 1):
26 | for j in range(1, n + 1):
27 | m[i, j] = float("Inf")
28 | return lookup_chain(m, p, 1, n)
29 |
30 |
31 | def lookup_chain(m, p, i, j):
32 | if m[i, j] < float("Inf"):
33 | return m[i, j]
34 | if i == j:
35 | m[i, j] = 0
36 | else:
37 | for k in range(i, j):
38 | q = lookup_chain(m, p, i, k) + lookup_chain(m, p,
39 | k + 1, j) + p[i - 1] * p[k] * p[j]
40 | if q < m[i, j]:
41 | m[i, j] = q
42 | return m[i, j]
43 |
44 |
45 | def print_optimal_parens(s, i, j):
46 | if i == j:
47 | print("A{}".format(int(i)), )
48 | else:
49 | print("(", )
50 | print_optimal_parens(s, i, s[i, j])
51 | print_optimal_parens(s, s[i, j] + 1, j)
52 | print(")", )
53 |
54 |
55 | # An incorrect greedy approach for matrix chain order problem
56 | def greedy_matrix_chain_order(p):
57 | n = len(p) - 1
58 | return greedy_matrix_chain_order_aux(p, 1, n)
59 |
60 |
61 | def greedy_matrix_chain_order_aux(p, i, j):
62 | if i == j:
63 | return 0
64 | q = float("Inf")
65 | for k in range(i, j):
66 | value = p[i - 1] * p[k] * p[j]
67 | if q > value:
68 | q = value
69 | pos = k
70 | return greedy_matrix_chain_order_aux(p, i, pos) + greedy_matrix_chain_order_aux(p, pos + 1, j) + q
71 |
--------------------------------------------------------------------------------
/matrix_pow.c:
--------------------------------------------------------------------------------
1 | // AUTHOR: WangQiang
2 | // DATE: 20140524
3 | // LAST UPDATE DATE: 20140525
4 | // EMAIL: cntqrxj@gmail.com
5 |
6 | #include
7 | #include
8 |
9 | void matrix_exp(int *A, int *B, int n, int pow) {
10 | int length = n * n;
11 | int *C;
12 | int i;
13 | void square_matrix_multiply(int *, int *, int *, int);
14 |
15 | if (pow == 1) {
16 | for (i = 0; i < length; i++)
17 | B[i] = A[i];
18 | return;
19 | }
20 | C = calloc(length, sizeof(int));
21 | matrix_exp(A, C, n, pow / 2);
22 | square_matrix_multiply(C, C, B, n);
23 | if (pow % 2) {
24 | for (i = 0; i < length; i++)
25 | C[i] = B[i];
26 | square_matrix_multiply(C, A, B, n);
27 | }
28 | free(C);
29 | return;
30 | }
31 |
--------------------------------------------------------------------------------
/max_subsequence_sum.c:
--------------------------------------------------------------------------------
1 | /* max_subsequence_sum: compute max subsequence sum of a[n]
2 | on-lines algorithms; O(n) */
3 | int max_subsequence_sum(int a[], unsigned n) {
4 | int this_sum, max_sum, best_i, best_j, i, j;
5 |
6 | i = this_sum = max_sum = 0; best_i = best_j = -1;
7 | for (j = 0; j < n; j++) {
8 | this_sum += a[j];
9 | if (this_sum > max_sum)
10 | { /* update max_sum, best_i, best_j */
11 | max_sum = this_sum;
12 | best_i = i;
13 | best_j = j;
14 | } else if (this_sum < 0) {
15 | i = j + 1;
16 | this_sum = 0;
17 | }
18 | }
19 | return max_sum;
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/maximum-subarray-brute-force.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | struct value {
5 | int low;
6 | int high;
7 | int sum;
8 | };
9 |
10 | //A brute-force solution to find maximum subarray: just try every possible pair
11 | struct value FIND_MAXIMUM_SUBARRAY(int A[], int low, int high) {
12 | int i, j;
13 | int left, right;
14 | int sum;
15 | int max_sum = INT_MIN;
16 | struct value max;
17 |
18 | for (i = low; i <= high; i++) {
19 | sum = 0;
20 | for (j = i; j <= high; j++) {
21 | sum = sum + A[j];
22 | if (sum >= max_sum) {
23 | left = i;
24 | right = j;
25 | max_sum = sum;
26 | }
27 | }
28 | }
29 | max.low = left;
30 | max.high = right;
31 | max.sum = max_sum;
32 | return max;
33 | }
34 |
35 | int main() {
36 | int a[17] = { 13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7, 0};
37 | struct value max;
38 | int b[17] = {100,113,110,85,105,102,86,63,81,101,94,106,101,79,94,90,97};
39 | int c[16];
40 | int d[6] = {-6, -100, -8, -2, -5, -1};
41 | int i;
42 |
43 | for (i = 0; i < 16; i++)
44 | c[i] = b[i + 1] - b[i];
45 | max = FIND_MAXIMUM_SUBARRAY(a, 0, 16);
46 | printf("%d, %d, %d, %d, %d\n", max.low, max.high, max.sum, a[max.low], a[max.high]);
47 | max = FIND_MAXIMUM_SUBARRAY(c, 0, 15);
48 | printf("%d, %d, %d, %d, %d, %d, %d\n", max.low, max.high, max.sum, a[max.low], a[max.high], b[max.low], b[max.high + 1]);
49 | max = FIND_MAXIMUM_SUBARRAY(d, 0, 5);
50 | printf("%d, %d, %d\n", max.low, max.high, max.sum);
51 | return 0;
52 | }
53 |
--------------------------------------------------------------------------------
/maximum-subarray-inline.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | struct value {
5 | int low;
6 | int high;
7 | int sum;
8 | };
9 |
10 | //An inline solution to find maximum subarray
11 | //FIND_MAXIMUM_SUBARRAY(A, low, high)
12 | // sum = A[low]
13 | // left = low
14 | // right = high
15 | // max-endpoint-sum = NEGATIVE INFINITE
16 | // for i = low to high
17 | // if max-endpoint-sum >= 0
18 | // max-endpoint-sum = max-endpoint-sum + A[i]
19 | // max-endpoint-high = i
20 | // else
21 | // max-endpoint-sum = A[i]
22 | // max-endpoint-low = max-endpoint-high = i
23 | // if max-endpoint-sum > sum
24 | // sum = max-endpoint-sum
25 | // left = max-endpoint-low
26 | // right = max-endpoint-high
27 | // return(left, right, sum)
28 | struct value FIND_MAXIMUM_SUBARRAY(int A[], int low, int high) {
29 | struct value max_endpoint, max;
30 | int i;
31 |
32 | max.sum = A[low];
33 | max.low = low;
34 | max.high = high;
35 | max_endpoint.sum = INT_MIN;
36 |
37 | for (i = low; i <= high; i++) {
38 | if (max_endpoint.sum >= 0) {
39 | max_endpoint.sum = max_endpoint.sum + A[i];
40 | max_endpoint.high = i;
41 | }
42 | else {
43 | max_endpoint.sum = A[i];
44 | max_endpoint.low = max_endpoint.high = i;
45 | }
46 | if (max_endpoint.sum > max.sum) {
47 | max.sum = max_endpoint.sum;
48 | max.low = max_endpoint.low;
49 | max.high = max_endpoint.high;
50 | }
51 | }
52 | return max;
53 | }
54 |
55 | int main() {
56 | int a[17] = { 13, -3, -25, -20, -3, -16, 23, 18, 20, -7, 12, -5, 22, -15, -4, 7, 0};
57 | int b[9] = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
58 | struct value max;
59 |
60 | max = FIND_MAXIMUM_SUBARRAY(a, 0, 16);
61 | printf("%d, %d, %d, %d, %d\n", max.low, max.high, max.sum, a[max.low], a[max.high]);
62 | max = FIND_MAXIMUM_SUBARRAY(b, 0, 8);
63 | printf("%d, %d, %d, %d, %d\n", max.low, max.high, max.sum, b[max.low], b[max.high]);
64 | return 0;
65 | }
66 |
--------------------------------------------------------------------------------
/maximum-subarray-recursive.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | struct value {
5 | int low;
6 | int high;
7 | int sum;
8 | };
9 |
10 | //FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)
11 | // left-sum = NEGATIVE INFINITE
12 | // sum = 0
13 | // for i = mid downto low
14 | // sum = sum + A[i]
15 | // if sum > left-sum
16 | // left-sum = sum
17 | // max-left = i
18 | // right-sum = NEGATIVE INFINITE
19 | // sum = 0
20 | // for j = mid + 1 to high
21 | // sum = sum + A[j]
22 | // if sum > right-sum
23 | // right-sum = sum
24 | // max-right = j
25 | // return(max-left,max-right,left-sum + right-sum)
26 |
27 |
28 | struct value FIND_MAX_CROSSING_SUBARRAY(int A[], int low, int mid, int high) {
29 | int left_sum = INT_MIN;
30 | int right_sum = INT_MIN;
31 | int max_left, max_right;
32 | int sum = 0;
33 | int i;
34 | struct value cross;
35 | for(i = mid; i >= low; i--) {
36 | sum = sum + A[i];
37 | if (sum >= left_sum)
38 | { left_sum = sum;
39 | max_left = i;
40 | }
41 | }
42 | sum = 0;
43 | for (i = mid + 1; i <= high; i++) {
44 | sum = sum + A[i];
45 | if (sum >= right_sum) {
46 | right_sum = sum;
47 | max_right = i;
48 | }
49 | }
50 | cross.low = max_left;
51 | cross.high = max_right;
52 | cross.sum = left_sum + right_sum;
53 | return cross;
54 | // printf("%d, %d, %d\n", max_left, max_right, left_sum + right_sum);
55 | }
56 |
57 | //FIND-MAXIMUM-SUBARRAY(A, low, high)
58 | // if high == low
59 | // return(low, high, A[low])
60 | // else mid = floor of (low + high) / 2
61 | // (left-low, left-high, left-sum) =
62 | // FIND-MAXIMUM-SUBARRAY(A, low, mid)
63 | // (right-low, right-high, right-sum) =
64 | // FIND-MAXIMUM-SUBARRAY(A, mid + 1, high)
65 | // (cross-low, cross-high, cross-sum) =
66 | // FIND-MAXIMUM-SUBARRAY(A, low, mid, high)
67 | // if left-sum >= right-sum and left-sum >= cross-sum
68 | // return(left-low, left-high, left-sum)
69 | // elseif right-sum >= left-sum and right-sum >= cross-sum
70 | // return(right-low, right-high, right-sum)
71 | // else return(cross-low, cross-high, cross-sum)
72 |
73 | struct value FIND_MAXIMUM_SUBARRAY(int A[], int low, int high) {
74 | struct value left, right, cross;
75 | int mid;
76 |
77 | if (low == high) {
78 | left.low = low;
79 | left.high = high;
80 | left.sum = A[low];
81 | return left;
82 | }
83 | else {
84 | mid = (low + high) / 2;
85 | left = FIND_MAXIMUM_SUBARRAY(A, low, mid);
86 | cross = FIND_MAX_CROSSING_SUBARRAY(A, low, mid, high);
87 | right = FIND_MAXIMUM_SUBARRAY(A, mid + 1, high);
88 | if (left.sum >= right.sum && left.sum >= cross.sum)
89 | return left;
90 | else if (right.sum >= left.sum && right.sum >= cross.sum)
91 | return right;
92 | else
93 | return cross;
94 | }
95 | }
96 | int main() {
97 | //int a[17] = { 13, -3, -25, -20, -3, -16, 23, 18, 20, -7, 12, -5, 22, -15, -4, 7, 0};
98 | struct value max;
99 | int b[6] = {-6, -2, -2, -2, -10, -1};
100 | //
101 | //max = FIND_MAXIMUM_SUBARRAY(a, 0, 16);
102 | max = FIND_MAXIMUM_SUBARRAY(b, 0, 5);
103 | //printf("%d, %d, %d, %d, %d\n", max.low, max.high, max.sum, a[max.low], a[max.high]);
104 | printf("%d, %d, %d\n", max.low, max.high, max.sum);
105 | return 0;
106 | }
107 |
--------------------------------------------------------------------------------
/memoized_cut_rod.py:
--------------------------------------------------------------------------------
1 | def memoized_cut_rod(p, n):
2 | r = [float("-Inf")] * (n + 1)
3 | return memoized_cut_rod_aux(p, n, r)
4 |
5 |
6 | def memoized_cut_rod_aux(p, n, r):
7 | if r[n] >= 0:
8 | return r[n]
9 | if n == 0:
10 | q = 0
11 | else:
12 | q = float("-Inf")
13 | for i in range(1, n + 1):
14 | q = max(q, p[i - 1] + memoized_cut_rod_aux(p, n - i, r))
15 | r[n] = q
16 | return q
17 |
--------------------------------------------------------------------------------
/merge.py:
--------------------------------------------------------------------------------
1 | def merge_with_sentinel(array, left, mid, right):
2 | """
3 | merge procedure with sentinels
4 |
5 | merge array[left...mid] and array[mid + 1...right]
6 | :param array:
7 | :param left:
8 | :param mid:
9 | :param right:
10 | :return:
11 | """
12 | left_part = array[left: mid + 1]
13 | left_part.append(float("Inf"))
14 | right_part = array[mid + 1: right + 1]
15 | right_part.append(float("Inf"))
16 | i = 0
17 | j = 0
18 | for k in range(left, right + 1):
19 | if left_part[i] <= right_part[j]:
20 | array[k] = left_part[i]
21 | i += 1
22 | else:
23 | array[k] = right_part[j]
24 | j += 1
25 |
26 |
27 | def merge_without_sentinel(array, left, mid, right):
28 | """
29 | merge procedure without sentinels
30 |
31 | A merge procedure without sentinels that stops once either array `left_part` or `right_part` has had all its elements
32 | copied back to `array` and then copying the remainder of another array back into `array`
33 | :param array:
34 | :param left:
35 | :param mid:
36 | :param right:
37 | :return:
38 | """
39 | left_part = array[left: mid + 1]
40 | right_part = array[mid + 1: right + 1]
41 | i = 0
42 | j = 0
43 | k = left
44 | while i < len(left_part) and j < len(right_part):
45 | if left_part[i] <= right_part[j]:
46 | array[k] = left_part[i]
47 | k += 1
48 | i += 1
49 | else:
50 | array[k] = right_part[j]
51 | k += 1
52 | j += 1
53 | if i < len(left_part):
54 | array[k: right + 1] = left_part[i:]
55 | else:
56 | array[k: right + 1] = right_part[j:]
--------------------------------------------------------------------------------
/merge_sort.py:
--------------------------------------------------------------------------------
1 | from insertion_sort import insertion_sort
2 | from merge import merge_with_sentinel
3 |
4 |
5 | def merge_sort(array, merge_method=merge_with_sentinel):
6 | """
7 | inplace O(nlgn) sort
8 | :param array:
9 | :param merge_method:
10 | :return:
11 | """
12 | _merge_sort(array, 0, len(array) - 1, merge_method)
13 |
14 |
15 | def _merge_sort(array, left, right, merge_method):
16 | if left < right:
17 | mid = (left + right) // 2
18 | _merge_sort(array, left, mid, merge_method)
19 | _merge_sort(array, mid + 1, right, merge_method)
20 | merge_method(array, left, mid, right)
21 |
22 |
23 | def merge_ins_sort_bottom_to_top(array, partition: int = 2):
24 | """
25 | Although merge sort runs faster than insertion sort asymptotically,
26 | the constant factors in insertion sort can make it faster in practice for small problem sizes on many machines.
27 | Thus, it makes sense to coarsen the leaves of the recursion by using insertion sort within merge sort when
28 | subproblems become sufficiently small. Consider a modification to merge sort in which n/k sublists of length k are
29 | sorted using insertion sort and then merged using the standard merging mechanism, where k is a value to be determined.
30 |
31 | bottom to top version with number of sublists specified
32 | :param array:
33 | :param partition: number of sublists
34 | :return:
35 | """
36 | assert partition > 0
37 | n = len(array)
38 | sublist_length = n // partition
39 | sublist_number = partition
40 | for i in range(sublist_number):
41 | left = sublist_length * i
42 | right = min(sublist_length * (i + 1) - 1, n - 1)
43 | insertion_sort(array, left, right)
44 | while sublist_number > 1:
45 | for i in range(0, sublist_number - 1, 2):
46 | merge_with_sentinel(array, sublist_length * i, sublist_length * (i + 1) - 1,
47 | min(sublist_length * (i + 2) - 1, n - 1))
48 | sublist_length *= 2
49 | sublist_number = sublist_number // 2
50 |
51 |
52 | def merge_ins_sort_top_to_bottom(array, sublist_length):
53 | """
54 | Although merge sort runs faster than insertion sort asymptotically, the constant factors in insertion sort can make
55 | it faster in practice for small problem sizes on many machines.
56 | Thus, it makes sense to coarsen the leaves of the recursion by using insertion sort within merge sort when
57 | subproblems become sufficiently small. Consider a modification to merge sort in which n/k sublists of length k are
58 | sorted using insertion sort and then merged using the standard merging mechanism, where k is a value to be determined.
59 |
60 | top to bottom version with sublist length specified
61 | :param array:
62 | :param sublist_length:
63 | :return:
64 | """
65 | n = len(array)
66 | assert 0 < sublist_length < n
67 | _merge_ins_sort_top_to_bottom(array, 0, n - 1, sublist_length)
68 |
69 |
70 | def _merge_ins_sort_top_to_bottom(array, start, end, sublist_length):
71 | """
72 |
73 | :param array:
74 | :param start:
75 | :param end:
76 | :param sublist_length:
77 | :return:
78 | """
79 | length = end - start + 1
80 | if length > sublist_length:
81 | mid = (start + end) // 2
82 | _merge_ins_sort_top_to_bottom(array, start, mid, sublist_length)
83 | _merge_ins_sort_top_to_bottom(array, mid + 1, end, sublist_length)
84 | merge_with_sentinel(array, start, mid, end)
85 | else:
86 | insertion_sort(array, start, end)
87 |
--------------------------------------------------------------------------------
/min_heap_with_linked_list.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 |
4 | class MinHeap(list):
5 | def __init__(self, data):
6 | list.__init__(self, data)
7 | self.length = len(data)
8 | self.heap_size = self.length
9 | self.build_min_heap()
10 |
11 | def __contains__(self, y):
12 | return y in self[0:self.heap_size]
13 |
14 | def left(self, i):
15 | return 2 * i + 1
16 |
17 | def right(self, i):
18 | return 2 * i + 2
19 |
20 | def parent(self, i):
21 | return (i - 1) / 2
22 |
23 | def min_heapify(self, i):
24 | l = self.left(i)
25 | r = self.right(i)
26 | if (l <= (self.heap_size - 1)) and (self[l].key < self[i].key):
27 | smallest = l
28 | else:
29 | smallest = i
30 | if (r <= (self.heap_size - 1)) and (self[r].key < self[smallest].key):
31 | smallest = r
32 | if smallest != i:
33 | self[i], self[smallest] = self[smallest], self[i]
34 | self.min_heapify(smallest)
35 |
36 | def build_min_heap(self):
37 | self.heap_size = self.length
38 | for i in range(self.length // 2 - 1, -1, -1):
39 | self.min_heapify(i)
40 |
41 |
42 | class MinPriorityQueue(MinHeap):
43 | def heap_minimum(self):
44 | return self[0].head
45 |
46 | def heap_extract_min(self):
47 | if self.heap_size < 1:
48 | sys.exit("heap underflow")
49 | minimum = self[0].extract(self[0].head)
50 | if self[0].empty():
51 | self[0] = self[self.heap_size - 1]
52 | self.heap_size = self.heap_size - 1
53 | self.min_heapify(0)
54 | return minimum
55 |
56 | def heap_decrease_key(self, i, element, key):
57 | if key > self[i]:
58 | sys.exit("new key is larger than current key")
59 | self[i] = key
60 | while i > 0 and self[self.parent(i)] > self[i]:
61 | tmp = self[self.parent(i)]
62 | self[self.parent(i)] = self[i]
63 | self[i] = tmp
64 | i = self.parent(i)
65 |
66 | def min_heap_insert(self, key):
67 | if self.heap_size >= self.length:
68 | sys.exit("heap overflow")
69 | self.heap_size = self.heap_size + 1
70 | self[self.heap_size - 1] = float("Inf")
71 | self.heap_decrease_key(self.heap_size - 1, key)
72 |
--------------------------------------------------------------------------------
/min_heap_with_linked_list_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from min_heap_with_linked_list import min_heap, min_priority_queue
3 | from linkedlist import LinkedList, LinkedListNode
4 |
5 |
6 | class TestHeap(unittest.TestCase):
7 | def test_min_heapify(self):
8 | L1 = LinkedList(1)
9 | L2 = LinkedList(2)
10 | L2.insert(LinkedListNode(2))
11 | L2.insert(LinkedListNode(2))
12 | L3 = LinkedList(3)
13 | L3.insert(LinkedListNode(3))
14 | L3.insert(LinkedListNode(3))
15 | L4 = LinkedList(4)
16 | L4.insert(LinkedListNode(4))
17 | L5 = LinkedList(5)
18 | L3.insert(LinkedListNode(5))
19 | L3.insert(LinkedListNode(5))
20 | L3.insert(LinkedListNode(5))
21 | h = min_heap([L5, L1, L2, L3, L4])
22 | h.min_heapify(0)
23 | self.assertEqual(h, [L1, L3, L2, L5, L4])
24 |
25 | def test_build_min_heap(self):
26 | L1 = LinkedList(1)
27 | L2 = LinkedList(2)
28 | L2.insert(LinkedListNode(2))
29 | L2.insert(LinkedListNode(2))
30 | L3 = LinkedList(3)
31 | L3.insert(LinkedListNode(3))
32 | L3.insert(LinkedListNode(3))
33 | L4 = LinkedList(4)
34 | L4.insert(LinkedListNode(4))
35 | L5 = LinkedList(5)
36 | L3.insert(LinkedListNode(5))
37 | L3.insert(LinkedListNode(5))
38 | L3.insert(LinkedListNode(5))
39 | h = min_heap([L3, L4, L5, L2, L1])
40 | h.build_min_heap()
41 | self.assertEqual(h, [L1, L2, L5, L3, L4])
42 |
43 | def test_heap_minimum(self):
44 | L1 = LinkedList(1)
45 | L1.insert(LinkedListNode(1))
46 | L1.insert(LinkedListNode(1))
47 | L2 = LinkedList(2)
48 | L2.insert(LinkedListNode(2))
49 | L2.insert(LinkedListNode(2))
50 | L3 = LinkedList(3)
51 | L3.insert(LinkedListNode(3))
52 | L3.insert(LinkedListNode(3))
53 | L4 = LinkedList(4)
54 | L4.insert(LinkedListNode(4))
55 | L5 = LinkedList(5)
56 | L3.insert(LinkedListNode(5))
57 | L3.insert(LinkedListNode(5))
58 | L3.insert(LinkedListNode(5))
59 | q = min_priority_queue([L1, L2, L3, L4, L5])
60 | self.assertEqual(q.heap_minimum().key, 1)
61 |
62 | def test_heap_extract_min(self):
63 | L1 = LinkedList(1)
64 | L1.insert(LinkedListNode(1))
65 | L1.insert(LinkedListNode(1))
66 | L2 = LinkedList(2)
67 | L2.insert(LinkedListNode(2))
68 | L2.insert(LinkedListNode(2))
69 | L3 = LinkedList(3)
70 | L3.insert(LinkedListNode(3))
71 | L3.insert(LinkedListNode(3))
72 | L4 = LinkedList(4)
73 | L4.insert(LinkedListNode(4))
74 | L5 = LinkedList(5)
75 | L3.insert(LinkedListNode(5))
76 | L3.insert(LinkedListNode(5))
77 | L3.insert(LinkedListNode(5))
78 | q = min_priority_queue([L1, L2, L3, L4, L5])
79 | self.assertEqual(q.heap_extract_min().key, 1)
80 | self.assertEqual(q, [L1, L2, L3, L4, L5])
81 | self.assertEqual(q.heap_extract_min().key, 1)
82 | self.assertEqual(q, [L2, L4, L3, L5, L5])
83 | # def test_heap_decrease_key(self):
84 | # a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16]
85 | # q = MinPriorityQueue(a)
86 | # q.heap_decrease_key(8, 1)
87 | # self.assertEqual(q, [1, 1, 3, 2, 7, 8, 9, 10, 4, 16])
88 | # def test_heap_insert(self):
89 | # a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16]
90 | # q = MinPriorityQueue(a)
91 | # q.heap_extract_min()
92 | # q.min_heap_insert(0)
93 | # self.assertEqual(q, [0, 2, 3, 10, 4, 8, 9, 16, 14, 7])
94 |
--------------------------------------------------------------------------------
/min_priority_queue_using_rb_tree.py:
--------------------------------------------------------------------------------
1 | from rb_tree import RbTree
2 | import sys
3 |
4 |
5 | class min_priority_queue(RbTree):
6 | def heap_minimum(self):
7 | return self.minimum()
8 |
9 | def heap_extract_min(self):
10 | x = self.minimum()
11 | self.delete(x)
12 | return x
13 |
14 | def heap_decrease_key(self, node, key):
15 | if key > node.key:
16 | sys.exit("new key is larger than current key")
17 | self.delete(node)
18 | node.key = key
19 | self.insert(node)
20 |
21 | def min_heap_insert(self, node):
22 | self.insert(node)
23 |
--------------------------------------------------------------------------------
/mod_exp.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | unsigned long modular_exponentiation(unsigned long a, unsigned long b, unsigned long n) {
4 | unsigned long c = 0;
5 | unsigned long d = 1;
6 | int k = sizeof(unsigned long) * 8 - 1;
7 | unsigned long mask = 1 << k;
8 | unsigned long shift = b;
9 | int i;
10 | for (i = k; i >= 0; i--) {
11 | c = 2 * c;
12 | d = (d * d) % n;
13 | if ((shift & mask) == mask)
14 | {
15 | c = c + 1;
16 | d = (d * a) % n;
17 | }
18 | shift = shift << 1;
19 | }
20 | return d;
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/most_reliable_path.py:
--------------------------------------------------------------------------------
1 | from graph import max_priority_queue
2 |
3 |
4 | def most_reliable_path(G, r, s):
5 | """
6 | We are given a directed graph G = (V, E) on which
7 | each edge (u, v) that belongs to E has an associated
8 | value r(u, v), which is a real number in the range
9 | 0 <= r(u, v) <= 1 that represents the reliability
10 | of a communication channel from vertex u to vertex v.
11 | We interpret r(u, v) as the probability that the channel
12 | from u to v will not fail, and we assume that these
13 | probabilities are independent.
14 | This is an algorithm to find the most reliable
15 | path from the source to other vertices.
16 |
17 | s: the source
18 | r: the function that returns the probability that the
19 | channel from u to v will not fail.
20 | """
21 | initialize_single_source(G, s)
22 | S = set()
23 | Q = max_priority_queue(G.vertices, 'r')
24 | while Q.heap_size > 0:
25 | u = Q.heap_extract_max()
26 | S = S.union({u})
27 | for v in G.adj[u]:
28 | if v.r < u.r * r(u, v):
29 | v.r = u.r * r(u, v)
30 | v.p = u
31 | Q.heap_increase_key(v.index, u.r * r(u, v))
32 |
33 |
34 | def initialize_single_source(G, s):
35 | for v in G.vertices:
36 | v.r = 0
37 | v.p = None
38 | s.r = 1
39 |
--------------------------------------------------------------------------------
/optimal_binary_search_tree.py:
--------------------------------------------------------------------------------
1 | from numpy import zeros
2 |
3 |
4 | def optimal_bst(p, q, n):
5 | e = zeros((n + 2, n + 1))
6 | w = zeros((n + 2, n + 1))
7 | root = zeros((1 + n, 1 + n))
8 | for i in range(1, n + 2):
9 | print("i = {}".format(i))
10 | e[i, i - 1] = q[i - 1]
11 | w[i, i - 1] = q[i - 1]
12 | for l in range(1, n + 1):
13 | for i in range(1, n - l + 2):
14 | j = i + l - 1
15 | e[i, j] = float("Inf")
16 | w[i, j] = w[i, j - 1] + p[j - 1] + q[j]
17 | for r in range(i, j + 1):
18 | t = e[i, r - 1] + e[r + 1, j] + w[i, j]
19 | if t < e[i, j]:
20 | e[i, j] = t
21 | root[i, j] = r
22 | return e, root
23 |
24 |
25 | def construct_optimal_bst(root):
26 | n = root.shape[1] - 1
27 | r = root[1, n]
28 | print("k{} is the root".format(int(r)))
29 | construct_optimal_bst_aux(root, r, 1, r - 1)
30 | construct_optimal_bst_aux(root, r, r + 1, n)
31 |
32 |
33 | def construct_optimal_bst_aux(root, p, i, j):
34 | if j < p:
35 | if i <= j:
36 | r = root[i, j]
37 | print("k{} is the left child of k{}".format(int(r), int(p)))
38 | construct_optimal_bst_aux(root, r, i, r - 1)
39 | construct_optimal_bst_aux(root, r, r + 1, j)
40 | else:
41 | print("d{} is the left child of k{}".format(int(j), int(p)))
42 | if i > p:
43 | if i <= j:
44 | r = root[i, j]
45 | print("k{} is the right child of k{}".format(int(r), int(p)))
46 | construct_optimal_bst_aux(root, r, i, r - 1)
47 | construct_optimal_bst_aux(root, r, r + 1, j)
48 | else:
49 | print("d{} is the right child of k{}".format(int(j), int(p)))
50 |
--------------------------------------------------------------------------------
/parallel_fib.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | int p_fib(int n)
6 | {
7 | int x, y;
8 |
9 | printf("%d\n", omp_get_nested());
10 | if (n <= 1)
11 | return n;
12 | else
13 | {
14 | //The values of private data are undefined upon entry to and exit from the specific construct
15 | //So x and y should be declared shared
16 | #pragma omp parallel sections shared(n, x, y)
17 | {
18 | #pragma omp section
19 | x = p_fib(n - 1);
20 | #pragma omp section
21 | y = p_fib(n - 2);
22 | }
23 | return x + y;
24 | }
25 | }
26 |
27 | int main(int argc, char *argv[])
28 | {
29 | printf("%d\n", omp_get_nested());
30 | omp_set_nested(1);
31 | printf("%d\n", p_fib(atoi(argv[1])));
32 | return 0;
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/parallel_mat_vec.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | //Multiply matrix A of size n * n by vector x of length n, return vector y of length n
6 | int *p_mat_vec(int *A, int *x, int n)
7 | {
8 | int *y = (int *) malloc(sizeof(int) * n);
9 | int i, j;
10 | #pragma omp parallel shared(A, x, n) private(i, j)
11 | {
12 | #pragma omp for
13 | for (i = 0; i < n; i++)
14 | y[i] = 0;
15 | #pragma omp for
16 | for (i = 0; i < n; i++)
17 | for (j = 0; j < n; j++)
18 | y[i] = y[i] + A[i * n + j] * x[j];
19 | }
20 | return y;
21 | }
22 |
23 | int main(int argc, char *argv[])
24 | {
25 | int * p_mat_vec(int *A, int *x, int n);
26 | int i, j, n;
27 | int *A, *x, *y;
28 | printf("Please give n: ");
29 | scanf("%d",&n);
30 | if ( (A=(int *)malloc(n * n *sizeof(int))) == NULL )
31 | perror("memory allocation for a");
32 | if ( (x=(int *)malloc(n*sizeof(int))) == NULL )
33 | perror("memory allocation for b");
34 | printf("Initializing matrix A and vector x\n");
35 | for (j=0; j
2 | #include
3 | #include
4 | #include
5 |
6 | int binary_search(int x, int *T, int p, int r)
7 | {
8 | int low = p;
9 | int high = (p < (r + 1) ? (r + 1) : p);
10 | int mid;
11 |
12 | while (low < high)
13 | {
14 | mid = (low + high) / 2;
15 | if (x <= T[mid])
16 | high = mid;
17 | else
18 | low = mid + 1;
19 | }
20 | return high;
21 | }
22 |
23 | void swap(int *p1, int *p2)
24 | {
25 | int tmp = *p1;
26 |
27 | *p1 = *p2;
28 | *p2 = tmp;
29 | return;
30 | }
31 |
32 | void parallel_merge(int *T, int p1, int r1, int p2, int r2, int *A, int p3)
33 | {
34 | int q1, q2, q3;
35 | int n1 = r1 - p1 + 1;
36 | int n2 = r2 - p2 + 1;
37 |
38 | if (n1 < n2)
39 | {
40 | swap(&p1, &p2);
41 | swap(&r1, &r2);
42 | swap(&n1, &n2);
43 | }
44 | if (n1 == 0)
45 | return;
46 | else
47 | {
48 | q1 = (p1 + r1) / 2;
49 | q2 = binary_search(T[q1], T, p2, r2);
50 | q3 = p3 + (q1 - p1) + (q2 - p2);
51 | A[q3] = T[q1];
52 | #pragma omp parallel sections shared(T, p1, q1, p2, q2, A, p3, q3)
53 | {
54 | #pragma omp section
55 | parallel_merge(T, p1, q1 - 1, p2, q2 - 1, A, p3);
56 | #pragma omp section
57 | parallel_merge(T, q1 + 1, r1, q2, r2, A, q3 + 1);
58 | }
59 | return;
60 | }
61 | }
62 | void parallel_merge_sort(int *A, int p, int r, int *B, int s)
63 | {
64 | int n = r - p + 1;
65 |
66 | if (n == 1)
67 | {
68 | B[s] = A[p];
69 | return;
70 | }
71 | else
72 | {
73 | int *T = (int *) malloc(sizeof(int) * n);
74 | int q1 = (p + r) / 2;
75 | int q2 = q1 - p + 1;
76 |
77 | #pragma omp parallel sections shared(A, p, q1, T, r, q2)
78 | {
79 | #pragma omp section
80 | parallel_merge_sort(A, p, q1, T, 0);
81 | #pragma omp section
82 | parallel_merge_sort(A, q1 + 1, r, T, q2);
83 | }
84 | parallel_merge(T, 0, q2 - 1, q2, n - 1, B, s);
85 | free(T);
86 | return;
87 | }
88 | }
89 |
90 | int main(int argc, char *argv[])
91 | {
92 | int i;
93 | int n = atoi(argv[1]);
94 | int a[n];
95 | int b[n];
96 |
97 | omp_set_nested(1);
98 | srand(time(NULL));
99 | for (i = 0; i < n; i++)
100 | {
101 | a[i] = rand();
102 | }
103 | for (i = 0; i < n; i++)
104 | printf("%d\t", a[i]);
105 | printf("\n\n");
106 | parallel_merge_sort(a, 0, n - 1, b, 0);
107 | for (i = 0; i < n; i++)
108 | printf("%d\t", b[i]);
109 | return 0;
110 | }
111 |
--------------------------------------------------------------------------------
/parallel_square_matrix_multiply.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | int *parallel_square_matrix_multiply(int *A, int *B, int n)
6 | {
7 | int *C = (int *) malloc(sizeof(int) * n * n);
8 | int i, j, k;
9 |
10 | #pragma omp parallel for shared(A, B, C, n) private(i, j, k)
11 | for (i = 0; i < n; i++)
12 | //If a thread in a team executing a parallel region encounters another parallel con-
13 | //struct, it creates a new team and becomes the master of that new team.
14 | //So the parallel construct is needed, insted of work-sharing region
15 | #pragma omp parallel for shared(i)
16 | for (j = 0; j < n; j++)
17 | {
18 | printf("%d\n", i);
19 | C[i * n + j] = 0;
20 | for (k = 0; k < n; k++)
21 | C[i * n + j] = C[i * n + j] + A[i * n + k] * B[k * n + j];
22 | }
23 | return C;
24 | }
25 |
26 | int main(int argc, char *argv[])
27 | {
28 | int i, j, n;
29 | int *A, *B, *C;
30 | printf("Please give n: ");
31 | scanf("%d",&n);
32 | if ( (A=(int *)malloc(n * n *sizeof(int))) == NULL )
33 | perror("memory allocation for matrix A");
34 | if ( (B=(int *)malloc(n * n *sizeof(int))) == NULL )
35 | perror("memory allocation for matrix B");
36 | printf("Initializing matrix A and matrix B\n");
37 | for (i=0; i x. The return value is the median of the second part.
18 | So the return value is (left + right) // 2 when all elements in the array A[left .. right] have the same value. Partition in place.
19 | """
20 | x = array[right]
21 | i = left - 1
22 | k = i
23 | for j in range(left, right):
24 | if array[j] < x:
25 | i = i + 1
26 | array[i], array[j] = array[j], array[i]
27 | k = k + 1
28 | if i != k:
29 | array[j], array[k] = array[k], array[j]
30 | elif array[j] == x:
31 | k = k + 1
32 | array[k], array[j] = array[j], array[k]
33 | array[k + 1], array[right] = array[right], array[k + 1]
34 | return (k + 2 + i) // 2
35 |
36 |
37 | def partition3(array, left, right):
38 | """
39 | Variant of partition. Requires O(n) extra space, but it is easier to implement.
40 | """
41 | pivot = array[right]
42 | left_part = [array[i] for i in range(left, right) if array[i] <= pivot]
43 | right_part = [array[i] for i in range(left, right) if array[i] > pivot]
44 | pivot_index = left + len(left_part)
45 | array[left:pivot_index] = left_part[:]
46 | array[pivot_index + 1:right + 1] = right_part[:]
47 | array[pivot_index] = pivot
48 | return pivot_index
49 |
50 |
51 | def randomized_partition(array, left, right):
52 | i = random.randint(left, right)
53 | array[i], array[right] = array[right], array[i]
54 | return partition(array, left, right)
55 |
--------------------------------------------------------------------------------
/polar_angle.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from heap import MaxHeap
4 |
5 |
6 | class Vector:
7 | def __init__(self, p2, p1=(0, 0)):
8 | self.x = p2[0] - p1[0]
9 | self.y = p2[1] - p1[0]
10 |
11 | def cross_product(self, v):
12 | return self.x * v.y - v.x * self.y
13 |
14 | def __lt__(self, v):
15 | return self.cross_product(v) > 0
16 |
17 | def __gt__(self, v):
18 | return self.cross_product(v) < 0
19 |
20 | def __eq__(self, v):
21 | return self.cross_product(v) == 0
22 |
23 | def __le__(self, v):
24 | return self.cross_product(v) >= 0
25 |
26 | def __ge__(self, v):
27 | return self.cross_product(v) <= 0
28 |
29 |
30 | def polar_angle(p0, point_list):
31 | """sort a sequence of n points according to
32 | their polar angles with respect to a given origin point p0.
33 | """
34 | v0 = Vector((p0[0] + 1, p0[1]), p0) # The polar angle of v0 is 0
35 | vector_list = [Vector(p, p0) for p in point_list]
36 | angle_0 = [] # list of vectors whose polar angles are 0
37 | angle_pi = [] # list of vectors whose polar angles are pi
38 | angle_0_pi = [] # list of vectors whose polar angles are larger than 0 and smaller than pi
39 | angle_pi_2pi = [] # list of vectors whose polar angles are larger than pi and smaller than 2pi
40 | for v in vector_list:
41 | if v == v0:
42 | if v.x > 0:
43 | angle_0.append(v)
44 | elif v.x < 0:
45 | angle_pi.append(v)
46 | elif v < v0:
47 | angle_pi_2pi.append(v)
48 | elif v > v0:
49 | angle_0_pi.append(v)
50 | heap_0_pi = MaxHeap(angle_0_pi)
51 | heap_pi_2pi = MaxHeap(angle_pi_2pi)
52 | heap_0_pi.heapsort()
53 | heap_pi_2pi.heapsort()
54 | return [(v.x, v.y) for v in (angle_0 + heap_0_pi + angle_pi + heap_pi_2pi)]
55 |
--------------------------------------------------------------------------------
/polygon_area.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | from typing import Sequence, Tuple, Union
3 |
4 | Number = Union[int, float]
5 |
6 |
7 | def polygon_area(polygon: Sequence[Tuple[Number, Number]]) -> float:
8 | n = len(polygon)
9 | area = sum((polygon[i][0] + polygon[i + 1][0]) * (polygon[i + 1][1] - polygon[i][1]) for i in range(n - 1))
10 | area += (polygon[0][0] + polygon[n - 1][0]) * (polygon[0][1] - polygon[n - 1][1])
11 | return 0.5 * abs(area)
12 |
--------------------------------------------------------------------------------
/polynomial_multiply.py:
--------------------------------------------------------------------------------
1 | import math
2 | import fft
3 |
4 |
5 | def polynominal_multiply(a, b, precision=0):
6 | a_len = len(a)
7 | b_len = len(b)
8 | length = int(2 ** (1 + math.ceil(math.log(max(a_len, b_len)))))
9 | print(length)
10 | extend_a = [0] * length
11 | extend_b = [0] * length
12 | for i in range(a_len):
13 | extend_a[i] = a[i]
14 | for i in range(a_len, length):
15 | extend_a[i] = 0
16 | for i in range(b_len):
17 | extend_b[i] = b[i]
18 | for i in range(b_len, length):
19 | extend_b[i] = 0
20 | a_fft = fft.recursive_fft(extend_a)
21 | b_fft = fft.recursive_fft(extend_b)
22 | m_fft = [a_fft[i] * b_fft[i] for i in range(len(a_fft))]
23 | ab = fft.recursive_inverse_fft(m_fft)
24 | return [round(ab[i].real, precision) for i in range(a_len + b_len - 1)]
25 |
--------------------------------------------------------------------------------
/pow.py:
--------------------------------------------------------------------------------
1 | def pow1(x, n: int):
2 | """
3 | compute x ^ n
4 | """
5 | if n == 0:
6 | return 1
7 | square = x * x
8 | if n % 2:
9 | return pow1(square, n // 2) * x
10 | return pow1(square, n // 2)
11 |
12 |
13 | def pow2(x, n: int):
14 | """
15 | compute x ^ n
16 | """
17 | if n == 0:
18 | return 1
19 | tmp = pow2(x, n // 2)
20 | if n % 2:
21 | return tmp * tmp * x
22 | return tmp * tmp
23 |
--------------------------------------------------------------------------------
/priority_queue.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from heap import MaxHeap, MinHeap
3 |
4 |
5 | class MaxPriorityQueue(MaxHeap):
6 | def heap_maximum(self):
7 | return self[0]
8 |
9 | def heap_extract_max(self):
10 | if self.heap_size < 1:
11 | sys.exit("heap underflow")
12 | maximum = self[0]
13 | self[0] = self[self.heap_size - 1]
14 | self.heap_size = self.heap_size - 1
15 | self.max_heapify(0)
16 | return maximum
17 |
18 | def heap_increase_key(self, i, key):
19 | if key < self[i]:
20 | sys.exit("new key is smaller than current key")
21 | self[i] = key
22 | while i > 0 and self[self.parent(i)] < self[i]:
23 | self[i], self[self.parent(i)] = self[self.parent(i)], self[i]
24 | i = self.parent(i)
25 |
26 | def max_heap_insert(self, key):
27 | if self.heap_size >= self.length:
28 | sys.exit("heap overflow")
29 | self.heap_size = self.heap_size + 1
30 | self[self.heap_size - 1] = float("-Inf")
31 | self.heap_increase_key(self.heap_size - 1, key)
32 |
33 | def heap_delete(self, i):
34 | self.heap_increase_key(i, float("Inf"))
35 | self[0], self[self.heap_size - 1] = self[self.heap_size - 1], self[0]
36 | self.heap_size = self.heap_size - 1
37 | self.max_heapify(0)
38 |
39 |
40 | class MinPriorityQueue(MinHeap):
41 | def heap_minimum(self):
42 | return self[0]
43 |
44 | def heap_extract_min(self):
45 | if self.heap_size < 1:
46 | sys.exit("heap underflow")
47 | minimum = self[0]
48 | self[0] = self[self.heap_size - 1]
49 | self.heap_size = self.heap_size - 1
50 | self.min_heapify(0)
51 | return minimum
52 |
53 | def heap_decrease_key(self, i, key):
54 | if key > self[i]:
55 | sys.exit("new key is larger than current key")
56 | self[i] = key
57 | while i > 0 and self[self.parent(i)] > self[i]:
58 | self[i], self[self.parent(i)] = self[self.parent(i)], self[i]
59 | i = self.parent(i)
60 |
61 | def min_heap_insert(self, key):
62 | if self.heap_size >= self.length:
63 | sys.exit("heap overflow")
64 | self.heap_size = self.heap_size + 1
65 | self[self.heap_size - 1] = float("Inf")
66 | self.heap_decrease_key(self.heap_size - 1, key)
67 |
--------------------------------------------------------------------------------
/quicksort.py:
--------------------------------------------------------------------------------
1 | from partition import partition, randomized_partition
2 |
3 |
4 | def quicksort(array, left, right, partition_method=partition):
5 | if left < right:
6 | index = partition_method(array, left, right)
7 | quicksort(array, left, index - 1)
8 | quicksort(array, index + 1, right)
9 |
10 |
11 | def randomized_quicksort(array, left, right):
12 | if left < right:
13 | index = randomized_partition(array, left, right)
14 | randomized_quicksort(array, left, index - 1)
15 | randomized_quicksort(array, index + 1, right)
16 |
--------------------------------------------------------------------------------
/random_array.py:
--------------------------------------------------------------------------------
1 | import random
2 |
3 |
4 | def random_arrays(array_num=100, array_size=100, array_lowerbound=0, array_upperbound=10000):
5 | for _ in range(array_num):
6 | yield [random.randint(array_lowerbound, array_upperbound) for _ in range(array_size)]
7 |
--------------------------------------------------------------------------------
/randomized_permute.py:
--------------------------------------------------------------------------------
1 | import random
2 |
3 |
4 | def randomize_in_place(A):
5 | """
6 | An algorithm to permute the given array in place.
7 | It computes a uniform random permutation.
8 | """
9 | n = len(A)
10 | for i in range(n):
11 | j = random.randint(i, n - 1)
12 | A[i], A[j] = A[j], A[i]
13 |
14 | # def permute_by_sorting(A):
15 | # n = len(A)
16 | # P = [0] * n
17 | # for i in
18 |
--------------------------------------------------------------------------------
/randomized_select.py:
--------------------------------------------------------------------------------
1 | from partition import randomized_partition
2 |
3 |
4 | def randomized_select(A, p, r, i):
5 | if p == r:
6 | return A[p]
7 | q = randomized_partition(A, p, r)
8 | k = q - p + 1
9 | if i == k:
10 | return A[q]
11 | elif i < k:
12 | return randomized_select(A, p, q - 1, i)
13 | else:
14 | return randomized_select(A, q + 1, r, i - k)
15 |
--------------------------------------------------------------------------------
/rank_tree.py:
--------------------------------------------------------------------------------
1 | # The variant of os_tree that use rank instead of size
2 | # !/usr/bin/env python
3 |
4 | from rb_tree import RbNode, RbTree
5 |
6 |
7 | class rank_node(RbNode):
8 | def __init__(self, key, p, left, right, color, rank):
9 | RbNode.__init__(self, key, p, left, right, color)
10 | self.rank = rank
11 |
12 | def update_rank_whole_tree(self, amount):
13 | if self.rank != 0:
14 | self.rank = self.rank + amount
15 | self.left.update_rank_whole_tree(amount)
16 | self.right.update_rank_whole_tree(amount)
17 |
18 | def decrease_all_successors(self, amount):
19 | self.rank = self.rank - amount
20 | self.right.update_rank_whole_tree(-1 * amount)
21 | y = self.p
22 | x = self
23 | while y.rank != 0 and y.right == x:
24 | x = y
25 | y = y.p
26 | if y.rank != 0:
27 | y.decrease_all_successors(amount)
28 |
29 |
30 | class rank_tree(RbTree):
31 | nil = rank_node(None, None, None, None, 1, 0)
32 | root = nil
33 |
34 | def __init__(self, values):
35 | if isinstance(values, list):
36 | for i in values:
37 | self.insert(rank_node(i, None, None, None, 0, 1))
38 | else:
39 | print("Not invalid argument")
40 |
41 | def insert(self, z):
42 | y = self.nil
43 | x = self.root
44 | while x != self.nil:
45 | y = x
46 | if z.key <= x.key:
47 | x.rank = x.rank + 1
48 | x.right.update_rank_whole_tree(1)
49 | x = x.left
50 | else:
51 | x = x.right
52 | if y == self.nil:
53 | self.root = z
54 | z.rank = 1
55 | elif z.key <= y.key:
56 | y.left = z
57 | z.rank = y.rank - 1
58 | else:
59 | y.right = z
60 | z.rank = y.rank + 1
61 | z.p = y
62 | z.left = self.nil
63 | z.right = self.nil
64 | z.color = 0 # red
65 | self.insert_fixed(z)
66 |
67 | def delete(self, z):
68 | z.decrease_all_successors(1) # z is counted as a successor
69 | y = z
70 | y_original_color = y.color
71 | if z.left == self.nil:
72 | x = z.right
73 | self.transplant(z, z.right)
74 | elif z.right == self.nil:
75 | x = z.left
76 | self.transplant(z, z.left)
77 | else:
78 | y = z.right.minimum()
79 | y_original_color = y.color
80 | x = y.right
81 | if y.p == z:
82 | x.p = y
83 | else:
84 | self.transplant(y, y.right)
85 | y.right = z.right
86 | y.right.p = y
87 | self.transplant(z, y)
88 | y.left = z.left
89 | y.left.p = y
90 | y.color = z.color
91 | if y_original_color == 1:
92 | self.delete_fixup(x)
93 |
--------------------------------------------------------------------------------
/right_horizontal_ray_intersect.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | from segment_intersect import segments_intersect
4 |
5 |
6 | def right_horizontal_ray_intersect(p0, p1, p2):
7 | """An algorithm to determine whether a given right horizontal ray from p0 intersects a line segment p1p2"""
8 | max_x = max(p1[0], p2[0])
9 | if max_x < p0[0]:
10 | return False
11 | # When max(x1, x2) = x0, if intersecting, the intersection point must be po, then po must be on the line segment p1p2
12 | elif max_x == p0[1]:
13 | if p1[0] == p2[0] and min(p1[1], p2[1]) <= p0[1] and max(p1[1], p2[1]) >= p0[1]:
14 | return True
15 | else:
16 | return equal(p0, p1) or equal(p0, p2)
17 | else:
18 | return segments_intersect(p1, p2, p0, (max_x, p0[1]))
19 |
20 |
21 | def equal(p1, p2):
22 | return p1[0] == p2[0] and p1[1] == p2[1]
23 |
--------------------------------------------------------------------------------
/segment_intersect.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 |
4 | def segments_intersect(p1, p2, p3, p4):
5 | d1 = direction(p3, p4, p1)
6 | d2 = direction(p3, p4, p2)
7 | d3 = direction(p1, p2, p3)
8 | d4 = direction(p1, p2, p4)
9 | if ((d1 > 0 > d2) or (d1 < 0 < d2)) and ((d3 > 0 > d4) or (d3 < 0 < d4)):
10 | return True
11 | elif d1 == 0 and on_segment(p3, p4, p1):
12 | return True
13 | elif d2 == 0 and on_segment(p3, p4, p2):
14 | return True
15 | elif d3 == 0 and on_segment(p1, p2, p3):
16 | return True
17 | elif d4 == 0 and on_segment(p1, p2, p4):
18 | return True
19 | else:
20 | return False
21 |
22 |
23 | def direction(pi, pj, pk):
24 | v1 = (pk[0] - pi[0], pk[1] - pi[1])
25 | v2 = (pj[0] - pi[0], pj[1] - pi[1])
26 | return v1[0] * v2[1] - v2[0] * v1[1]
27 |
28 |
29 | def on_segment(pi, pj, pk):
30 | return min(pi[0], pj[0]) <= pk[0] <= max(pi[0], pj[0]) and min(pi[1], pj[1]) <= pk[1] <= max(
31 | pi[1], pj[1])
32 |
--------------------------------------------------------------------------------
/selection_sort.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 |
5 | def selection_sort(array: list):
6 | """
7 | Inplace sort
8 | Consider sorting n numbers stored in array A by first finding the smallest element of A
9 | and exchanging it with the element in A[0] . Then find the second smallest element of A, and exchange it with A[1].
10 | Continue in this manner for the first n - 1 elements of A.
11 | :param array:
12 | :return:
13 | """
14 | n = len(array)
15 | for i in range(n - 1):
16 | minimum = array[i]
17 | index = i
18 | for j in range(i + 1, n):
19 | if minimum > array[j]:
20 | minimum = array[j]
21 | index = j
22 | array[i], array[index] = array[index], array[i]
23 |
--------------------------------------------------------------------------------
/square-matrix-multiply-brute-force.c:
--------------------------------------------------------------------------------
1 | // AUTHOR: WangQiang
2 | // DATE: 20140524
3 | // LAST UPDATE DATE: 20140524
4 | // EMAIL: cntqrxj@gmail.com
5 |
6 | #include
7 |
8 | //void square_matrix_multiply(int a[][2], int b[][2], int c[][2]) {
9 | //int i, j, k;
10 | //
11 | //for (i = 0; i < 2; i++)
12 | //for (j = 0; j < 2; j++) {
13 | //c[i][j] = 0;
14 | //for (k = 0; k < 2; k++)
15 | //c[i][j] = c[i][j] + a[i][k] * b[k][j];
16 | //}
17 | //}
18 |
19 | void square_matrix_multiply(int *a, int *b, int *c, int n) {
20 | int i, j, k;
21 |
22 | for (i = 0; i < n; i++)
23 | for (j = 0; j < n; j++) {
24 | *(c + i * n + j) = 0;
25 | for (k = 0; k < n; k++)
26 | *(c + i * n + j) = *(c + i * n + j) + *(a + i * n + k) * *(b + k * n + j);
27 | }
28 | }
29 |
30 | int main() {
31 | //int d[4] = {1, 3, 7, 5};
32 | //int e[4] = {6, 8, 4, 2};
33 | //int f[4];
34 | //int A[16] = {-1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1};
35 | int A[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
36 | int B[16], C[16];
37 | int i, j;
38 | //
39 | //square_matrix_multiply(d, e, f, 2);
40 | //printf("Matrix d:\n");
41 | //for (i = 0; i < 2; i++) {
42 | //for (j = 0; j < 2; j++)
43 | //printf("%d\t", *(d + 2 * i + j));
44 | //printf("\n");
45 | //}
46 | //printf("\n");
47 | //printf("Matrix e:\n");
48 | //for (i = 0; i < 2; i++) {
49 | //for (j = 0; j < 2; j++)
50 | //printf("%d\t", *(e + 2 * i + j));
51 | //printf("\n");
52 | //}
53 | //printf("\n");
54 | //printf("The result of matrix multiply d * e:\n");
55 | //for (i = 0; i < 2; i++) {
56 | //for (j = 0; j < 2; j++)
57 | //printf("%d\t", *(f + 2 * i + j));
58 | //printf("\n");
59 | //}
60 | square_matrix_multiply(A, A, B, 4);
61 | //square_matrix_multiply(A, B, C, 4);
62 | //square_matrix_multiply(C, C, B, 4);
63 | //printf("Matrix A:\n");
64 | //for (i = 0; i < 4; i++) {
65 | //for (j = 0; j < 4; j++)
66 | //printf("%d\t", *(A + 4 * i + j));
67 | //printf("\n");
68 | //}
69 | //printf("\n");
70 | //printf("The result is:\n");
71 | for (i = 0; i < 4; i++) {
72 | for (j = 0; j < 4; j++)
73 | printf("%d\t", *(B + 4 * i + j));
74 | printf("\n");
75 | }
76 | return 0;
77 | }
78 |
--------------------------------------------------------------------------------
/square-matrix-multiply-brute-force2.c:
--------------------------------------------------------------------------------
1 | // AUTHOR: WangQiang
2 | // DATE: 20140527
3 | // LAST UPDATE DATE: 20140527
4 | // EMAIL: cntqrxj@gmail.com
5 |
6 | #include
7 |
8 | #define RANK 50
9 |
10 | void square_matrix_multiply(int a[][RANK], int b[][RANK], int c[][RANK]) {
11 | int i, j, k;
12 |
13 | for (i = 0; i < RANK; i++)
14 | for (j = 0; j < RANK; j++) {
15 | c[i][j] = 0;
16 | for (k = 0; k < RANK; k++)
17 | c[i][j] = c[i][j] + a[i][k] * b[k][j];
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/square-matrix-multiply-recursive.c:
--------------------------------------------------------------------------------
1 | // AUTHOR: WangQiang
2 | // CREATE DATE: 20140526
3 | // LAST UPDATE DATE: 20140528
4 | // EMAIL: cntqrxj@gmail.com
5 |
6 | #include
7 | #include
8 |
9 | static void submatrix_init(int *S, int S_row, int S_col, int *T, int T_row, int T_col, int row_start, int col_start) {
10 | int i, j;
11 | for (i = 0; i < T_row; i++)
12 | for (j = 0; j < T_col; j++)
13 | *(T + (i * T_row + j)) = *(S + (S_row * (row_start - 1) + col_start - 1) + i * S_row + j);
14 | }
15 |
16 | static void to_matrix(int *S, int S_row, int S_col, int *M, int M_row, int M_col, int row_start, int col_start) {
17 | int i, j;
18 | for (i = 0; i < S_row; i++)
19 | for (j = 0; j < S_col; j++)
20 | *(M + (M_row * (row_start - 1) + col_start - 1) + i * M_row + j) = *(S + (i * S_row + j));
21 | }
22 |
23 | static void matrix_add(int *A, int *B, int *C, int row, int col) {
24 | int i, j;
25 |
26 | for (i = 0; i < row; i++)
27 | for (j = 0; j < col; j++)
28 | *(C + (i * row) + j) = *(A + (i * row) + j) + *(B + (i * row) + j);
29 | }
30 |
31 | void square_matrix_multiply(int *A, int *B, int *C, int n) {
32 | int half = n / 2;
33 | int num = half * half;
34 |
35 | if (n == 1)
36 | *C = *A * *B;
37 | else {
38 | int *A11 = (int *) calloc(num, sizeof(int));
39 | int *A12 = (int *) calloc(num, sizeof(int));
40 | int *A21 = (int *) calloc(num, sizeof(int));
41 | int *A22 = (int *) calloc(num, sizeof(int));
42 | int *B11 = (int *) calloc(num, sizeof(int));
43 | int *B12 = (int *) calloc(num, sizeof(int));
44 | int *B21 = (int *) calloc(num, sizeof(int));
45 | int *B22 = (int *) calloc(num, sizeof(int));
46 | int *C11 = (int *) calloc(num, sizeof(int));
47 | int *C12 = (int *) calloc(num, sizeof(int));
48 | int *C21 = (int *) calloc(num, sizeof(int));
49 | int *C22 = (int *) calloc(num, sizeof(int));
50 | int *D11 = (int *) calloc(num, sizeof(int));
51 | int *D12 = (int *) calloc(num, sizeof(int));
52 | int *D21 = (int *) calloc(num, sizeof(int));
53 | int *D22 = (int *) calloc(num, sizeof(int));
54 |
55 | submatrix_init(A, n, n, A11, half, half, 1, 1);
56 | submatrix_init(A, n, n, A12, half, half, 1, half + 1);
57 | submatrix_init(A, n, n, A21, half, half, half + 1, 1);
58 | submatrix_init(A, n, n, A22, half, half, half + 1, half + 1);
59 | submatrix_init(B, n, n, B11, half, half, 1, 1);
60 | submatrix_init(B, n, n, B12, half, half, 1, half + 1);
61 | submatrix_init(B, n, n, B21, half, half, half + 1, 1);
62 | submatrix_init(B, n, n, B22, half, half, half + 1, half + 1);
63 | square_matrix_multiply(A11, B11, C11, half);
64 | square_matrix_multiply(A12, B21, D11, half);
65 | square_matrix_multiply(A11, B12, C12, half);
66 | square_matrix_multiply(A12, B22, D12, half);
67 | square_matrix_multiply(A21, B11, C21, half);
68 | square_matrix_multiply(A22, B21, D21, half);
69 | square_matrix_multiply(A21, B12, C22, half);
70 | square_matrix_multiply(A22, B22, D22, half);
71 | matrix_add(C11, D11, C11, half, half);
72 | matrix_add(C12, D12, C12, half, half);
73 | matrix_add(C21, D21, C21, half, half);
74 | matrix_add(C22, D22, C22, half, half);
75 | to_matrix(C11, half, half, C, n, n, 1, 1);
76 | to_matrix(C12, half, half, C, n, n, 1, half + 1);
77 | to_matrix(C21, half, half, C, n, n, half + 1, 1);
78 | to_matrix(C22, half, half, C, n, n, half + 1, half + 1);
79 | free(A11);
80 | free(A12);
81 | free(A21);
82 | free(A22);
83 | free(B11);
84 | free(B12);
85 | free(B21);
86 | free(B22);
87 | free(C11);
88 | free(C12);
89 | free(C21);
90 | free(C22);
91 | free(D11);
92 | free(D12);
93 | free(D21);
94 | free(D22);
95 | }
96 | return;
97 | }
98 |
--------------------------------------------------------------------------------
/square_matrix_multiply_Strassen.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/python2.7
2 |
3 | from numpy import *
4 |
5 |
6 | def square_matrix_multiply(A, B):
7 | shape = A.shape
8 | length = shape[0]
9 | half = length / 2
10 |
11 | C = zeros(shape, dtype=int64)
12 | if length == 1:
13 | C[0, 0] = A[0, 0] * B[0, 0]
14 | return C
15 |
16 | S1 = zeros((half, half), dtype=int64)
17 | S2 = zeros((half, half), dtype=int64)
18 | S3 = zeros((half, half), dtype=int64)
19 | S4 = zeros((half, half), dtype=int64)
20 | S5 = zeros((half, half), dtype=int64)
21 | S6 = zeros((half, half), dtype=int64)
22 | S7 = zeros((half, half), dtype=int64)
23 | S8 = zeros((half, half), dtype=int64)
24 | S9 = zeros((half, half), dtype=int64)
25 | S10 = zeros((half, half), dtype=int64)
26 |
27 | P1 = zeros((half, half), dtype=int64)
28 | P2 = zeros((half, half), dtype=int64)
29 | P3 = zeros((half, half), dtype=int64)
30 | P4 = zeros((half, half), dtype=int64)
31 | P5 = zeros((half, half), dtype=int64)
32 | P6 = zeros((half, half), dtype=int64)
33 | P7 = zeros((half, half), dtype=int64)
34 |
35 | S1 = B[0:half, half:length] - B[half:length, half:length]
36 | S2 = A[0:half, 0:half] + A[0:half, half:length]
37 | S3 = A[half:length, 0:half] + A[half:length, half:length]
38 | S4 = B[half:length, 0:half] - B[0:half, 0:half]
39 | S5 = A[0:half, 0:half] + A[half:length, half:length]
40 | S6 = B[0:half, 0:half] + B[half:length, half:length]
41 | S7 = A[0:half, half:length] - A[half:length, half:length]
42 | S8 = B[half:length, 0:half] + B[half:length, half:length]
43 | S9 = A[0:half, 0:half] - A[half:length, 0:half]
44 | S10 = B[0:half, 0:half] + B[0:half, half:length]
45 |
46 | P1 = square_matrix_multiply(A[0:half, 0:half], S1)
47 | P2 = square_matrix_multiply(S2, B[half:length, half:length])
48 | P3 = square_matrix_multiply(S3, B[0:half, 0:half])
49 | P4 = square_matrix_multiply(A[half:length, half:length], S4)
50 | P5 = square_matrix_multiply(S5, S6)
51 | P6 = square_matrix_multiply(S7, S8)
52 | P7 = square_matrix_multiply(S9, S10)
53 |
54 | C[0:half, 0:half] = P5 + P4 - P2 + P6
55 | C[0:half, half:length] = P1 + P2
56 | C[half:length, 0:half] = P3 + P4
57 | C[half:length, half:length] = P5 + P1 - P3 - P7
58 |
59 | return C
60 |
61 |
62 | # # A = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
63 | # # B = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
64 | # # A = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
65 | # # B = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
66 | # A = array([[1, 3], [7, 5]])
67 | # B = array([[6, 8], [4, 2]])
68 | # # A = array([[1, 2, 3], [4, 5, 6]])
69 | # # B = array([[1, 2], [4, 5]])
70 | # print(square_matrix_multiply(A, B))
71 | # # print( dot(A, B))
72 |
--------------------------------------------------------------------------------
/stack.py:
--------------------------------------------------------------------------------
1 | class FullException(Exception):
2 | pass
3 |
4 |
5 | class EmptyException(Exception):
6 | pass
7 |
8 |
9 | class Stack(list):
10 | def __init__(self, size):
11 | super(Stack, self).__init__([None] * size)
12 | self.top = -1
13 | self.size = len(size)
14 |
15 | def push(self, x):
16 | if self.full():
17 | raise FullException("This stack is full")
18 | else:
19 | self.top = self.top + 1
20 | self[self.top] = x
21 |
22 | def pop(self, *args, **kwargs):
23 | if self.empty():
24 | raise EmptyException('This stack is empty')
25 | else:
26 | self.top = self.top - 1
27 | return self[self.top + 1]
28 |
29 | def empty(self):
30 | return self.top == -1
31 |
32 | def full(self):
33 | return self.top == self.size - 1
34 |
35 | # def multipop(self, k):
36 | # l = []
37 | # while not self.empty() and k > 0:
38 | #
39 | # l.append(self.pop())
40 | # return l
41 |
--------------------------------------------------------------------------------
/synthetic_division.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 |
4 | def synthetic_division(A, n, x):
5 | q = [0] * (n - 1)
6 | q[n - 2] = A[n - 1]
7 | for i in range(n - 3, -1, -1):
8 | q[i] = x * q[i + 1] + A[i + 1]
9 | r = x * q[0] + A[0]
10 | return q, r
11 |
--------------------------------------------------------------------------------
/tests/Bellman_Ford_matrix_test.py:
--------------------------------------------------------------------------------
1 | from Bellman_Ford_matrix import Bellman_Ford_matrix, slow_all_pairs_shortest_paths
2 | import unittest
3 | import numpy
4 |
5 |
6 | class TestBellmanFordMatrix(unittest.TestCase):
7 | def test_Bellman_Ford_matrix(self):
8 | W = numpy.array([[float("Inf"), 6., 7., float("Inf"), float("Inf")], [float("Inf"), float("Inf"), 8., 5., -4.],
9 | [float("Inf"), float("Inf"), float("Inf"), -3., 9.],
10 | [float("Inf"), -2., float("Inf"), float("Inf"), float("Inf")],
11 | [2., float("Inf"), float("Inf"), 7., float("Inf")]])
12 | d, p = Bellman_Ford_matrix(W, 1)
13 | self.assertEqual(d, [0, 2.0, 7.0, 4.0, -2.0])
14 | self.assertEqual(p, [None, 4, 1, 3, 2])
15 |
16 | def test_slow_all_pairs_shortest_paths(self):
17 | W = numpy.array([[0, 6., 7., float("Inf"), float("Inf")], [float("Inf"), 0, 8., 5., -4.],
18 | [float("Inf"), float("Inf"), 0, -3., 9.], [float("Inf"), -2., float("Inf"), 0, float("Inf")],
19 | [2., float("Inf"), float("Inf"), 7., 0]])
20 | L = slow_all_pairs_shortest_paths(W, 1)
21 | # print(L)
22 | self.assertEqual(L, [0, 2.0, 7.0, 4.0, -2.0])
23 |
--------------------------------------------------------------------------------
/tests/Horner_rule_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 | import unittest
5 | import random
6 | from Horner_rule import Horner_rule
7 |
8 |
9 | class TestHornerRule(unittest.TestCase):
10 | def test_horner_rule(self):
11 | for _ in range(100):
12 | x = random.randint(1, 5)
13 | coefficients = [random.randint(0, 100) for _ in range(11)]
14 | expected_result = 0
15 | for index, coefficient in enumerate(coefficients):
16 | expected_result += coefficient * x ** index
17 | self.assertEqual(Horner_rule(x, coefficients), expected_result)
18 |
--------------------------------------------------------------------------------
/tests/Johnson_test.py:
--------------------------------------------------------------------------------
1 | from Johnson import Johnson
2 | from graph import Vertex, Graph
3 | import unittest
4 |
5 |
6 | class TestJohnson(unittest.TestCase):
7 | def testJohnson(self):
8 | a1 = Vertex(1)
9 | a2 = Vertex(2)
10 | a3 = Vertex(3)
11 | a4 = Vertex(4)
12 | a5 = Vertex(5)
13 | vertices = [a1, a2, a3, a4, a5]
14 | edges = [(a1, a2), (a1, a3), (a1, a5), (a2, a4), (a2, a5), (a3, a2), (a4, a1), (a4, a3), (a5, a4)]
15 | g = Graph(vertices, edges)
16 | weight = [3, 8, -4, 1, 7, 4, 2, -5, 6]
17 | w = dict()
18 | for i, j in zip(edges, weight):
19 | w[i] = j
20 | D = Johnson(g, w)
21 | # print(D)
22 | a1 = Vertex(1)
23 | a2 = Vertex(2)
24 | a3 = Vertex(3)
25 | a4 = Vertex(4)
26 | a5 = Vertex(5)
27 | a6 = Vertex(6)
28 | vertices = [a1, a2, a3, a4, a5, a6]
29 | edges = [(a1, a5), (a2, a1), (a2, a4), (a3, a2), (a3, a6), (a4, a1), (a4, a5), (a5, a2), (a6, a2), (a6, a3)]
30 | g = Graph(vertices, edges)
31 | weight = [-1, 1, 2, 2, -8, -4, 3, 7, 5, 10]
32 | w = dict()
33 | for i, j in zip(edges, weight):
34 | w[i] = j
35 | D = Johnson(g, w)
36 | # print(D)
37 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Firkraag/algorithm/253f63e8c1e9cea2b90980d76973b37b347d70bb/tests/__init__.py
--------------------------------------------------------------------------------
/tests/all_pairs_shortest_paths_test.py:
--------------------------------------------------------------------------------
1 | from all_pairs_shortest_paths import slow_all_pairs_shortest_paths, faster_all_pairs_shortest_paths
2 | import unittest
3 | import numpy as np
4 |
5 |
6 | class TestAllPairsShortestPaths(unittest.TestCase):
7 | def test_slow_all_pairs_shortest_paths(self):
8 | W = np.array([[0, 3, 8, float("Inf"), -4], [float("Inf"), 0, float("Inf"), 1, 7],
9 | [float("Inf"), 4, 0, float("Inf"), float("Inf")], [2, float("Inf"), -5, 0, float("Inf")],
10 | [float("Inf"), float("Inf"), float("Inf"), 6, 0]])
11 | R = slow_all_pairs_shortest_paths(W)
12 | L = np.array([[0, 1, -3, 2, -4], [3, 0, -4, 1, -1], [7, 4, 0, 5, 3], [2, -1, -5, 0, -2], [8, 5, 1, 6, 0]])
13 | self.assertEqual((R == L).all(), True)
14 | W = np.array([[0, float("Inf"), float("Inf"), float("Inf"), -1, float("Inf")],
15 | [1, 0, float("Inf"), 2, float("Inf"), float("Inf")],
16 | [float("Inf"), 2, 0, float("Inf"), float("Inf"), -8],
17 | [-4, float("Inf"), float("Inf"), 0, 3, float("Inf")],
18 | [float("Inf"), 7, float("Inf"), float("Inf"), 0, float("Inf")],
19 | [float("Inf"), 5, 10, float("Inf"), float("Inf"), 0]])
20 | R = slow_all_pairs_shortest_paths(W)
21 | L = np.array([[0, 6, float("Inf"), 8, -1, float("Inf")], [-2, 0, float("Inf"), 2, -3, float("Inf")],
22 | [-5, -3, 0, -1, -6, -8], [-4, 2, float("Inf"), 0, -5, float("Inf")],
23 | [5, 7, float("Inf"), 9, 0, float("Inf")], [3, 5, 10, 7, 2, 0]])
24 | self.assertEqual((R == L).all(), True)
25 |
26 | def test_faster_all_pairs_shortest_paths(self):
27 | W = np.array([[0, 3, 8, float("Inf"), -4], [float("Inf"), 0, float("Inf"), 1, 7],
28 | [float("Inf"), 4, 0, float("Inf"), float("Inf")], [2, float("Inf"), -5, 0, float("Inf")],
29 | [float("Inf"), float("Inf"), float("Inf"), 6, 0]])
30 | R = faster_all_pairs_shortest_paths(W)
31 | L = np.array([[0, 1, -3, 2, -4], [3, 0, -4, 1, -1], [7, 4, 0, 5, 3], [2, -1, -5, 0, -2], [8, 5, 1, 6, 0]])
32 | self.assertEqual((R == L).all(), True)
33 | W = np.array([[0, float("Inf"), float("Inf"), float("Inf"), -1, float("Inf")],
34 | [1, 0, float("Inf"), 2, float("Inf"), float("Inf")],
35 | [float("Inf"), 2, 0, float("Inf"), float("Inf"), -8],
36 | [-4, float("Inf"), float("Inf"), 0, 3, float("Inf")],
37 | [float("Inf"), 7, float("Inf"), float("Inf"), 0, float("Inf")],
38 | [float("Inf"), 5, 10, float("Inf"), float("Inf"), 0]])
39 | R = faster_all_pairs_shortest_paths(W)
40 | L = np.array([[0, 6, float("Inf"), 8, -1, float("Inf")], [-2, 0, float("Inf"), 2, -3, float("Inf")],
41 | [-5, -3, 0, -1, -6, -8], [-4, 2, float("Inf"), 0, -5, float("Inf")],
42 | [5, 7, float("Inf"), 9, 0, float("Inf")], [3, 5, 10, 7, 2, 0]])
43 | self.assertEqual((R == L).all(), True)
44 |
--------------------------------------------------------------------------------
/tests/bh_tree_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import unittest
3 | from bh_tree import bh_tree, bh_node
4 |
5 |
6 | class TestRbTree(unittest.TestCase):
7 | def test_insert_one(self):
8 | T = bh_tree([41])
9 | self.wrap(T, 41, 1)
10 |
11 | def test_insert_two(self):
12 | T = bh_tree([41, 38])
13 | self.wrap(T, 41, 1)
14 | self.wrap(T, 38, 1)
15 |
16 | def test_insert_three(self):
17 | T = bh_tree([41, 38, 31])
18 | self.wrap(T, 38, 1)
19 | self.wrap(T, 31, 1)
20 | self.wrap(T, 41, 1)
21 |
22 | def test_insert_four(self):
23 | T = bh_tree([41, 38, 31, 12])
24 | self.wrap(T, 38, 2)
25 | self.wrap(T, 31, 1)
26 | self.wrap(T, 41, 1)
27 | self.wrap(T, 12, 1)
28 |
29 | def test_insert_five(self):
30 | T = bh_tree([41, 38, 31, 12, 19])
31 | self.wrap(T, 38, 2)
32 | self.wrap(T, 19, 1)
33 | self.wrap(T, 41, 1)
34 | self.wrap(T, 12, 1)
35 | self.wrap(T, 31, 1)
36 |
37 | def test_insert_six(self):
38 | T = bh_tree([41, 38, 31, 12, 19, 9])
39 | self.wrap(T, 38, 2)
40 | self.wrap(T, 19, 2)
41 | self.wrap(T, 41, 1)
42 | self.wrap(T, 12, 1)
43 | self.wrap(T, 31, 1)
44 | self.wrap(T, 9, 1)
45 |
46 | def test_delete_one(self):
47 | T = bh_tree([41, 38, 31, 12, 19, 9])
48 | T.delete(T.iterative_tree_search(9))
49 | self.wrap(T, 38, 2)
50 | self.wrap(T, 19, 2)
51 | self.wrap(T, 41, 1)
52 | self.wrap(T, 12, 1)
53 | self.wrap(T, 31, 1)
54 |
55 | def test_delete_two(self):
56 | T = bh_tree([41, 38, 31, 12, 19, 9])
57 | T.delete(T.iterative_tree_search(9))
58 | T.delete(T.iterative_tree_search(12))
59 | self.wrap(T, 38, 2)
60 | self.wrap(T, 19, 1)
61 | self.wrap(T, 41, 1)
62 | self.wrap(T, 31, 1)
63 |
64 | def test_delete_three(self):
65 | T = bh_tree([41, 38, 31, 12, 19, 9])
66 | T.delete(T.iterative_tree_search(9))
67 | T.delete(T.iterative_tree_search(12))
68 | T.delete(T.iterative_tree_search(19))
69 | self.wrap(T, 38, 2)
70 | self.wrap(T, 31, 1)
71 | self.wrap(T, 41, 1)
72 |
73 | def test_delete_four(self):
74 | T = bh_tree([41, 38, 31, 12, 19, 9])
75 | T.delete(T.iterative_tree_search(9))
76 | T.delete(T.iterative_tree_search(12))
77 | T.delete(T.iterative_tree_search(19))
78 | T.delete(T.iterative_tree_search(31))
79 | self.wrap(T, 38, 1)
80 | self.wrap(T, 41, 1)
81 |
82 | def test_delete_five(self):
83 | T = bh_tree([41, 38, 31, 12, 19, 9])
84 | T.delete(T.iterative_tree_search(9))
85 | T.delete(T.iterative_tree_search(12))
86 | T.delete(T.iterative_tree_search(19))
87 | T.delete(T.iterative_tree_search(31))
88 | T.delete(T.iterative_tree_search(38))
89 | self.wrap(T, 41, 1)
90 |
91 | def test_delete_six(self):
92 | T = bh_tree([41, 38, 31, 12, 19, 9])
93 | T.delete(T.iterative_tree_search(9))
94 | T.delete(T.iterative_tree_search(12))
95 | T.delete(T.iterative_tree_search(19))
96 | T.delete(T.iterative_tree_search(31))
97 | T.delete(T.iterative_tree_search(38))
98 | T.delete(T.iterative_tree_search(41))
99 | self.assertEqual(T.root, T.nil)
100 |
101 | def wrap(self, tree, node, bh):
102 | self.assertEqual(tree.iterative_tree_search(node).bh, bh)
103 |
104 |
105 | if __name__ == '__main__':
106 | unittest.main()
107 |
--------------------------------------------------------------------------------
/tests/binary_search_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import unittest
3 | import random
4 | from binary_search import binary_search, bisect_left, bisect_right
5 |
6 |
7 | class TestBinarySearch(unittest.TestCase):
8 | def test_binary_search(self):
9 | for _ in range(100):
10 | array = sorted([random.randint(1, 10000) for _ in range(100)])
11 | target = random.randint(1, 10000)
12 | index = binary_search(target, array)
13 | if index == -1:
14 | self.assertNotIn(target, array)
15 | else:
16 | self.assertEqual(target, array[index])
17 |
18 | def test_bisect_left(self):
19 | for length in range(10):
20 | array = sorted([random.randint(1, 10) for _ in range(length)])
21 | target = random.randint(0, 15)
22 | index = bisect_left(array, target)
23 | self.assertTrue(all(val < target for val in array[:index]))
24 | self.assertTrue(all(val >= target for val in array[index:]))
25 |
26 | def test_bisect_right(self):
27 | for length in range(10):
28 | array = sorted([random.randint(1, 10) for _ in range(length)])
29 | target = random.randint(0, 15)
30 | index = bisect_right(array, target)
31 | self.assertTrue(all(val <= target for val in array[:index]))
32 | self.assertTrue(all(val > target for val in array[index:]))
33 |
--------------------------------------------------------------------------------
/tests/bubble_sort_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import unittest
3 | import random
4 | from bubble_sort import bubble_sort
5 |
6 |
7 | class TestBubbleSort(unittest.TestCase):
8 | def test_bubble_sort(self):
9 | for _ in range(100):
10 | array = [random.randint(1, 10000) for _ in range(100)]
11 | array_copy = array[:]
12 | bubble_sort(array)
13 | self.assertEqual(array, sorted(array_copy))
14 |
--------------------------------------------------------------------------------
/tests/contains_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import unittest
4 | from contains import contains
5 |
6 |
7 | class TestContains(unittest.TestCase):
8 | def test_contains(self):
9 | x = [1, 1.5, 3.5, 2.3, 10.01]
10 | self.assertEqual(contains(x, 5), {
11 | (1, 2), (2.3, 3.3), (3.5, 4.5), (10.01, 11.01)})
12 | x = [3.5, 5.2, -1.1, -4, -12, -11.33]
13 | self.assertEqual(contains(x, 6), {
14 | (-12, -11), (-4, -3), (-1.1, -0.10000000000000009), (3.5, 4.5), (5.2, 6.2)})
15 |
--------------------------------------------------------------------------------
/tests/counting_sort_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from counting_sort import counting_sort
3 |
4 |
5 | class TestHeap(unittest.TestCase):
6 | def test_counting_sort(self):
7 | A = [2, 5, 3, 0, 2, 3, 0, 3]
8 | B = []
9 | for i in range(len(A)):
10 | B.append(0)
11 | counting_sort(A, B, 5)
12 | self.assertEqual(B, [0, 0, 2, 2, 3, 3, 3, 5])
13 | self.assertEqual(A, [2, 5, 3, 0, 2, 3, 0, 3])
14 |
--------------------------------------------------------------------------------
/tests/cut_rod_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import unittest
3 |
4 | from cut_rod import bottom_up_cut_rod, bottom_up_cut_rod_two_subproblem, memoized_cut_rod, print_cut_rod_solution, \
5 | bottom_up_cut_rod_with_fixed_cut_cost, extended_memoized_cut_rod
6 |
7 |
8 | class TestCutRod(unittest.TestCase):
9 | def test_bottom_up_cut_rod(self):
10 | p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30]
11 | values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13,
12 | 6, 17, 7, 18, 8, 22, 9, 25, 10, 30]
13 | for i in range(len(values), 2):
14 | self.assertEqual(bottom_up_cut_rod(p, values[i]), values[i + 1])
15 |
16 | def test_bottom_up_cut_rod_two_subproblem(self):
17 | p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30]
18 | values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13,
19 | 6, 17, 7, 18, 8, 22, 9, 25, 10, 30]
20 | for i in range(len(values), 2):
21 | self.assertEqual(bottom_up_cut_rod_two_subproblem(
22 | p, values[i]), values[i + 1])
23 |
24 | def test_memoized_cut_rod(self):
25 | p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30]
26 | values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13,
27 | 6, 17, 7, 18, 8, 22, 9, 25, 10, 30]
28 | for i in range(len(values), 2):
29 | self.assertEqual(memoized_cut_rod(p, values[i]), values[i + 1])
30 |
31 | def test_bottom_up_cut_rod_with_fixed_cut_cost(self):
32 | p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30]
33 | values = [1, 1, 2, 5, 3, 8, 4, 9, 5, 11,
34 | 6, 17, 7, 17, 8, 20, 9, 24, 10, 30]
35 | for i in range(len(values), 2):
36 | self.assertEqual(bottom_up_cut_rod_with_fixed_cut_cost(
37 | p, values[i], 2), values[i + 1])
38 | values = [1, 1, 2, 5, 3, 8, 4, 9, 5, 11.5,
39 | 6, 17, 7, 17, 8, 20.5, 9, 24, 10, 30]
40 | for i in range(len(values), 2):
41 | self.assertEqual(bottom_up_cut_rod_with_fixed_cut_cost(
42 | p, values[i], 1.5), values[i + 1])
43 |
44 | def test_print_rod_solution(self):
45 | p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30]
46 | values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13,
47 | 6, 17, 7, 18, 8, 22, 9, 25, 10, 30]
48 | print_cut_rod_solution(p, 9, extended_memoized_cut_rod)
49 |
--------------------------------------------------------------------------------
/tests/depth_tree_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import unittest
3 | from depth_tree import depth_tree, depth_node
4 |
5 |
6 | class TestRbtree(unittest.TestCase):
7 | def test_insert_one(self):
8 | T = depth_tree([41])
9 | self.wrap(T, 41, 0)
10 |
11 | def test_insert_two(self):
12 | T = depth_tree([41, 38])
13 | self.wrap(T, 41, 0)
14 | self.wrap(T, 38, 1)
15 |
16 | def test_insert_three(self):
17 | T = depth_tree([41, 38, 31])
18 | self.wrap(T, 38, 0)
19 | self.wrap(T, 31, 1)
20 | self.wrap(T, 41, 1)
21 |
22 | def test_insert_four(self):
23 | T = depth_tree([41, 38, 31, 12])
24 | self.wrap(T, 38, 0)
25 | self.wrap(T, 31, 1)
26 | self.wrap(T, 41, 1)
27 | self.wrap(T, 12, 2)
28 |
29 | def test_insert_five(self):
30 | T = depth_tree([41, 38, 31, 12, 19])
31 | self.wrap(T, 38, 0)
32 | self.wrap(T, 19, 1)
33 | self.wrap(T, 41, 1)
34 | self.wrap(T, 12, 2)
35 | self.wrap(T, 31, 2)
36 |
37 | def test_insert_six(self):
38 | T = depth_tree([41, 38, 31, 12, 19, 9])
39 | self.wrap(T, 38, 0)
40 | self.wrap(T, 19, 1)
41 | self.wrap(T, 41, 1)
42 | self.wrap(T, 12, 2)
43 | self.wrap(T, 31, 2)
44 | self.wrap(T, 9, 3)
45 |
46 | def test_delete_one(self):
47 | T = depth_tree([41, 38, 31, 12, 19, 9])
48 | T.delete(T.iterative_tree_search(9))
49 | self.wrap(T, 38, 0)
50 | self.wrap(T, 19, 1)
51 | self.wrap(T, 41, 1)
52 | self.wrap(T, 12, 2)
53 | self.wrap(T, 31, 2)
54 |
55 | def test_delete_two(self):
56 | T = depth_tree([41, 38, 31, 12, 19, 9])
57 | T.delete(T.iterative_tree_search(9))
58 | T.delete(T.iterative_tree_search(12))
59 | self.wrap(T, 38, 0)
60 | self.wrap(T, 19, 1)
61 | self.wrap(T, 41, 1)
62 | self.wrap(T, 31, 2)
63 |
64 | def test_delete_three(self):
65 | T = depth_tree([41, 38, 31, 12, 19, 9])
66 | T.delete(T.iterative_tree_search(9))
67 | T.delete(T.iterative_tree_search(12))
68 | T.delete(T.iterative_tree_search(19))
69 | self.wrap(T, 38, 0)
70 | self.wrap(T, 31, 1)
71 | self.wrap(T, 41, 1)
72 |
73 | def test_delete_four(self):
74 | T = depth_tree([41, 38, 31, 12, 19, 9])
75 | T.delete(T.iterative_tree_search(9))
76 | T.delete(T.iterative_tree_search(12))
77 | T.delete(T.iterative_tree_search(19))
78 | T.delete(T.iterative_tree_search(31))
79 | self.wrap(T, 38, 0)
80 | self.wrap(T, 41, 1)
81 |
82 | def test_delete_five(self):
83 | T = depth_tree([41, 38, 31, 12, 19, 9])
84 | T.delete(T.iterative_tree_search(9))
85 | T.delete(T.iterative_tree_search(12))
86 | T.delete(T.iterative_tree_search(19))
87 | T.delete(T.iterative_tree_search(31))
88 | T.delete(T.iterative_tree_search(38))
89 | self.wrap(T, 41, 0)
90 |
91 | def test_delete_six(self):
92 | T = depth_tree([41, 38, 31, 12, 19, 9])
93 | T.delete(T.iterative_tree_search(9))
94 | T.delete(T.iterative_tree_search(12))
95 | T.delete(T.iterative_tree_search(19))
96 | T.delete(T.iterative_tree_search(31))
97 | T.delete(T.iterative_tree_search(38))
98 | T.delete(T.iterative_tree_search(41))
99 | self.assertEqual(T.nil.depth, -1)
100 |
101 | def wrap(self, tree, node, depth):
102 | self.assertEqual(tree.iterative_tree_search(node).depth, depth)
103 |
104 |
105 | if __name__ == '__main__':
106 | unittest.main()
107 |
--------------------------------------------------------------------------------
/tests/disjoint_sets_forest_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import unittest
4 | import disjoint_sets_forest as ds
5 |
6 |
7 | class TestDisjointSets(unittest.TestCase):
8 | def test_forest(self):
9 | pool = [0] * 17
10 | for i in range(1, 17):
11 | pool[i] = ds.node(i)
12 | for i in range(1, 17):
13 | self.assertEqual(pool[i].p, pool[i])
14 | for i in range(1, 16, 2):
15 | pool[i].union(pool[i + 1])
16 | parent_list = [2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16]
17 | for i in range(1, 17):
18 | self.assertEqual(pool[i].p, pool[parent_list[i - 1]])
19 | for i in range(1, 14, 4):
20 | pool[i].union(pool[i + 2])
21 | parent_list = [2, 4, 4, 4, 6, 8, 8, 8, 10, 12, 12, 12, 14, 16, 16, 16]
22 | for i in range(1, 17):
23 | self.assertEqual(pool[i].p, pool[parent_list[i - 1]])
24 | pool[1].union(pool[5])
25 | parent_list = [4, 4, 4, 8, 8, 8, 8, 8, 10, 12, 12, 12, 14, 16, 16, 16]
26 | for i in range(1, 17):
27 | self.assertEqual(pool[i].p, pool[parent_list[i - 1]])
28 | pool[11].union(pool[13])
29 | parent_list = [4, 4, 4, 8, 8, 8, 8, 8, 10, 12, 12, 16, 16, 16, 16, 16]
30 | for i in range(1, 17):
31 | self.assertEqual(pool[i].p, pool[parent_list[i - 1]])
32 | pool[1].union(pool[10])
33 | parent_list = [8, 4, 4, 8, 8, 8, 8, 16, 10, 16, 12, 16, 16, 16, 16, 16]
34 | for i in range(1, 17):
35 | self.assertEqual(pool[i].p, pool[parent_list[i - 1]])
36 | self.assertTrue(pool[2].find_set() == pool[16])
37 | parent_list = [8, 16, 4, 16, 8, 8, 8,
38 | 16, 10, 16, 12, 16, 16, 16, 16, 16]
39 | for i in range(1, 17):
40 | self.assertEqual(pool[i].p, pool[parent_list[i - 1]])
41 | self.assertTrue(pool[9].find_set() == pool[16])
42 | parent_list = [8, 16, 4, 16, 8, 8, 8,
43 | 16, 16, 16, 12, 16, 16, 16, 16, 16]
44 | for i in range(1, 17):
45 | self.assertEqual(pool[i].p, pool[parent_list[i - 1]])
46 |
--------------------------------------------------------------------------------
/tests/disjoint_sets_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import unittest
4 | import disjoint_sets_linked_list as ds
5 |
6 |
7 | class TestDisjointSets(unittest.TestCase):
8 | def test_linked_lists_with_head_and_tail(self):
9 | pool = [0] * 17
10 | for i in range(1, 17):
11 | pool[i] = ds.node(i)
12 | a = ds.header(pool[i])
13 | self.assertEqual(a.head, pool[i])
14 | self.assertEqual(a.tail, pool[i])
15 | for i in range(1, 16, 2):
16 | pool[i].union(pool[i + 1])
17 | for i in range(1, 14, 4):
18 | pool[i].union(pool[i + 2])
19 | pool[1].union(pool[5])
20 | pool[11].union(pool[13])
21 | pool[1].union(pool[10])
22 | self.assertTrue(pool[2].find_set() == pool[1])
23 | self.assertTrue(pool[9].find_set() == pool[1])
24 |
25 | def test_linked_lists_no_tail(self):
26 | pool = [0] * 17
27 | for i in range(1, 17):
28 | pool[i] = ds.node_notail(i)
29 | ds.header_notail(pool[i])
30 | for i in range(1, 16, 2):
31 | pool[i].union(pool[i + 1])
32 | for i in range(1, 14, 4):
33 | pool[i].union(pool[i + 2])
34 | pool[1].union(pool[5])
35 | pool[11].union(pool[13])
36 | pool[1].union(pool[10])
37 | self.assertTrue(pool[2].find_set() == pool[16])
38 | self.assertTrue(pool[9].find_set() == pool[16])
39 |
--------------------------------------------------------------------------------
/tests/hamiltonian_path_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import unittest
3 | from graph import Vertex, Graph
4 | from hamiltonian_path import hamiltonian_path
5 |
6 |
7 | class TestHamiltonianPath(unittest.TestCase):
8 | def testHamPath(self):
9 | r = Vertex('r')
10 | s = Vertex('s')
11 | t = Vertex('t')
12 | x = Vertex('x')
13 | y = Vertex('y')
14 | z = Vertex('z')
15 | vertices = [r, s, t, x, y, z]
16 | edges = [(r, s), (s, t), (t, x), (x, y), (y, z)]
17 | G = Graph(vertices, edges)
18 | self.assertEqual([hamiltonian_path(G, r, v) for v in vertices], [False, False, False, False, False, True])
19 | edges = [(r, s), (r, t), (s, x), (s, y), (t, z)]
20 | G = Graph(vertices, edges)
21 | self.assertEqual([hamiltonian_path(G, r, v) for v in vertices], [False, False, False, False, False, False])
22 | edges = [(r, s), (s, t), (s, x), (t, x)]
23 | vertices = [r, s, t, x]
24 | G = Graph(vertices, edges)
25 | self.assertEqual([hamiltonian_path(G, r, v) for v in vertices], [False, False, False, True])
26 | edges = [(r, s), (s, t), (s, x), (t, x), (r, y), (y, s)]
27 | vertices = [r, s, t, x, y]
28 | G = Graph(vertices, edges)
29 | self.assertEqual([hamiltonian_path(G, r, v) for v in vertices], [False, False, False, True, False])
30 | edges = [(r, s), (s, t), (s, x), (t, x), (r, y)]
31 | vertices = [r, s, t, x, y]
32 | G = Graph(vertices, edges)
33 | self.assertEqual([hamiltonian_path(G, r, v) for v in vertices], [False, False, False, False, False])
34 |
--------------------------------------------------------------------------------
/tests/heap_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from heap import MaxHeap, MinHeap
3 |
4 |
5 | class TestHeap(unittest.TestCase):
6 | # def test_init(self):
7 | # a = heap([4, 1, 3, 2, 16, 9, 10, 14, 8, 7])
8 | # self.assertEqual(a.__heap, a)
9 | # self.assertEqual(a.__length, 10)
10 | # self.assertEqual(a.__heap_size, 10)
11 | def test_max_heapify(self):
12 | a = [16, 4, 10, 14, 7, 9, 3, 2, 8, 1]
13 | h = MaxHeap(a)
14 | h.max_heapify(1)
15 | self.assertEqual(h, [16, 14, 10, 8, 7, 9, 3, 2, 4, 1])
16 |
17 | def test_build_max_heap(self):
18 | a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7]
19 | h = MaxHeap(a)
20 | h.build_max_heap()
21 | self.assertEqual(h, [16, 14, 10, 8, 7, 9, 3, 2, 4, 1])
22 |
23 | def test_heapsort(self):
24 | a = [4, 1, 3, 3, 16, 9, 10, 14, 8, 7]
25 | h = MaxHeap(a)
26 | h.heapsort()
27 | self.assertEqual(h, [1, 3, 3, 4, 7, 8, 9, 10, 14, 16])
28 |
29 | def test_min_heapify(self):
30 | a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16]
31 | h = MinHeap(a)
32 | h.min_heapify(1)
33 | self.assertEqual(h, [1, 2, 3, 4, 7, 8, 9, 10, 14, 16])
34 |
35 | def test_build_min_heap(self):
36 | a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16]
37 | h = MinHeap(a)
38 | h.build_min_heap()
39 | self.assertEqual(h, [1, 2, 3, 4, 7, 8, 9, 10, 14, 16])
40 |
--------------------------------------------------------------------------------
/tests/insertion_sort_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import unittest
3 | import random
4 | from insertion_sort import insertion_sort, insertion_sort_recursive, insert_with_linear_search, \
5 | insert_with_binary_search
6 |
7 |
8 | class TestInsertionSort(unittest.TestCase):
9 | def test_insertion_sort_with_linear_search(self):
10 | for _ in range(100):
11 | array = [random.randint(1, 10000) for _ in range(100)]
12 | array_copy = array[:]
13 | insertion_sort(array, insert_method=insert_with_linear_search)
14 | self.assertEqual(array, sorted(array_copy))
15 |
16 | def test_insertion_sort_with_binary_search(self):
17 | for _ in range(100):
18 | array = [random.randint(1, 10000) for _ in range(100)]
19 | array_copy = array[:]
20 | insertion_sort(array, insert_method=insert_with_binary_search)
21 | self.assertEqual(array, sorted(array_copy))
22 |
23 | def test_insertion_sort_recursive(self):
24 | for _ in range(100):
25 | array = [random.randint(1, 10000) for _ in range(100)]
26 | array_copy = array[:]
27 | insertion_sort_recursive(array)
28 | self.assertEqual(array, sorted(array_copy))
29 | for _ in range(100):
30 | array = [random.randint(1, 10000) for _ in range(100)]
31 | array_copy = array[:]
32 | insertion_sort_recursive(
33 | array, insert_method=insert_with_binary_search)
34 | self.assertEqual(array, sorted(array_copy))
35 |
--------------------------------------------------------------------------------
/tests/inversion_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | import unittest
4 | import random
5 | from inversion import inversion_with_insertion_sort, inversion_with_merge_sort
6 |
7 |
8 | class TestInversion(unittest.TestCase):
9 | def test_inversion_with_insertion_sort(self):
10 | for _ in range(100):
11 | array = [random.randint(0, 100) for _ in range(100)]
12 | expected_result = 0
13 | for i in range(len(array)):
14 | for j in range(i + 1, len(array)):
15 | if array[i] > array[j]:
16 | expected_result += 1
17 | self.assertEqual(inversion_with_insertion_sort(array), expected_result)
18 |
19 | def test_inversion_with_merge_sort(self):
20 | for _ in range(100):
21 | array = [random.randint(0, 100) for _ in range(100)]
22 | expected_result = 0
23 | for i in range(len(array)):
24 | for j in range(i + 1, len(array)):
25 | if array[i] > array[j]:
26 | expected_result += 1
27 | self.assertEqual(inversion_with_merge_sort(array), expected_result)
28 |
--------------------------------------------------------------------------------
/tests/k_way_merge_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import unittest
3 | from k_way_merge import k_way_merge
4 | from random_array import random_arrays
5 |
6 |
7 | class TestKWayMerge(unittest.TestCase):
8 | def test_k_way_merge(self):
9 | for array in random_arrays():
10 | lists = []
11 | for i in range(10):
12 | lists.append(array[10 * i: (i + 1) * 10])
13 | lists[-1].sort()
14 | self.assertEqual(k_way_merge(lists), sorted(array))
15 |
--------------------------------------------------------------------------------
/tests/linked_list_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from linkedlist import LinkedList, LinkedListNode
3 |
4 |
5 | class TestLinkedList(unittest.TestCase):
6 | def test_insert(self):
7 | L = LinkedList()
8 | a = LinkedListNode(1)
9 | b = LinkedListNode(4)
10 | c = LinkedListNode(16)
11 | d = LinkedListNode(9)
12 | e = LinkedListNode(25)
13 | L.insert(a)
14 | L.insert(b)
15 | L.insert(c)
16 | L.insert(d)
17 | L.insert(e)
18 | l = []
19 | x = L.head
20 | while x:
21 | l.append(x)
22 | x = x.next
23 | self.assertEqual(l, [e, d, c, b, a])
24 |
25 | def test_search(self):
26 | L = LinkedList()
27 | a = LinkedListNode(1)
28 | b = LinkedListNode(4)
29 | c = LinkedListNode(16)
30 | d = LinkedListNode(9)
31 | e = LinkedListNode(25)
32 | L.insert(a)
33 | L.insert(b)
34 | L.insert(c)
35 | L.insert(d)
36 | L.insert(e)
37 | self.assertEqual(L.search(4), b)
38 |
39 | def test_delete(self):
40 | L = LinkedList()
41 | a = LinkedListNode(1)
42 | b = LinkedListNode(4)
43 | c = LinkedListNode(16)
44 | d = LinkedListNode(9)
45 | e = LinkedListNode(25)
46 | L.insert(a)
47 | L.insert(b)
48 | L.insert(c)
49 | L.insert(d)
50 | L.insert(e)
51 | L.delete(b)
52 | l = []
53 | x = L.head
54 | while x:
55 | l.append(x)
56 | x = x.next
57 | self.assertEqual(l, [e, d, c, a])
58 |
--------------------------------------------------------------------------------
/tests/longest_common_subsequence_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import unittest
3 | from longest_common_subsequence import lcs_length_one_row, lcs_length
4 |
5 |
6 | class TestLCS(unittest.TestCase):
7 | def test_lcs_length(self):
8 | X = "ABCBDAB"
9 | Y = "BDCABA"
10 | c, b = lcs_length(X, Y)
11 | self.assertEqual(c[len(X), len(Y)], 4)
12 | X = [1, 0, 0, 1, 0, 1, 0, 1]
13 | Y = [0, 1, 0, 1, 1, 0, 1, 1, 0]
14 | c, b = lcs_length(X, Y)
15 | self.assertEqual(c[len(X), len(Y)], 6)
16 | X = "ACCGGTCGAGTGCGCGGAAGCCGGCCGAA"
17 | Y = "GTCGTTCGGAATGCCGTTGCTCTGTAAA"
18 | c, b = lcs_length(X, Y)
19 | self.assertEqual(c[len(X), len(Y)], 20)
20 |
21 | def test_lcs_length_one_row(self):
22 | X = "ABCBDAB"
23 | Y = "BDCABA"
24 | self.assertEqual(lcs_length_one_row(X, Y), 4)
25 | X = [1, 0, 0, 1, 0, 1, 0, 1]
26 | Y = [0, 1, 0, 1, 1, 0, 1, 1, 0]
27 | self.assertEqual(lcs_length_one_row(X, Y), 6)
28 | X = "ACCGGTCGAGTGCGCGGAAGCCGGCCGAA"
29 | Y = "GTCGTTCGGAATGCCGTTGCTCTGTAAA"
30 | self.assertEqual(lcs_length_one_row(X, Y), 20)
31 |
--------------------------------------------------------------------------------
/tests/longest_monotonically_increasing_subsequence_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding=utf-8
3 | import unittest
4 | from longest_monotonically_increasing_subsequence import longest_monotonically_increasing_subsequence
5 |
6 |
7 | class TestLMIS(unittest.TestCase):
8 | def test_longest_monotonically_increasing_subsequence(self):
9 | X = [5, 4, 1, 3, 2]
10 | self.assertEqual(longest_monotonically_increasing_subsequence(X), 2)
11 | X = [1, 3, 4, 2, 5]
12 | self.assertEqual(longest_monotonically_increasing_subsequence(X), 4)
13 | X = [1, 3, 10, 5, 3, 4]
14 | self.assertEqual(longest_monotonically_increasing_subsequence(X), 3)
15 |
--------------------------------------------------------------------------------
/tests/merge_sort_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import unittest
3 | import random
4 | from merge_sort import merge_sort, merge_with_sentinel, merge_without_sentinel, merge_ins_sort_bottom_to_top, \
5 | merge_ins_sort_top_to_bottom
6 |
7 |
8 | class TestMergeSort(unittest.TestCase):
9 | def test_merge_sort_with_sentinel(self):
10 | for _ in range(100):
11 | array = [random.randint(1, 10000) for _ in range(100)]
12 | array_copy = array[:]
13 | merge_sort(array, merge_with_sentinel)
14 | self.assertEqual(array, sorted(array_copy))
15 |
16 | def test_merge_sort_without_sentinel(self):
17 | for _ in range(100):
18 | array = [random.randint(1, 10000) for _ in range(100)]
19 | array_copy = array[:]
20 | merge_sort(array, merge_without_sentinel)
21 | self.assertEqual(array, sorted(array_copy))
22 |
23 | def test_merge_ins_sort(self):
24 | for length in range(100, 200):
25 | array = [random.randint(1, 10000) for _ in range(length)]
26 | array_copy = array[:]
27 | merge_ins_sort_bottom_to_top(array, partition=1)
28 | self.assertEqual(array, sorted(array_copy))
29 | for length in range(100, 200):
30 | array = [random.randint(1, 10000) for _ in range(length)]
31 | array_copy = array[:]
32 | merge_ins_sort_top_to_bottom(array, sublist_length=15)
33 | self.assertEqual(array, sorted(array_copy))
34 |
--------------------------------------------------------------------------------
/tests/min_gap_tree_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import unittest
3 | from min_gap_tree import MinGapTree, MinGapNode
4 |
5 |
6 | class TestMinGapTree(unittest.TestCase):
7 | def test_insert_one(self):
8 | T = MinGapTree([50])
9 | self.wrap(T, 50, float("Inf"))
10 |
11 | def test_insert_two(self):
12 | T = MinGapTree([50, 38])
13 | self.wrap(T, 50, 12)
14 | self.wrap(T, 38, 12)
15 |
16 | def test_insert_three(self):
17 | T = MinGapTree([50, 38, 31])
18 | self.wrap(T, 38, 7)
19 | self.wrap(T, 31, 7)
20 | self.wrap(T, 50, float("Inf"))
21 |
22 | def test_insert_four(self):
23 | T = MinGapTree([50, 38, 31, 12])
24 | self.wrap(T, 38, 7)
25 | self.wrap(T, 31, 7)
26 | self.wrap(T, 50, float("Inf"))
27 | self.wrap(T, 12, 19)
28 |
29 | def test_insert_five(self):
30 | T = MinGapTree([50, 38, 31, 12, 19])
31 | self.wrap(T, 38, 7)
32 | self.wrap(T, 19, 7)
33 | self.wrap(T, 50, float("Inf"))
34 | self.wrap(T, 12, 7)
35 | self.wrap(T, 31, 7)
36 |
37 | def test_insert_six(self):
38 | T = MinGapTree([50, 38, 31, 12, 19, 9])
39 | self.wrap(T, 38, 3)
40 | self.wrap(T, 19, 3)
41 | self.wrap(T, 50, float("Inf"))
42 | self.wrap(T, 12, 3)
43 | self.wrap(T, 31, 7)
44 | self.wrap(T, 9, 3)
45 |
46 | def test_delete_one(self):
47 | T = MinGapTree([50, 38, 31, 12, 19, 9])
48 | T.delete(T.iterative_tree_search(9))
49 | self.wrap(T, 38, 7)
50 | self.wrap(T, 19, 7)
51 | self.wrap(T, 50, float("Inf"))
52 | self.wrap(T, 12, 7)
53 | self.wrap(T, 31, 7)
54 |
55 | def test_delete_two(self):
56 | T = MinGapTree([50, 38, 31, 12, 19, 9])
57 | T.delete(T.iterative_tree_search(9))
58 | T.delete(T.iterative_tree_search(12))
59 | self.wrap(T, 38, 7)
60 | self.wrap(T, 19, 7)
61 | self.wrap(T, 50, float("Inf"))
62 | self.wrap(T, 31, 7)
63 |
64 | def test_delete_three(self):
65 | T = MinGapTree([50, 38, 31, 12, 19, 9])
66 | T.delete(T.iterative_tree_search(9))
67 | T.delete(T.iterative_tree_search(12))
68 | T.delete(T.iterative_tree_search(19))
69 | self.wrap(T, 38, 7)
70 | self.wrap(T, 31, 7)
71 | self.wrap(T, 50, float("Inf"))
72 |
73 | def test_delete_four(self):
74 | T = MinGapTree([50, 38, 31, 12, 19, 9])
75 | T.delete(T.iterative_tree_search(9))
76 | T.delete(T.iterative_tree_search(12))
77 | T.delete(T.iterative_tree_search(19))
78 | T.delete(T.iterative_tree_search(31))
79 | self.wrap(T, 38, 12)
80 | self.wrap(T, 50, float("Inf"))
81 |
82 | def test_delete_five(self):
83 | T = MinGapTree([50, 38, 31, 12, 19, 9])
84 | T.delete(T.iterative_tree_search(9))
85 | T.delete(T.iterative_tree_search(12))
86 | T.delete(T.iterative_tree_search(19))
87 | T.delete(T.iterative_tree_search(31))
88 | T.delete(T.iterative_tree_search(38))
89 | self.wrap(T, 50, float("Inf"))
90 |
91 | def test_delete_six(self):
92 | T = MinGapTree([50, 38, 31, 12, 19, 9])
93 | T.delete(T.iterative_tree_search(9))
94 | T.delete(T.iterative_tree_search(12))
95 | T.delete(T.iterative_tree_search(19))
96 | T.delete(T.iterative_tree_search(31))
97 | T.delete(T.iterative_tree_search(38))
98 | T.delete(T.iterative_tree_search(50))
99 | self.assertEqual(T.root, T.nil)
100 |
101 | def wrap(self, tree, node, min_gap):
102 | self.assertEqual(tree.iterative_tree_search(node).min_gap, min_gap)
103 |
104 |
105 | if __name__ == '__main__':
106 | unittest.main()
107 |
--------------------------------------------------------------------------------
/tests/min_heap_with_linked_list_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | from linkedlist import LinkedList, LinkedListNode
4 | from min_heap_with_linked_list import MinHeap, MinPriorityQueue
5 |
6 |
7 | class TestHeap(unittest.TestCase):
8 | def test_min_heapify(self):
9 | L1 = LinkedList(1)
10 | L2 = LinkedList(2)
11 | L2.insert(LinkedListNode(2))
12 | L2.insert(LinkedListNode(2))
13 | L3 = LinkedList(3)
14 | L3.insert(LinkedListNode(3))
15 | L3.insert(LinkedListNode(3))
16 | L4 = LinkedList(4)
17 | L4.insert(LinkedListNode(4))
18 | L5 = LinkedList(5)
19 | L3.insert(LinkedListNode(5))
20 | L3.insert(LinkedListNode(5))
21 | L3.insert(LinkedListNode(5))
22 | h = MinHeap([L5, L1, L2, L3, L4])
23 | h.min_heapify(0)
24 | self.assertEqual(h, [L1, L3, L2, L5, L4])
25 |
26 | def test_build_min_heap(self):
27 | L1 = LinkedList(1)
28 | L2 = LinkedList(2)
29 | L2.insert(LinkedListNode(2))
30 | L2.insert(LinkedListNode(2))
31 | L3 = LinkedList(3)
32 | L3.insert(LinkedListNode(3))
33 | L3.insert(LinkedListNode(3))
34 | L4 = LinkedList(4)
35 | L4.insert(LinkedListNode(4))
36 | L5 = LinkedList(5)
37 | L3.insert(LinkedListNode(5))
38 | L3.insert(LinkedListNode(5))
39 | L3.insert(LinkedListNode(5))
40 | h = MinHeap([L3, L4, L5, L2, L1])
41 | h.build_min_heap()
42 | self.assertEqual(h, [L1, L2, L5, L3, L4])
43 |
44 | def test_heap_minimum(self):
45 | L1 = LinkedList(1)
46 | L1.insert(LinkedListNode(1))
47 | L1.insert(LinkedListNode(1))
48 | L2 = LinkedList(2)
49 | L2.insert(LinkedListNode(2))
50 | L2.insert(LinkedListNode(2))
51 | L3 = LinkedList(3)
52 | L3.insert(LinkedListNode(3))
53 | L3.insert(LinkedListNode(3))
54 | L4 = LinkedList(4)
55 | L4.insert(LinkedListNode(4))
56 | L5 = LinkedList(5)
57 | L3.insert(LinkedListNode(5))
58 | L3.insert(LinkedListNode(5))
59 | L3.insert(LinkedListNode(5))
60 | q = MinPriorityQueue([L1, L2, L3, L4, L5])
61 | self.assertEqual(q.heap_minimum().key, 1)
62 |
63 | def test_heap_extract_min(self):
64 | L1 = LinkedList(1)
65 | L1.insert(LinkedListNode(1))
66 | L1.insert(LinkedListNode(1))
67 | L2 = LinkedList(2)
68 | L2.insert(LinkedListNode(2))
69 | L2.insert(LinkedListNode(2))
70 | L3 = LinkedList(3)
71 | L3.insert(LinkedListNode(3))
72 | L3.insert(LinkedListNode(3))
73 | L4 = LinkedList(4)
74 | L4.insert(LinkedListNode(4))
75 | L5 = LinkedList(5)
76 | L3.insert(LinkedListNode(5))
77 | L3.insert(LinkedListNode(5))
78 | L3.insert(LinkedListNode(5))
79 | q = MinPriorityQueue([L1, L2, L3, L4, L5])
80 | self.assertEqual(q.heap_extract_min().key, 1)
81 | self.assertEqual(q, [L1, L2, L3, L4, L5])
82 | self.assertEqual(q.heap_extract_min().key, 1)
83 | self.assertEqual(q, [L2, L4, L3, L5, L5])
84 | # def test_heap_decrease_key(self):
85 | # a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16]
86 | # q = MinPriorityQueue(a)
87 | # q.heap_decrease_key(8, 1)
88 | # self.assertEqual(q, [1, 1, 3, 2, 7, 8, 9, 10, 4, 16])
89 | # def test_heap_insert(self):
90 | # a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16]
91 | # q = MinPriorityQueue(a)
92 | # q.heap_extract_min()
93 | # q.min_heap_insert(0)
94 | # self.assertEqual(q, [0, 2, 3, 10, 4, 8, 9, 16, 14, 7])
95 |
--------------------------------------------------------------------------------
/tests/min_priority_queue_using_rb_tree_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import unittest
3 | from min_priority_queue_using_rb_tree import min_priority_queue
4 | from rb_tree import RbNode
5 |
6 |
7 | class TestMinPriorityQueue(unittest.TestCase):
8 | def test_extract_min(self):
9 | q = min_priority_queue([41, 38, 31, 12, 19, 9])
10 | self.assertEqual(q.heap_extract_min().key, 9)
11 | self.assertEqual(q.heap_extract_min().key, 12)
12 | self.assertEqual(q.heap_extract_min().key, 19)
13 | self.assertEqual(q.heap_extract_min().key, 31)
14 | self.assertEqual(q.heap_extract_min().key, 38)
15 | self.assertEqual(q.heap_extract_min().key, 41)
16 |
17 | def test_heap_decrease_key(self):
18 | q = min_priority_queue([41, 38, 31, 12, 19, 9])
19 | q.heap_decrease_key(q.iterative_tree_search(9), 5)
20 | q.heap_decrease_key(q.iterative_tree_search(38), 5)
21 | self.assertEqual(q.heap_extract_min().key, 5)
22 | self.assertEqual(q.heap_extract_min().key, 5)
23 | self.assertEqual(q.heap_extract_min().key, 12)
24 | self.assertEqual(q.heap_extract_min().key, 19)
25 | self.assertEqual(q.heap_extract_min().key, 31)
26 | self.assertEqual(q.heap_extract_min().key, 41)
27 |
28 | def test_heap_insert(self):
29 | q = min_priority_queue([41, 38, 31, 12, 19, 9])
30 | q.min_heap_insert(RbNode(5, None, None, None, 0))
31 | q.min_heap_insert(RbNode(38, None, None, None, 0))
32 | q.min_heap_insert(RbNode(50, None, None, None, 0))
33 | self.assertEqual(q.heap_extract_min().key, 5)
34 | self.assertEqual(q.heap_extract_min().key, 9)
35 | self.assertEqual(q.heap_extract_min().key, 12)
36 | self.assertEqual(q.heap_extract_min().key, 19)
37 | self.assertEqual(q.heap_extract_min().key, 31)
38 | self.assertEqual(q.heap_extract_min().key, 38)
39 | self.assertEqual(q.heap_extract_min().key, 38)
40 | self.assertEqual(q.heap_extract_min().key, 41)
41 | self.assertEqual(q.heap_extract_min().key, 50)
42 |
43 |
44 | if __name__ == '__main__':
45 | unittest.main()
46 |
--------------------------------------------------------------------------------
/tests/most_reliable_path_test.py:
--------------------------------------------------------------------------------
1 | from most_reliable_path import most_reliable_path
2 | import unittest
3 | from graph import Vertex, Graph
4 |
5 |
6 | class TestMostReliablePath(unittest.TestCase):
7 | def test_most_reliable_path(self):
8 | s = Vertex('s')
9 | u = Vertex('u')
10 | v = Vertex('v')
11 | w = Vertex('w')
12 | vertices = [s, u, v, w]
13 | edges = [(s, u), (s, v), (s, w), (u, v), (u, w), (w, u)]
14 | G = Graph(vertices, edges)
15 | probabilities = [0.2, 0.1, 0.15, 0.7, 0.6, 0.9]
16 | re = dict()
17 | for i, j in zip(edges, probabilities):
18 | re[i] = j
19 |
20 | def r(x, y):
21 | return re[(x, y)]
22 |
23 | most_reliable_path(G, r, s)
24 | self.assertEqual([i.p for i in vertices], [None, s, u, s])
25 | self.assertEqual([round(i.r, 2) for i in vertices], [1, 0.2, 0.14, 0.15])
26 | most_reliable_path(G, r, u)
27 | self.assertEqual([i.p for i in vertices], [None, None, u, u])
28 | self.assertEqual([round(i.r, 2) for i in vertices], [0, 1, 0.7, 0.6])
29 |
--------------------------------------------------------------------------------
/tests/partition_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from partition import partition, partition2, partition3
3 | from random_array import random_arrays
4 |
5 |
6 | class TestPartition(unittest.TestCase):
7 | def test_partition(self):
8 | for array in random_arrays():
9 | pivot_index = partition(array, 0, len(array) - 1)
10 | pivot = array[pivot_index]
11 | self.assertTrue(all(array[i] <= pivot for i in range(pivot_index)) and all(
12 | array[i] > pivot for i in range(pivot_index + 1, len(array))))
13 |
14 | def test_partition2(self):
15 | a = [2, 8, 7, 1, 4, 5, 6, 4]
16 | partition2(a, 0, 7)
17 | self.assertEqual(a, [2, 1, 4, 4, 7, 5, 6, 8])
18 |
19 | def test_partition3(self):
20 | for array in random_arrays():
21 | pivot_index = partition3(array, 0, len(array) - 1)
22 | pivot = array[pivot_index]
23 | self.assertTrue(all(array[i] <= pivot for i in range(pivot_index)) and all(
24 | array[i] > pivot for i in range(pivot_index + 1, len(array))))
25 |
--------------------------------------------------------------------------------
/tests/pointer_tree_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import unittest
3 | from pointer_tree import pointer_tree, pointer_node
4 |
5 |
6 | class TestOstree(unittest.TestCase):
7 | def test_insert_one(self):
8 | T = pointer_tree([41])
9 | self.wrap(T, 41, 41, 41, float("-Inf"), float("Inf"))
10 |
11 | def test_insert_two(self):
12 | T = pointer_tree([41, 38])
13 | self.wrap(T, 41, 38, 41, 38, float("Inf"))
14 | self.wrap(T, 38, 38, 38, float("-Inf"), 41)
15 |
16 | def test_insert_three(self):
17 | T = pointer_tree([41, 38, 31])
18 | self.wrap(T, 38, 31, 41, 31, 41)
19 | self.wrap(T, 31, 31, 31, float("-Inf"), 38)
20 | self.wrap(T, 41, 41, 41, 38, float("Inf"))
21 |
22 | def test_insert_four(self):
23 | T = pointer_tree([41, 38, 31, 12])
24 | self.wrap(T, 38, 12, 41, 31, 41)
25 | self.wrap(T, 31, 12, 31, 12, 38)
26 | self.wrap(T, 41, 41, 41, 38, float("Inf"))
27 | self.wrap(T, 12, 12, 12, float("-Inf"), 31)
28 |
29 | def test_insert_five(self):
30 | T = pointer_tree([41, 38, 31, 12, 19])
31 | self.wrap(T, 38, 12, 41, 31, 41)
32 | self.wrap(T, 19, 12, 31, 12, 31)
33 | self.wrap(T, 41, 41, 41, 38, float("Inf"))
34 | self.wrap(T, 12, 12, 12, float("-Inf"), 19)
35 | self.wrap(T, 31, 31, 31, 19, 38)
36 |
37 | def test_insert_six(self):
38 | T = pointer_tree([41, 38, 31, 12, 19, 9])
39 | self.wrap(T, 38, 9, 41, 31, 41)
40 | self.wrap(T, 19, 9, 31, 12, 31)
41 | self.wrap(T, 41, 41, 41, 38, float("Inf"))
42 | self.wrap(T, 12, 9, 12, 9, 19)
43 | self.wrap(T, 31, 31, 31, 19, 38)
44 | self.wrap(T, 9, 9, 9, float("-Inf"), 12)
45 |
46 | def test_delete_one(self):
47 | T = pointer_tree([41, 38, 31, 12, 19, 9])
48 | T.delete(T.iterative_tree_search(9))
49 | self.wrap(T, 38, 12, 41, 31, 41)
50 | self.wrap(T, 19, 12, 31, 12, 31)
51 | self.wrap(T, 41, 41, 41, 38, float("Inf"))
52 | self.wrap(T, 12, 12, 12, float("-Inf"), 19)
53 | self.wrap(T, 31, 31, 31, 19, 38)
54 |
55 | def test_delete_two(self):
56 | T = pointer_tree([41, 38, 31, 12, 19, 9])
57 | T.delete(T.iterative_tree_search(9))
58 | T.delete(T.iterative_tree_search(12))
59 | self.wrap(T, 38, 19, 41, 31, 41)
60 | self.wrap(T, 19, 19, 31, float("-Inf"), 31)
61 | self.wrap(T, 41, 41, 41, 38, float("Inf"))
62 | self.wrap(T, 31, 31, 31, 19, 38)
63 |
64 | def test_delete_three(self):
65 | T = pointer_tree([41, 38, 31, 12, 19, 9])
66 | T.delete(T.iterative_tree_search(9))
67 | T.delete(T.iterative_tree_search(12))
68 | T.delete(T.iterative_tree_search(19))
69 | self.wrap(T, 38, 31, 41, 31, 41)
70 | self.wrap(T, 31, 31, 31, float("-Inf"), 38)
71 | self.wrap(T, 41, 41, 41, 38, float("Inf"))
72 |
73 | def test_delete_four(self):
74 | T = pointer_tree([41, 38, 31, 12, 19, 9])
75 | T.delete(T.iterative_tree_search(9))
76 | T.delete(T.iterative_tree_search(12))
77 | T.delete(T.iterative_tree_search(19))
78 | T.delete(T.iterative_tree_search(31))
79 | self.wrap(T, 38, 38, 41, float("-Inf"), 41)
80 | self.wrap(T, 41, 41, 41, 38, float("Inf"))
81 |
82 | def test_delete_five(self):
83 | T = pointer_tree([41, 38, 31, 12, 19, 9])
84 | T.delete(T.iterative_tree_search(9))
85 | T.delete(T.iterative_tree_search(12))
86 | T.delete(T.iterative_tree_search(19))
87 | T.delete(T.iterative_tree_search(31))
88 | T.delete(T.iterative_tree_search(38))
89 | self.wrap(T, 41, 41, 41, float("-Inf"), float("Inf"))
90 |
91 | def test_delete_six(self):
92 | T = pointer_tree([41, 38, 31, 12, 19, 9])
93 | T.delete(T.iterative_tree_search(9))
94 | T.delete(T.iterative_tree_search(12))
95 | T.delete(T.iterative_tree_search(19))
96 | T.delete(T.iterative_tree_search(31))
97 | T.delete(T.iterative_tree_search(38))
98 | T.delete(T.iterative_tree_search(41))
99 | self.assertEqual(T.root, T.nil)
100 |
101 | def wrap(self, tree, node, minimum, maximum, predecessor, successor):
102 | self.assertEqual(tree.iterative_tree_search(node).minimum.key, minimum)
103 | self.assertEqual(tree.iterative_tree_search(node).maximum.key, maximum)
104 | self.assertEqual(tree.iterative_tree_search(
105 | node).predecessor.key, predecessor)
106 | self.assertEqual(tree.iterative_tree_search(
107 | node).successor.key, successor)
108 |
109 |
110 | if __name__ == '__main__':
111 | unittest.main()
112 |
--------------------------------------------------------------------------------
/tests/polygon_area_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from polygon_area import polygon_area
3 |
4 |
5 | class TestPolygonArea(unittest.TestCase):
6 | def test_rectangle_area(self):
7 | rectangle = ((0, 0), (0, 2), (2, 2), (2, 0))
8 | self.assertEqual(polygon_area(rectangle), 4)
9 |
10 | def test_triangle_area(self):
11 | triangle = ((0, 0), (5, 0), (2.5, 5))
12 | self.assertEqual(polygon_area(triangle), 12.5)
13 |
--------------------------------------------------------------------------------
/tests/priority_queue_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from priority_queue import MaxPriorityQueue, MinPriorityQueue
3 |
4 |
5 | class TestMaxPriorityQueue(unittest.TestCase):
6 | def test_init(self):
7 | a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7]
8 | q = MaxPriorityQueue(a)
9 | self.assertEqual(q, [16, 14, 10, 8, 7, 9, 3, 2, 4, 1])
10 |
11 | def test_heap_maximum(self):
12 | a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7]
13 | self.assertEqual(MaxPriorityQueue(a).heap_maximum(), 16)
14 |
15 | def test_heap_extract_max(self):
16 | a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7]
17 | h = MaxPriorityQueue(a)
18 | self.assertEqual(h.heap_extract_max(), 16)
19 | self.assertEqual(h, [14, 8, 10, 4, 7, 9, 3, 2, 1, 1])
20 |
21 | def test_heap_increase_key(self):
22 | a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7]
23 | h = MaxPriorityQueue(a)
24 | h.heap_increase_key(8, 15)
25 | self.assertEqual(h, [16, 15, 10, 14, 7, 9, 3, 2, 8, 1])
26 |
27 | def test_heap_insert(self):
28 | a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7]
29 | queue = MaxPriorityQueue(a)
30 | queue.heap_extract_max()
31 | queue.max_heap_insert(100)
32 | self.assertEqual(queue, [100, 14, 10, 4, 8, 9, 3, 2, 1, 7])
33 |
34 | def test_heap_delete(self):
35 | a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7]
36 | h = MaxPriorityQueue(a)
37 | h.heap_delete(4)
38 | self.assertEqual(h[0:h.heap_size], [16, 14, 10, 8, 1, 9, 3, 2, 4])
39 | h.heap_delete(2)
40 | self.assertEqual(h[0:h.heap_size], [16, 14, 9, 8, 1, 4, 3, 2])
41 | h.heap_delete(0)
42 | self.assertEqual(h[0:h.heap_size], [14, 8, 9, 2, 1, 4, 3])
43 | h.heap_delete(5)
44 | self.assertEqual(h[0:h.heap_size], [14, 8, 9, 2, 1, 3])
45 | h.heap_delete(3)
46 | self.assertEqual(h[0:h.heap_size], [14, 8, 9, 3, 1])
47 | h.heap_delete(1)
48 | self.assertEqual(h[0:h.heap_size], [14, 3, 9, 1])
49 | h.heap_delete(3)
50 | self.assertEqual(h[0:h.heap_size], [14, 3, 9])
51 | h.heap_delete(2)
52 | self.assertEqual(h[0:h.heap_size], [14, 3])
53 | h.heap_delete(1)
54 | self.assertEqual(h[0:h.heap_size], [14])
55 | h.heap_delete(0)
56 | self.assertEqual(h[0:h.heap_size], [])
57 |
58 |
59 | class TestMinPriorityQueue(unittest.TestCase):
60 | def test_init(self):
61 | a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16]
62 | q = MinPriorityQueue(a)
63 | self.assertEqual(q, [1, 2, 3, 4, 7, 8, 9, 10, 14, 16])
64 |
65 | def test_heap_minimum(self):
66 | a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16]
67 | self.assertEqual(MinPriorityQueue(a).heap_minimum(), 1)
68 |
69 | def test_heap_extract_min(self):
70 | a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16]
71 | q = MinPriorityQueue(a)
72 | self.assertEqual(q.heap_extract_min(), 1)
73 | self.assertEqual(q, [2, 4, 3, 10, 7, 8, 9, 16, 14, 16])
74 |
75 | def test_heap_decrease_key(self):
76 | a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16]
77 | q = MinPriorityQueue(a)
78 | q.heap_decrease_key(8, 1)
79 | self.assertEqual(q, [1, 1, 3, 2, 7, 8, 9, 10, 4, 16])
80 |
81 | def test_heap_insert(self):
82 | a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16]
83 | q = MinPriorityQueue(a)
84 | q.heap_extract_min()
85 | q.min_heap_insert(0)
86 | self.assertEqual(q, [0, 2, 3, 10, 4, 8, 9, 16, 14, 7])
87 |
--------------------------------------------------------------------------------
/tests/quicksort_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from partition import partition, partition2, partition3
3 | import random
4 | from quicksort import quicksort, randomized_quicksort
5 |
6 |
7 | class TestQuickSort(unittest.TestCase):
8 | def test_quicksort(self):
9 | for _ in range(100):
10 | array = [random.randint(1, 10000) for _ in range(100)]
11 | array_copy = array[:]
12 | quicksort(array, 0, len(array) - 1, partition)
13 | array_copy.sort()
14 | self.assertEqual(array, array_copy)
15 | for _ in range(100):
16 | array = [random.randint(1, 10000) for _ in range(100)]
17 | array_copy = array[:]
18 | quicksort(array, 0, len(array) - 1, partition2)
19 | array_copy.sort()
20 | self.assertEqual(array, array_copy)
21 | for _ in range(100):
22 | array = [random.randint(1, 10000) for _ in range(100)]
23 | array_copy = array[:]
24 | quicksort(array, 0, len(array) - 1, partition3)
25 | array_copy.sort()
26 | self.assertEqual(array, array_copy)
27 |
28 | def test_randomized_quicksort(self):
29 | for _ in range(100):
30 | array = [random.randint(1, 10000) for _ in range(100)]
31 | array_copy = array[:]
32 | randomized_quicksort(array, 0, len(array) - 1)
33 | array_copy.sort()
34 | self.assertEqual(array, array_copy)
35 |
--------------------------------------------------------------------------------
/tests/randomized_select_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from randomized_select import randomized_select
3 |
4 |
5 | class TestRandSelect(unittest.TestCase):
6 | def test_randomize_select_distinct(self):
7 | a = [10, 11, 5, 3, 2, 6, 0, 8, 100, 50]
8 | self.assertEqual(randomized_select(a, 0, 9, 5), 6)
9 |
10 | def test_randomize_select_duplicate(self):
11 | a = [10, 11, 5, 8, 2, 6, 8, 8, 100, 50]
12 | self.assertEqual(randomized_select(a, 0, 9, 4), 8)
13 | self.assertEqual(randomized_select(a, 0, 9, 5), 8)
14 | self.assertEqual(randomized_select(a, 0, 9, 6), 8)
15 |
--------------------------------------------------------------------------------
/tests/selection_sort_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 | import unittest
5 | from random_array import random_arrays
6 | from selection_sort import selection_sort
7 |
8 |
9 | class TestSelectionSort(unittest.TestCase):
10 | def test_selection_sort(self):
11 | for array in random_arrays():
12 | sorted_array = sorted(array)
13 | selection_sort(array)
14 | self.assertEqual(array, sorted_array)
15 |
--------------------------------------------------------------------------------
/tests/test_binary_add.py:
--------------------------------------------------------------------------------
1 | from unittest import TestCase
2 | from binary_add import binary_add
3 |
4 |
5 | class Test(TestCase):
6 | def test_binary_add(self):
7 | array1 = [1, 0, 1, 0]
8 | array2 = [0, 1, 1, 0]
9 | self.assertEqual(binary_add(array1, array2), [1, 0, 0, 0, 0])
10 |
--------------------------------------------------------------------------------
/tests/test_deque.py:
--------------------------------------------------------------------------------
1 | from unittest import TestCase
2 |
3 | from Queue import FullException, EmptyException
4 | from deque import Deque
5 |
6 |
7 | class TestDeque(TestCase):
8 | def test_enqueue_tail_and_dequeue_head(self):
9 | deque = Deque(3)
10 | deque.enqueue_tail(1)
11 | deque.enqueue_tail(2)
12 | with self.assertRaises(FullException):
13 | deque.enqueue_tail(3)
14 | self.assertEqual(1, deque.dequeue_head())
15 | self.assertEqual(2, deque.dequeue_head())
16 | with self.assertRaises(EmptyException):
17 | deque.dequeue_head()
18 |
19 | def test_enqueue_head_and_dequeue_tail(self):
20 | deque = Deque(3)
21 | deque.enqueue_head(1)
22 | deque.enqueue_head(2)
23 | with self.assertRaises(FullException):
24 | deque.enqueue_head(3)
25 | self.assertEqual(1, deque.dequeue_tail())
26 | self.assertEqual(2, deque.dequeue_tail())
27 | with self.assertRaises(EmptyException):
28 | deque.dequeue_tail()
29 |
30 | def test_enqueue_tail_and_dequeue_tail(self):
31 | deque = Deque(3)
32 | deque.enqueue_tail(1)
33 | deque.enqueue_tail(2)
34 | self.assertEqual(2, deque.dequeue_tail())
35 | self.assertEqual(1, deque.dequeue_tail())
36 | with self.assertRaises(EmptyException):
37 | deque.dequeue_tail()
38 | with self.assertRaises(EmptyException):
39 | deque.dequeue_head()
40 |
41 | def test_enqueue_head_and_dequeue_head(self):
42 | deque = Deque(3)
43 | deque.enqueue_head(1)
44 | deque.enqueue_head(2)
45 | self.assertEqual(2, deque.dequeue_head())
46 | self.assertEqual(1, deque.dequeue_head())
47 | with self.assertRaises(EmptyException):
48 | deque.dequeue_tail()
49 | with self.assertRaises(EmptyException):
50 | deque.dequeue_head()
51 |
--------------------------------------------------------------------------------
/tests/test_dynamic_array.py:
--------------------------------------------------------------------------------
1 | from unittest import TestCase
2 | from dynamic_array import DynamicArray
3 |
4 |
5 | class TestDynamicArray(TestCase):
6 | def test_add_and_get_and_size(self):
7 | dynamic_array = DynamicArray(2)
8 | self.assertEqual(0, dynamic_array.size())
9 | dynamic_array.add(1)
10 | dynamic_array.add(2)
11 | dynamic_array.add(3)
12 | self.assertEqual(3, dynamic_array.size())
13 | self.assertEqual(1, dynamic_array.get(0))
14 | self.assertEqual(2, dynamic_array.get(1))
15 | self.assertEqual(3, dynamic_array.get(2))
16 |
--------------------------------------------------------------------------------
/tests/test_euclid.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | from unittest import TestCase
4 |
5 | from euclid import euclid
6 |
7 |
8 | class TestEuclid(TestCase):
9 | def test_gcd(self):
10 | self.assertEqual(euclid(10, 3), 1)
11 | self.assertEqual(euclid(10, 4), 2)
12 | self.assertEqual(euclid(10, 1), 1)
13 | self.assertEqual(euclid(10, 5), 5)
14 |
--------------------------------------------------------------------------------
/tests/test_gcd.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | from unittest import TestCase
4 |
5 | from gcd import gcd
6 |
7 |
8 | class TestGcd(TestCase):
9 | def test_gcd(self):
10 | self.assertEqual(gcd(10, 3), 1)
11 | self.assertEqual(gcd(10, 4), 2)
12 | self.assertEqual(gcd(10, 1), 1)
13 | self.assertEqual(gcd(10, 5), 5)
14 |
--------------------------------------------------------------------------------
/tests/test_lowest_common_multiple.py:
--------------------------------------------------------------------------------
1 | from unittest import TestCase
2 | from lowest_common_multiple import lcm
3 |
4 |
5 | class LcmTest(TestCase):
6 | def test_lcm(self):
7 | self.assertEqual(lcm(10, 1), 10)
8 | self.assertEqual(lcm(10, 8), 40)
9 | self.assertEqual(lcm(15, 9), 45)
10 |
--------------------------------------------------------------------------------
/tests/test_merge.py:
--------------------------------------------------------------------------------
1 | from unittest import TestCase
2 | from merge import merge_without_sentinel, merge_with_sentinel
3 | from random_array import random_arrays
4 |
5 |
6 | class MergeTest(TestCase):
7 | def test_merge_with_sentinel(self):
8 | for array in random_arrays():
9 | left_array = array[:len(array) // 2]
10 | right_array = array[len(array) // 2:]
11 | left_array.sort()
12 | right_array.sort()
13 | result_array = left_array + right_array
14 | merge_with_sentinel(result_array, 0, len(array) // 2 - 1, len(array) - 1)
15 | self.assertEqual(result_array, sorted(array))
16 |
17 | def test_merge_without_sentinel(self):
18 | for array in random_arrays():
19 | left_array = array[:len(array) // 2]
20 | right_array = array[len(array) // 2:]
21 | left_array.sort()
22 | right_array.sort()
23 | result_array = left_array + right_array
24 | merge_without_sentinel(result_array, 0, len(array) // 2 - 1, len(array) - 1)
25 | self.assertEqual(result_array, sorted(array))
26 |
--------------------------------------------------------------------------------
/tests/test_pow.py:
--------------------------------------------------------------------------------
1 | import math
2 | import random
3 | from unittest import TestCase
4 | from pow import pow1, pow2
5 |
6 |
7 | class Test(TestCase):
8 | def test_pow1(self):
9 | x = random.randint(1, 10)
10 | for n in range(10):
11 | self.assertEqual(pow1(x, n), math.pow(x, n))
12 |
13 | def test_pow2(self):
14 | x = random.randint(1, 10)
15 | for n in range(10):
16 | self.assertEqual(pow2(x, n), math.pow(x, n))
17 |
--------------------------------------------------------------------------------
/tests/test_queue.py:
--------------------------------------------------------------------------------
1 | from unittest import TestCase
2 | from Queue import Queue, EmptyException, FullException
3 |
4 |
5 | class TestQueue(TestCase):
6 | def test_enqueue_and_dequeue(self):
7 | queue = Queue(3)
8 | queue.enqueue(1)
9 | queue.enqueue(2)
10 | with self.assertRaises(FullException):
11 | queue.enqueue(3)
12 | self.assertEqual(1, queue.dequeue())
13 | self.assertEqual(2, queue.dequeue())
14 | with self.assertRaises(EmptyException):
15 | queue.dequeue()
16 |
17 | def test_empty(self):
18 | queue = Queue(2)
19 | self.assertTrue(queue.empty())
20 |
21 | def test_full(self):
22 | queue = Queue(2)
23 | queue.enqueue(1)
24 | self.assertTrue(queue.full())
25 | queue = Queue(1)
26 | self.assertTrue(queue.full())
27 |
28 | def test_capacity(self):
29 | queue = Queue(5)
30 | self.assertEqual(4, queue.capacity())
31 |
--------------------------------------------------------------------------------
/tests/two_sum_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from random_array import random_arrays
3 | import random
4 | from two_sum import two_sum
5 |
6 |
7 | class TestInsertionSort(unittest.TestCase):
8 | def test_two_sum(self):
9 | for array in random_arrays(array_num=1000, array_size=10, array_lowerbound=1, array_upperbound=20):
10 | x = random.randint(1, 100)
11 | n = len(array)
12 | result = False
13 | for i in range(n):
14 | for j in range(i + 1, n):
15 | if array[i] + array[j] == x:
16 | result = True
17 | self.assertEqual(two_sum(x, array), result)
18 |
--------------------------------------------------------------------------------
/tests/universal_sink_test.py:
--------------------------------------------------------------------------------
1 | import universal_sink as us
2 | import unittest
3 | import numpy
4 |
5 |
6 | class TestRbtree(unittest.TestCase):
7 | def test_universal_sink(self):
8 | data = numpy.array(
9 | [[0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 1, 0], [1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 0], [1, 0, 0, 1, 0, 0],
10 | [1, 0, 0, 0, 0, 1]])
11 | self.assertEqual(us.universal_sink(data), 1)
12 | data = numpy.array(
13 | [[0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 1, 1], [1, 1, 0, 0, 0, 0], [1, 1, 0, 1, 0, 0],
14 | [1, 1, 0, 0, 0, 1]])
15 | self.assertEqual(us.universal_sink(data), 2)
16 | data = numpy.array(
17 | [[0, 1, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0], [1, 1, 1, 1, 0, 0],
18 | [1, 1, 1, 0, 0, 1]])
19 | self.assertEqual(us.universal_sink(data), 3)
20 | data = numpy.array(
21 | [[0, 1, 0, 1, 0, 0], [0, 0, 0, 1, 1, 0], [0, 0, 0, 1, 1, 1], [0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0],
22 | [0, 0, 0, 1, 0, 1]])
23 | self.assertEqual(us.universal_sink(data), 4)
24 | data = numpy.array(
25 | [[0, 1, 1, 0, 1, 0], [0, 0, 1, 0, 1, 0], [0, 0, 0, 0, 1, 0], [1, 1, 1, 0, 1, 0], [0, 0, 0, 0, 0, 0],
26 | [1, 1, 1, 0, 1, 1]])
27 | self.assertEqual(us.universal_sink(data), 5)
28 | data = numpy.array(
29 | [[0, 1, 1, 0, 1, 1], [0, 0, 1, 0, 1, 1], [0, 0, 0, 0, 1, 1], [1, 1, 1, 0, 1, 1], [0, 0, 0, 0, 0, 1],
30 | [0, 0, 0, 0, 0, 0]])
31 | self.assertEqual(us.universal_sink(data), 6)
32 |
--------------------------------------------------------------------------------
/tests/vEB_tree_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import unittest
4 | from vEB_tree import vEB_node
5 |
6 |
7 | class testVEB(unittest.TestCase):
8 | def test_vEB(self):
9 | v = vEB_node(2 ** 8)
10 | l = [1, 4, 50, 30, 100, 201]
11 | for i in l:
12 | v.insert(i)
13 | for i in l:
14 | self.assertEqual(v.member(i), True)
15 | self.assertEqual(v.member(2), False)
16 | self.assertEqual(v.member(3), False)
17 | v.delete(1)
18 | self.assertEqual(v.member(1), False)
19 | v.delete(100)
20 | self.assertEqual(v.member(100), False)
21 |
--------------------------------------------------------------------------------
/tests/wrestlers_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import unittest
3 | from wrestlers import wrestlers
4 |
5 |
6 | class TestWrestler(unittest.TestCase):
7 | def testBfs(self):
8 | wrestlersList = [1, 2, 3, 4, 5, 6, 7, 8]
9 | rivalriesList = [(1, 2), (1, 3), (2, 4), (3, 5), (3, 6),
10 | (5, 6), (5, 7), (5, 8), (6, 8), (7, 8)]
11 | self.assertEqual(wrestlers(wrestlersList, rivalriesList), False)
12 | rivalriesList = [(1, 2), (1, 3), (2, 4), (3, 5),
13 | (3, 6), (5, 7), (5, 8), (6, 8), (7, 8)]
14 | self.assertEqual(wrestlers(wrestlersList, rivalriesList), False)
15 | rivalriesList = [(1, 2), (1, 3), (2, 4), (3, 5),
16 | (3, 6), (5, 7), (5, 8), (6, 8)]
17 | self.assertEqual(wrestlers(wrestlersList, rivalriesList), True)
18 |
--------------------------------------------------------------------------------
/three_points_colinear.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from heap import MaxHeap
4 |
5 |
6 | class vector:
7 | def __init__(self, p1, p2, p1_index=0, p2_index=0):
8 | # gurantee that the polar angle of this Vector with respect to the origin point is in the range [0, pi)
9 | if p1[1] > p2[1]:
10 | self.x = p1[0] - p2[0]
11 | self.y = p1[1] - p2[1]
12 | elif p1[1] == p2[1]:
13 | self.y = 0
14 | self.x = abs(p1[0] - p2[0])
15 | else:
16 | self.x = p2[0] - p1[0]
17 | self.y = p2[1] - p1[1]
18 | self.p1 = p1
19 | self.p2 = p2
20 | self.p1_index = p1_index
21 | self.p2_index = p2_index
22 |
23 | def cross_product(self, v):
24 | return self.x * v.y - v.x * self.y
25 |
26 | def __lt__(self, v):
27 | return self.cross_product(v) > 0
28 |
29 | def __gt__(self, v):
30 | return self.cross_product(v) < 0
31 |
32 | def __eq__(self, v):
33 | return self.cross_product(v) == 0
34 |
35 | def __le__(self, v):
36 | return self.cross_product(v) >= 0
37 |
38 | def __ge__(self, v):
39 | return self.cross_product(v) <= 0
40 |
41 |
42 | def three_points_colinear(points_list):
43 | """ to determine whether any three points in a set of n points are colinear"""
44 | n = len(points_list)
45 | vectors_list = []
46 | for i in range(n):
47 | for j in range(i + 1, n):
48 | vectors_list.append(vector(points_list[i], points_list[j], i, j))
49 | v0 = vector((1, 0), (0, 0))
50 | heap_vectors = MaxHeap(vectors_list)
51 | heap_vectors.heapsort()
52 | status = [False] * n
53 | v = heap_vectors[0]
54 | status[v.p1_index] = True
55 | status[v.p2_index] = True
56 | stack = []
57 | stack.append(v.p1_index)
58 | stack.append(v.p2_index)
59 | for i in range(1, len(heap_vectors)):
60 | v = heap_vectors[i]
61 | if v == heap_vectors[i - 1]:
62 | if status[v.p1_index]:
63 | return True
64 | elif status[v.p2_index]:
65 | return True
66 | else:
67 | status[v.p1_index] = True
68 | status[v.p2_index] = True
69 | stack.append(v.p1_index)
70 | stack.append(v.p2_index)
71 | else:
72 | print(len(stack))
73 | print(stack)
74 | for i in range(len(stack)):
75 | status[stack.pop()] = False
76 | stack.append(v.p1_index)
77 | stack.append(v.p2_index)
78 | return False
79 |
--------------------------------------------------------------------------------
/three_sum.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding=utf-8
3 |
4 |
5 | def three_sum(array):
6 | """
7 | Given an array `array` of n integers, find one triplet
8 | in the array which gives the sum of zero.
9 |
10 | `array` must be in increasing order
11 | """
12 | n = len(array)
13 | for i in range(n - 2):
14 | j = i + 1
15 | k = n - 1
16 |
17 | while k >= j:
18 | if array[i] + array[j] + array[k] == 0:
19 | return array[i], array[j], array[k]
20 | elif array[i] + array[j] + array[k] > 0:
21 | k = k - 1
22 | else:
23 | j = j + 1
24 |
--------------------------------------------------------------------------------
/two_sum.py:
--------------------------------------------------------------------------------
1 | def two_sum(x: int, array: list):
2 | """
3 | an algorithm that, given a set S of n integers and another integer x,
4 | determines whether or not there exist two elements in S whose sum is exactly x.
5 | :param x:
6 | :param array:
7 | :return:
8 | """
9 | sorted_array = sorted(array)
10 | i = 0
11 | j = len(array) - 1
12 | while i < j:
13 | sum = sorted_array[i] + sorted_array[j]
14 | if sum == x:
15 | return True
16 | elif sum < x:
17 | i = i + 1
18 | else:
19 | j = j - 1
20 | return False
21 |
--------------------------------------------------------------------------------
/universal_sink.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 |
4 | def universal_sink(M):
5 | """
6 | An algorithm to determine whether a directed graph G contains
7 | a universal sink---a vertex with in-degree |V| - 1 and
8 | out-degree 0---in time O(V), given an adjacency matrix for G
9 |
10 | M: numpy matrix, the adjacency matrix for the graph
11 | rtype: vertex index if G contains a universal sink, otherwise, return None
12 | """
13 |
14 | return universal_sink_aux(M, 1)
15 |
16 |
17 | def universal_sink_aux(M, i):
18 | """
19 | M: numpy matrix
20 | i: vertex index
21 | """
22 | size = M.shape[0]
23 | j = i
24 | while True:
25 | if j > size or M[i - 1][j - 1] != 0:
26 | break
27 | j = j + 1
28 | if j > size:
29 | for j in range(1, i):
30 | if M[i - 1][j - 1] != 0:
31 | return None
32 | for j in range(1, size + 1):
33 | if M[j - 1][i - 1] == 0 and j != i:
34 | return None
35 | return i
36 | else:
37 | return universal_sink_aux(M, j)
38 |
--------------------------------------------------------------------------------
/vEB_tree.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import math
4 |
5 |
6 | class vEB_node:
7 | def __init__(self, u):
8 | """u must be exact power of 2, as required by CLRS; otherwise, the behavior is undefined"""
9 | self.u = u
10 | self.min = None
11 | self.max = None
12 | if u > 2:
13 | self.root = int(math.sqrt(u))
14 | self.cluster = [0] * self.root
15 | self.summary = vEB_node(self.root)
16 | for i in range(self.root):
17 | self.cluster[i] = vEB_node(self.root)
18 |
19 | def high(self, x):
20 | return x // self.root
21 |
22 | def low(self, x):
23 | return x % self.root
24 |
25 | def index(self, x, y):
26 | return x * self.root + y
27 |
28 | def member(self, x):
29 | if self.min == x or self.max == x:
30 | return True
31 | elif self.u == 2:
32 | return False
33 | else:
34 | return self.cluster[self.high(x)].member(self.low(x))
35 |
36 | def successor(self, x):
37 | if self.u == 2:
38 | if x == 0 and self.max == 1:
39 | return 1
40 | else:
41 | return None
42 | elif self.min is not None and x < self.min:
43 | return self.min
44 | else:
45 | max_low = self.cluster[self.high(x)].max
46 | if max_low is not None and self.low(x) < max_low:
47 | offset = self.cluster[self.high(x)].successor(self.low(x))
48 | return self.index(self.high(x), offset)
49 | else:
50 | succ_cluster = self.summary.successor(self.high(x))
51 | if succ_cluster is None:
52 | return None
53 | else:
54 | offset = self.cluster[succ_cluster].min
55 | return self.index(succ_cluster, offset)
56 |
57 | def empty_tree_insert(self, x):
58 | self.min = x
59 | self.max = x
60 |
61 | def insert(self, x):
62 | if self.min is None:
63 | self.empty_tree_insert(x)
64 | elif (x == self.min) or (x == self.max):
65 | return
66 | else:
67 | if x < self.min:
68 | x, self.min = self.min, x
69 | if self.u > 2:
70 | if self.cluster[self.high(x)].min is None:
71 | self.summary.insert(self.high(x))
72 | self.cluster[self.high(x)].empty_tree_insert(self.low(x))
73 | else:
74 | self.cluster[self.high(x)].insert(self.low(x))
75 | if x > self.max:
76 | self.max = x
77 |
78 | def delete(self, x):
79 | # print( "u = {}, x = {}".format(self.u, x))
80 | if self.min == self.max:
81 | # print( "min = {}, max = {}".format(self.min, self.max))
82 | if x == self.min:
83 | self.min = None
84 | self.max = None
85 | elif self.u == 2:
86 | if x == 0:
87 | self.min = 1
88 | else:
89 | self.max = 0
90 | elif x < self.min:
91 | return
92 | else:
93 | if x == self.min:
94 | first_cluster = self.summary.min
95 | x = self.index(first_cluster, self.cluster[first_cluster].min)
96 | self.min = x
97 | self.cluster[self.high(x)].delete(self.low(x))
98 | if self.cluster[self.high(x)].min is None:
99 | self.summary.delete(self.high(x))
100 | if x == self.max:
101 | summary_max = self.summary.max
102 | if summary_max is None:
103 | self.max = self.min
104 | else:
105 | self.max = self.index(
106 | summary_max, self.cluster[summary_max].max)
107 | elif x == self.max:
108 | self.max = self.index(
109 | self.high(x), self.cluster[self.high(x)].max)
110 |
111 | def print_veb(self):
112 | if self.u == 2:
113 | print("u = {}, min = {}, max = {}".format(
114 | self.u, self.min, self.max))
115 | else:
116 | print("u = {}, min = {}, max = {}".format(
117 | self.u, self.min, self.max))
118 | print("Summary: \t", )
119 | self.summary.print_veb()
120 | print()
121 | for i in range(self.root):
122 | self.cluster[i].print_veb()
123 | print()
124 |
--------------------------------------------------------------------------------
/wrestlers.py:
--------------------------------------------------------------------------------
1 | from queue import Queue
2 | from graph import Graph, Vertex
3 |
4 |
5 | def wrestlers(wrestlersList, rivalriesList):
6 | """
7 | There are two types of professional wrestlers: "babyfaces"
8 | ("good guys") and "heels" ("bad guys"). Between any pair of
9 | professional wrestlers, there may or may not be a rivalry.
10 | Given a list of professional wrestlers and a list of pairs of
11 | wrestlers for which there are rivalries, determine whether it is
12 | possible to designate some of the wrestlers as babyfaces and There
13 | remainder as heels such that each rivalry is between a babyfaces
14 | and a heel.
15 | """
16 | d = dict()
17 | vertices = [None] * len(wrestlersList)
18 | edges = [None] * len(rivalriesList)
19 | for i in range(len(wrestlersList)):
20 | vertices[i] = Vertex(wrestlersList[i])
21 | d[wrestlersList[i]] = vertices[i]
22 |
23 | for i in range(len(rivalriesList)):
24 | w1, w2 = rivalriesList[i]
25 | edges[i] = (d[w1], d[w2])
26 | g = Graph(vertices, edges, False)
27 |
28 | for u in g.vertices:
29 | u.type = 0
30 | for u in g.vertices:
31 | if u.type == 0:
32 | if not _bfs(g, u):
33 | return False
34 | return True
35 |
36 |
37 | def _bfs(g, s):
38 | s.type = 1
39 | q = Queue(2 * len(g.vertices))
40 | q.put(s)
41 | while not q.empty():
42 | u = q.get()
43 | for v in g.adj[u]:
44 | if u.type == v.type:
45 | return False
46 | elif v.type == 0:
47 | if u.type == 1:
48 | v.type = 2
49 | else:
50 | v.type = 1
51 | q.put(v)
52 | return True
53 |
--------------------------------------------------------------------------------