def _small_order_select(B, p, r, i): n = r - p + 1 m = n // 2 if i >= m: return _select_with_cascaded_swaps(B, n, p, r, i) for j in between(0, m - 1): if B[p + j] < B[p + m + j]: _cascaded_swap(B, n, p + j, p + m + j) if n % 2 == 1: _cascaded_align(B, n, p + m) m += 1 n += 1 r = B.length p = r - n + 1 idx = _small_order_select(B, p + m, r, i) r = B.length q = idx - i + 1 m = r - q + 1 n = 2 * m p = r - n + 1 for j in between(0, i - 1): _cascaded_swap(B, n, p + i + j, p + m + j) _select_with_cascaded_swaps(B, n, p, p + 2 * i - 1, i) return p + i - 1
def tasks_independent_bruteforce(deadlines): n = deadlines.length N = Array([len([d for d in deadlines if d <= t]) for t in between(1, n)]) for t in between(1, n): if N[t] > t: return False return True
def young_sort(A): n = int(math.sqrt(A.length)) Y = Matrix([[math.inf] * n] * n) for i in between(1, n ** 2): young_insert(Y, n, n, A[i]) for i in between(1, n ** 2): A[i] = young_extract_min(Y, n, n, 1, 1)
def memoized_matrix_chain(p): n = p.length - 1 m = Array([Array.indexed(1, n) for _ in between(1, n)]) for i in between(1, n): for j in between(i, n): m[i, j] = math.inf return lookup_chain(p, m, 1, n)
def young_sort(A): n = int(math.sqrt(A.length)) Y = Matrix([[math.inf] * n] * n) for i in between(1, n**2): young_insert(Y, n, n, A[i]) for i in between(1, n**2): A[i] = young_extract_min(Y, n, n, 1, 1)
def segments_intersect(a, b): a_vertical = is_verticle(a) b_vertical = is_verticle(b) if(a_vertical == b_vertical): # Lines are parallel if a_vertical and a[0][0] == b[0][0]: # Both verticle and in same column return ( util.between(a[0][1], b[0][1], b[1][1]) or util.between(a[1][1], b[0][1], b[1][1]) or util.between(b[0][1], a[0][1], a[1][1]) or util.between(b[1][1], a[0][1], a[1][1]) ) if not a_vertical and a[0][1] == b[0][1]: # Both horiztonal and in same row return ( util.between(a[0][0], b[0][0], b[1][0]) or util.between(a[1][0], b[0][0], b[1][0]) or util.between(b[0][0], a[0][0], a[1][0]) or util.between(b[1][0], a[0][0], a[1][0]) ) else: # Mixed vertical and horizontal vert, hori = (a, b) if a_vertical else (b, a) return util.between(vert[0][0], hori[0][0], hori[1][0]) and util.between(hori[0][1], vert[0][1], vert[1][1]) return False
def test_checkerboard(self): n = random.randint(1, 8) # profit[i, j] contains a triple (a, b, c), where the profit of moving from square of coords (i, j): # to square of coords (i+1, j-1) is a, to square of coords (i+1, j) is b, to square of coords (i+1, j+1) is c, # where (i, j) means i-th row from the bottom and j-th column from the left profit = Array([Array.indexed(1, n) for _ in between(1, n - 1)]) for i in between(1, n - 1): profit[i, 1] = (None, random.randint(-100, 100), random.randint(-100, 100)) for j in between(2, n - 1): profit[i, j] = (random.randint(-100, 100), random.randint(-100, 100), random.randint(-100, 100)) profit[i, n] = (random.randint(-100, 100), random.randint(-100, 100), None) captured_output = io.StringIO() actual_maximum_profit, squares, last_square = checkerboard( n, lambda x, y: checkerboard_profit(profit, x, y)) with redirect_stdout(captured_output): print_moves(squares, n, last_square) expected_maximum_profit = \ get_optimal_checkerboard_path_bruteforce(n, lambda x, y: checkerboard_profit(profit, x, y)) assert_that(actual_maximum_profit, is_(equal_to(expected_maximum_profit))) assert_squares_path(n, captured_output.getvalue().splitlines(), profit, expected_maximum_profit)
def merge_(A, p, q, r): n1 = q - p + 1 n2 = r - q L = Array.indexed(1, n1) R = Array.indexed(1, n2) for i in between(1, n1): L[i] = A[p + i - 1] for j in between(1, n2): R[j] = A[q + j] i = j = 1 k = p while i <= n1 and j <= n2: if L[i] <= R[j]: A[k] = L[i] i = i + 1 else: A[k] = R[j] j = j + 1 k = k + 1 while i <= n1: A[k] = L[i] i = i + 1 k = k + 1 while j <= n2: A[k] = R[j] j = j + 1 k = k + 1
def bucket_sort(A): n = A.length B = Array([[] for _ in range(n)], start=0) for i in between(1, n): B[math.floor(n * A[i])].append(A[i]) for i in between(0, n - 1): _insertion_sort_list(B[i]) _concatenate_lists(B, A)
def selection_sort(A): n = A.length for j in between(1, n - 1): min = j for i in between(j + 1, n): if A[i] < A[min]: min = i A[min], A[j] = A[j], A[min]
def activity_selector_bruteforce(s, f): n = s.length - 2 max_size = 0 for m in between(1, n): for activities_ids in itertools.combinations(between(1, n), m): if activities_compatible(activities_ids, s, f): max_size = max(max_size, m) return max_size
def knapsack_bruteforce(w, v, W): max_value = 0 n = w.length for m in between(1, n): for item_ids in itertools.combinations(between(1, n), m): if items_total_weight(item_ids, w) <= W: max_value = max(max_value, items_total_value(item_ids, v)) return max_value
def memoized_lcs_length(X, Y): m = X.length n = Y.length c = Array([Array.indexed(0, n) for _ in between(0, m)], start=0) for i in between(0, m): for j in between(0, n): c[i, j] = math.inf return lookup_lcs(c, X, Y, m, n)
def get_shortest_bitonic_path_length_bruteforce(points): n = points.length min_length = math.inf for k in between(0, n - 2): for right_path in itertools.combinations(between(2, n - 1), k): left_path = [x for x in rbetween(n - 1, 2) if x not in right_path] path_length = get_path_length(points, [1] + list(right_path) + [n] + left_path + [1]) min_length = min(min_length, path_length) return min_length
def get_optimal_schedule_bruteforce(times, profits, deadlines): n = times.length max_profit = 0 for m in between(1, n): for schedule in itertools.permutations(between(1, n), m): profit = get_schedule_total_profit(schedule, times, profits, deadlines) max_profit = max(max_profit, profit) return max_profit
def refueling_bruteforce(stations, n): min_stops = math.inf m = stations.length for nstops in between(0, m): for stops in itertools.combinations(between(1, m), nstops): if stops_valid(stops, stations, n): min_stops = min(min_stops, nstops) break return min_stops
def polynomial_evaluate(a, x): y = 0.0 n = a.length - 1 for i in between(0, n): s = a[i] for j in between(1, i): s = s * x y = y + s return y
def binary_add(A, B): n = A.length C = Array.indexed(1, n + 1) for i in between(1, n + 1): C[i] = 0 for i in between(1, n): sum = A[i] + B[i] + C[i] C[i] = sum % 2 C[i + 1] = math.floor(sum / 2) return C
def unit_circle_sort(A): n = A.length B = Array([[] for _ in range(n)], start=0) for i in between(1, n): d = math.sqrt(A[i].x**2 + A[i].y**2) B[math.ceil(d**2 * n) - 1].append( (A[i], d)) # store distances with points; we'll sort by them later for i in between(0, n - 1): _insertion_sort_list_by_distance(B[i]) _concatenate_lists_of_points(B, A)
def max_overlapping_activities(s, f): n = s.length max_overlaps = 0 for i in between(1, n): overlaps = 0 for j in between(1, n): if s[j] <= s[i] < f[j]: overlaps += 1 max_overlaps = max(max_overlaps, overlaps) return max_overlaps
def matrix_multiply(A, B): if A.columns != B.rows: raise RuntimeError('incompatible dimensions') else: C = Matrix.of_dimensions(A.rows, B.columns) for i in between(1, A.rows): for j in between(1, B.columns): C[i, j] = 0 for k in between(1, A.columns): C[i, j] = C[i, j] + A[i, k] * B[k, j] return C
def get_probabilities_for_optimal_bst(): n = random.randint(1, 10) p, _ = get_random_array(min_size=n, max_size=n) q, _ = get_random_array(min_size=n + 1, max_size=n + 1) q.start = 0 total = sum([x for x in p.elements + q.elements]) for i in between(1, n): p[i] /= total for i in between(0, n): q[i] /= total return p, q
def counting_sort(A, B, k): C = Array.indexed(0, k) for i in between(0, k): C[i] = 0 for j in between(1, A.length): C[A[j]] = C[A[j]] + 1 for i in between(1, k): C[i] = C[i] + C[i - 1] for j in rbetween(A.length, 1): B[C[A[j]]] = A[j] C[A[j]] = C[A[j]] - 1
def make_change(n, d): c = Array.indexed(0, n) denom = Array.indexed(1, n) c[0] = 0 for j in between(1, n): c[j] = math.inf for i in between(1, d.length): if j >= d[i] and 1 + c[j - d[i]] < c[j]: c[j] = 1 + c[j - d[i]] denom[j] = d[i] return c, denom
def knapsack(w, v, W): n = w.length K = Array([Array.indexed(0, W) for _ in between(0, n)], start=0) for j in between(0, W): K[0, j] = 0 for i in between(1, n): for j in between(0, W): K[i, j] = K[i - 1, j] if w[i] <= j and K[i - 1, j - w[i]] + v[i] > K[i, j]: K[i, j] = K[i - 1, j - w[i]] + v[i] return K
def tasks_independent(A, k): C = Array.indexed(0, k) for i in between(0, k): C[i] = 0 for j in between(1, A.length): C[A[j]] = C[A[j]] + 1 for i in between(1, k): C[i] = C[i] + C[i - 1] for t in between(1, k): if C[t] > t: return False return True
def _sort_by_character(A, p, r, position): k = ord('z') - ord('a') C = Array([0] * (k + 1), start=0) for j in between(p, r): x = ord(A[j][position - 1]) - ord('a') C[x] += 1 for i in between(1, k): C[i] += C[i - 1] B = Array.indexed(1, r - p + 1) for j in rbetween(r, p): x = ord(A[j][position - 1]) - ord('a') B[C[x]] = A[j] C[x] -= 1 A.elements[p - 1:r] = B.elements
def test_print_optimal_parens(self): n = random.randint(1, 10) s = Array([Array.indexed(1, n) for _ in between(1, n)]) for i in between(1, n - 1): for j in between(i + 1, n): s[i, j] = random.randint(i, j - 1) captured_output = io.StringIO() with redirect_stdout(captured_output): print_optimal_parens(s, 1, n) actual_output = captured_output.getvalue().splitlines()[0] expected_output = get_optimal_parens_bruteforce(s, 1, n) assert_that(actual_output, is_(equal_to(expected_output)))
def josephus_simulate(n, m): L = List() singly_linked_list_insert(L, SNode(n)) x = L.head for i in rbetween(n - 1, 1): singly_linked_list_insert(L, SNode(i)) x.next = L.head for i in between(1, n): for j in between(1, m): x = x.next print(x.next.key) if L.head is x.next: L.head = x.next.next x.next = x.next.next
def median_nearest(A, k): n = A.length x = select(A, 1, n, math.floor((n + 1) / 2)) dist = Array.indexed(1, n) for i in between(1, n): dist[i] = abs(A[i] - x) y = select(dist, 1, n, k) N = set() for i in between(1, n): if abs(A[i] - x) <= y: N.add(A[i]) if len(N) == k + 1: N.remove(x + y) return N
def dynamic_activity_selector(s, f): n = s.length - 2 c = Array([Array.indexed(0, n + 1) for _ in between(0, n + 1)]) A = Array([Array.indexed(0, n + 1) for _ in between(0, n + 1)]) for l in between(2, n + 2): for i in between(0, n - l + 2): j = i + l - 1 c[i, j] = 0 A[i, j] = set() for k in between(i + 1, j - 1): q = c[i, k] + c[k, j] + 1 if f[i] <= s[k] < f[k] <= s[j] and q > c[i, j]: c[i, j] = q A[i, j] = A[i, k] | {'a' + str(k)} | A[k, j] return A[0, n + 1]
def jugs_group(R, B): n = R.length for i in between(1, n - 1): j = i while R[i] != B[j]: j = j + 1 B[i], B[j] = B[j], B[i]
def monge_minimums(A): m = A.rows minimums_indices = _monge_minimums_indices(A) minimums = Array.indexed(1, m) for i in between(1, m): minimums[i] = A[i, minimums_indices[i]] return minimums
def get_maximum_lcs_length_bruteforce(sequence1, sequence2): max_length = 0 for i in between(1, min(sequence1.length, sequence2.length)): for subsequence in itertools.combinations(sequence1, i): if is_subsequence_of(subsequence, sequence2): max_length = len(subsequence) return max_length
def randomize_in_place_(A): n = A.length j = random(1, n) A[1], A[j] = A[j], A[1] for i in between(2, n): j = random(i, n) A[i], A[j] = A[j], A[i]
def _move_strings_with_exact_length_to_front(A, p, r, position): q = p for j in between(p, r): if len(A[j]) == position - 1: A[q], A[j] = A[j], A[q] q += 1 return q
def permute_by_sorting(A): n = A.length P = Array.indexed(1, n) for i in between(1, n): P[i] = random(1, n ** 3) _sort_using_priorities(A, P) return A
def sum_search(S, x): n = S.length merge_sort(S, 1, n) for i in between(1, n - 1): if recursive_binary_search(S, x - S[i], i + 1, n) is not None: return True return False
def get_maximum_lis_length_bruteforce(sequence): max_length = 0 for i in between(1, sequence.length): for subsequence in itertools.combinations(sequence, i): if is_monotonically_increasing(subsequence): max_length = len(subsequence) return max_length