Ejemplo n.º 1
0
def fastest_way_(a, t, e, x, n):
    f = Array([Array.indexed(1, 2), Array.indexed(1, 2)])
    l = Array([Array.indexed(1, n), Array.indexed(1, n)])
    f[1, 2] = e[1] + a[1, 1]
    f[2, 2] = e[2] + a[2, 1]
    for j in between(2, n):
        f[1, 1] = f[1, 2]
        f[2, 1] = f[2, 2]
        if f[1, 1] + a[1, j] <= f[2, 1] + t[2, j - 1] + a[1, j]:
            f[1, 2] = f[1, 1] + a[1, j]
            l[1, j] = 1
        else:
            f[1, 2] = f[2, 1] + t[2, j - 1] + a[1, j]
            l[1, j] = 2
        if f[2, 1] + a[2, j] <= f[1, 1] + t[1, j - 1] + a[2, j]:
            f[2, 2] = f[2, 1] + a[2, j]
            l[2, j] = 2
        else:
            f[2, 2] = f[1, 1] + t[1, j - 1] + a[2, j]
            l[2, j] = 1
    if f[1, 2] + x[1] <= f[2, 2] + x[2]:
        f_star = f[1, 2] + x[1]
        l_star = 1
    else:
        f_star = f[2, 2] + x[2]
        l_star = 2
    return f_star, l, l_star
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
def get_random_multiple_array_list(min_size=1, max_size=10, max_value=999):
    list_size = random.randint(min_size, max_size)
    array_size = random.randint(list_size, max_size)
    key, next, prev = Array.indexed(1, array_size), Array.indexed(1, array_size), Array.indexed(1, array_size)
    list_indexes = random.sample(range(1, array_size + 1), list_size)

    head = None
    prev_index = None
    for index in list_indexes:
        key[index] = random.randint(0, max_value)
        if prev_index is None:
            head = index
        else:
            next[prev_index] = index
            prev[index] = prev_index
        prev_index = index

    free_indexes = [i for i in range(1, array_size + 1) if i not in list_indexes]
    random.shuffle(free_indexes)

    free = None
    prev_free_index = None
    for free_index in free_indexes:
        if prev_free_index is None:
            free = free_index
        else:
            next[prev_free_index] = free_index
        prev_free_index = free_index

    return MultipleArrayList(key, next, prev, head, free)
Ejemplo n.º 4
0
def setup_activities(n):
    start_times = Array.indexed(0, n + 1)
    finish_times = Array.indexed(0, n + 1)
    for i in between(1, n):
        start_times[i] = random.randint(0, 49)
        finish_times[i] = start_times[i] + random.randint(1, 50)
    start_times[0], finish_times[0] = 0, 0
    start_times[n + 1], finish_times[n + 1] = math.inf, math.inf
    return start_times, finish_times
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
def get_random_huge_array(max_value=999):
    table_size = max_value
    table_capacity = random.randint(1, min(20, max_value))
    nelements = random.randint(0, table_capacity)
    table = Array.indexed(0, table_size - 1)
    stack = Array.indexed(1, table_capacity)
    keys = random.sample(range(max_value), nelements)

    for i, key in enumerate(keys):
        table[key] = i + 1
        stack[i + 1] = Element(key)
    stack.top = len(keys)

    return table, stack, keys
Ejemplo n.º 7
0
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]
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
def get_random_single_array_list(min_size=1, max_size=10, max_value=999):
    list_size = random.randint(min_size, max_size)
    array_size = 3 * random.randint(list_size, max_size)
    A = Array.indexed(1, array_size)
    list_indexes = random.sample(range(1, array_size + 1, 3), list_size)

    head = None
    prev_index = None
    for index in list_indexes:
        A[index] = random.randint(0, max_value)
        if prev_index is None:
            head = index
        else:
            A[prev_index + 1] = index
            A[index + 2] = prev_index
        prev_index = index

    free_indexes = [i for i in range(1, array_size + 1, 3) if i not in list_indexes]
    random.shuffle(free_indexes)

    free = None
    prev_free_index = None
    for free_index in free_indexes:
        if prev_free_index is None:
            free = free_index
        else:
            A[prev_free_index + 1] = free_index
        prev_free_index = free_index

    return SingleArrayList(A, head, free)
Ejemplo n.º 11
0
def greedy_make_change(n):
    C = Array.indexed(1, 6)
    d = Array([1, 2, 5, 10, 20, 50])
    for i in rbetween(d.length, 1):
        C[i] = math.floor(n / d[i])
        n %= d[i]
    return C
Ejemplo n.º 12
0
def matrix_chain_order(p):
    n = p.length - 1
    m = Array([Array.indexed(1, n) for _ in between(1, n)])
    s = Array([Array.indexed(1, n) for _ in between(1, n)])
    for i in between(1, n):
        m[i, i] = 0
    for l in between(2, n):
        for i in between(1, n - l + 1):
            j = i + l - 1
            m[i, j] = math.inf
            for k in between(i, j - 1):
                q = m[i, k] + m[k + 1, j] + p[i - 1] * p[k] * p[j]
                if q < m[i, j]:
                    m[i, j] = q
                    s[i, j] = k
    return m, s
Ejemplo n.º 13
0
def _construct_secondary_hash_table_no_collisions(keys, size, h_):
    S = Array.indexed(0, size - 1)
    for k in keys:
        if S[h_(k)] is not None:
            return None
        S[h_(k)] = k
    return S
Ejemplo n.º 14
0
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)
Ejemplo n.º 15
0
def assert_valid_operations(operations, word1, word2):
    i = 1
    j = 1
    m = word1.length
    n = word2.length
    result = Array.indexed(1, n)
    for op in operations:
        if op == 'copy':
            result[j] = word1[i]
            i += 1
            j += 1
        elif op[:11] == 'replace by ':
            ch = op[11:]
            result[j] = ch
            i += 1
            j += 1
        elif op == 'delete':
            i += 1
        elif op[:7] == 'insert ':
            ch = op[7:]
            result[j] = ch
            j += 1
        elif op == 'twiddle':
            result[j] = word1[i + 1]
            result[j + 1] = word1[i]
            i += 2
            j += 2
        else:
            assert_that(op, is_(equal_to('kill')))
            assert_that(op, is_(equal_to(operations[-1])))
            i = m + 1
    assert_that(i, is_(equal_to(m + 1)))
    assert_that(result, is_(equal_to(word2)))
Ejemplo n.º 16
0
def get_random_direct_address_table():
    table_size = random.randint(1, 10)
    nelements = random.randint(0, table_size)
    elements = [Element(key) for key in random.sample(range(table_size), nelements)]
    table = Array.indexed(0, table_size - 1)
    for element in elements:
        table[element.key] = element
    return table, elements
Ejemplo n.º 17
0
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)
Ejemplo n.º 18
0
def lis_length(X):
    n = X.length
    c = Array.indexed(1, n)
    b = Array.indexed(1, n)
    m = 0
    b_star = 0
    for i in between(1, n):
        c[i] = 1
        b[i] = 0
        for j in between(1, i - 1):
            if X[j] <= X[i] and c[j] + 1 > c[i]:
                c[i] = c[j] + 1
                b[i] = j
        if c[i] > m:
            m = c[i]
            b_star = i
    return m, b, b_star
Ejemplo n.º 19
0
def optimal_bst(p, q, n):
    e = Array([Array.indexed(0, n) for _ in between(1, n + 1)])
    w = Array([Array.indexed(0, n) for _ in between(1, n + 1)])
    root = Array([Array.indexed(1, n) for _ in between(1, n)])
    for i in between(1, n + 1):
        e[i, i - 1] = q[i - 1]
        w[i, i - 1] = q[i - 1]
    for l in between(1, n):
        for i in between(1, n - l + 1):
            j = i + l - 1
            e[i, j] = math.inf
            w[i, j] = w[i, j - 1] + p[j] + q[j]
            for r in between(i, j):
                t = e[i, r - 1] + e[r + 1, j] + w[i, j]
                if t < e[i, j]:
                    e[i, j] = t
                    root[i, j] = r
    return e, root
Ejemplo n.º 20
0
    def test_counting_sort(self):
        k = 20
        array, elements = get_random_array(max_value=k)
        actual_sorted_array = Array.indexed(1, array.length)

        counting_sort(array, actual_sorted_array, k)

        expected_array = Array(sorted(elements))
        assert_that(actual_sorted_array, is_(equal_to(expected_array)))
Ejemplo n.º 21
0
def lcs_length_(X, Y):
    m = X.length
    n = Y.length
    if m < n:
        return lcs_length_(Y, X)
    c = Array([Array.indexed(0, n), Array.indexed(0, n)], start=0)
    for j in between(0, n):
        c[0, j] = 0
    c[1, 0] = 0
    for i in between(1, m):
        for j in between(1, n):
            if X[i] == Y[j]:
                c[1, j] = c[0, j - 1] + 1
            else:
                c[1, j] = max(c[1, j - 1], c[0, j])
        for j in between(1, n):
            c[0, j] = c[1, j]
    return c[1, n]
Ejemplo n.º 22
0
    def test_recursive_matrix_chain(self):
        n = random.randint(1, 10)
        dimensions = Array([random.randint(1, 999) for _ in range(n + 1)], start=0)
        m = Array([Array.indexed(1, n) for _ in between(1, n)])

        actual_minimum_cost = recursive_matrix_chain(dimensions, m, 1, n)

        expected_minimum_cost = get_minimum_matrix_product_cost(dimensions, 1, n)
        assert_that(actual_minimum_cost, is_(equal_to(expected_minimum_cost)))
Ejemplo n.º 23
0
def jobs_scheduling(t, p, d):
    n = p.length
    a = Array(list(between(1, n)))
    _sort_jobs_by_deadlines(a, t, p, d)
    for i in between(1, n):
        d[i] = min(d[i], n ** 2)
    P = Array.indexed(0, d[n])
    s = Array([Array.indexed(0, d[n]) for _ in between(1, n)])
    for j in between(0, d[n]):
        P[j] = 0
    for i in between(1, n):
        for j in between(0, d[n]):
            s[i, j] = 0
    for i in between(1, n):
        for j in rbetween(d[n], t[i]):
            if P[min(j, d[i]) - t[i]] + p[i] > P[j]:
                P[j] = P[min(j, d[i]) - t[i]] + p[i]
                s[i, j] = 1
    return P, s, a
Ejemplo n.º 24
0
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
Ejemplo n.º 25
0
def random_hash_table(h, table_size, max_value):
    table = Array.indexed(0, table_size - 1)
    nelements = random.randint(0, table.length)
    keys = [random.randint(0, max_value) for _ in range(nelements)]
    for key in keys:
        i = 0
        while table[h(key, i, table_size)] is not None:
            i += 1
        table[h(key, i, table_size)] = key
    return table, keys
Ejemplo n.º 26
0
def bitonic_tsp(p):
    n = p.length
    _sort_by_x_coordinates(p)
    b = Array([Array.indexed(1, n) for _ in between(1, n)])
    r = Array([Array.indexed(1, n) for _ in between(1, n)])
    b[1, 1] = 0
    for j in between(2, n):
        for i in between(1, j):
            if i == 1 or i < j - 1:
                b[i, j] = b[i, j - 1] + _distance(p[j - 1], p[j])
                r[i, j] = j - 1
            else:
                b[i, j] = math.inf
                for k in between(1, i - 1):
                    q = b[k, i] + _distance(p[k], p[j])
                    if q < b[i, j]:
                        b[i, j] = q
                        r[i, j] = k
    return b, r
Ejemplo n.º 27
0
def _sort_by_length(A, n):
    numbers_by_length = Array.indexed(1, n)
    for number in A:
        if numbers_by_length[len(str(number))] is None:
            numbers_by_length[len(str(number))] = []
        numbers_by_length[len(str(number))].append(number)
    for i in between(1, n):
        if numbers_by_length[i] is not None:
            numbers_by_length[i] = Array(numbers_by_length[i])
    return numbers_by_length
Ejemplo n.º 28
0
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
Ejemplo n.º 29
0
def stack_dequeue(S):
    if stack_empty(S):
        raise RuntimeError('underflow')
    S_ = Array.indexed(1, S.length)
    S_.top = 0
    while not stack_empty(S):
        push(S_, pop(S))
    x = pop(S_)
    while not stack_empty(S_):
        push(S, pop(S_))
    return x
Ejemplo n.º 30
0
    def test_print_stations(self):
        n = random.randint(1, 10)
        l = Array([Array.indexed(1, n), Array.indexed(1, n)])
        l[1, 1], l[2, 1] = 0, 0
        for i in between(2, n):
            l[1, i], l[2, i] = random.choice([(1, 1), (1, 2), (2, 2)])
        l_star = random.randint(1, 2)
        captured_output = io.StringIO()

        with redirect_stdout(captured_output):
            print_stations(l, l_star, n)

        actual_output = captured_output.getvalue().splitlines()
        expected_output = []
        i = l_star
        expected_output.append('line ' + str(i) + ', station ' + str(n))
        for j in rbetween(n, 2):
            i = l[i, j]
            expected_output.append('line ' + str(i) + ', station ' + str(j - 1))
        assert_that(actual_output, is_(equal_to(expected_output)))
Ejemplo n.º 31
0
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
Ejemplo n.º 32
0
def edit_distance(x, y, cost):
    m = x.length
    n = y.length
    c = Array([Array.indexed(0, n) for _ in between(0, m)])
    op = Array([Array.indexed(0, n) for _ in between(0, m)])
    l = Array([Array.indexed(0, n) for _ in between(0, m)])
    r = Array([Array.indexed(0, n) for _ in between(0, m)])
    for i in between(0, m):
        c[i, 0] = i * cost['delete']
        (op[i, 0], l[i, 0], r[i, 0]) = ('delete', i - 1, 0)
    for j in between(1, n):
        c[0, j] = j * cost['insert']
        (op[0, j], l[0, j], r[0, j]) = ('insert ' + y[j], 0, j - 1)
    for i in between(1, m):
        for j in between(1, n):
            c[i, j] = math.inf
            if x[i] == y[j]:
                c[i, j] = c[i - 1, j - 1] + cost['copy']
                (op[i, j], l[i, j], r[i, j]) = ('copy', i - 1, j - 1)
            if x[i] != y[j] and c[i - 1, j - 1] + cost['replace'] < c[i, j]:
                c[i, j] = c[i - 1, j - 1] + cost['replace']
                (op[i, j], l[i, j], r[i, j]) = ('replace by ' + y[j], i - 1, j - 1)
            if c[i - 1, j] + cost['delete'] < c[i, j]:
                c[i, j] = c[i - 1, j] + cost['delete']
                (op[i, j], l[i, j], r[i, j]) = ('delete', i - 1, j)
            if c[i, j - 1] + cost['insert'] < c[i, j]:
                c[i, j] = c[i, j - 1] + cost['insert']
                (op[i, j], l[i, j], r[i, j]) = ('insert ' + y[j], i, j - 1)
            if i >= 2 and j >= 2 and x[i] == y[j - 1] and x[i - 1] == y[j] \
                    and c[i - 2, j - 2] + cost['twiddle'] < c[i, j]:
                c[i, j] = c[i - 2, j - 2] + cost['twiddle']
                (op[i, j], l[i, j], r[i, j]) = ('twiddle', i - 2, j - 2)
    for k in between(0, m - 1):
        if c[k, n] + cost['kill'] < c[m, n]:
            c[m, n] = c[k, n] + cost['kill']
            (op[m, n], l[m, n], r[m, n]) = ('kill', k, n)
    return c, op, l, r
Ejemplo n.º 33
0
def break_lines(l, M):
    n = l.length
    L = Array.indexed(0, n)
    L[0] = 0
    for i in between(1, n):
        L[i] = L[i - 1] + l[i]
    c = Array.indexed(0, n)
    p = Array.indexed(1, n)
    c[0] = 0
    for j in between(1, n):
        c[j] = math.inf
        j0 = max(1, j - math.ceil(M / 2) + 1)
        for i in between(j0, j):
            extras = M - j + i - (L[j] - L[i - 1])
            if extras < 0:
                lc = math.inf
            elif j == n:
                lc = 0
            else:
                lc = extras**3
            if c[i - 1] + lc < c[j]:
                c[j] = c[i - 1] + lc
                p[j] = i
    return c, p
Ejemplo n.º 34
0
def get_random_chained_direct_address_table():
    table_size = random.randint(1, 10)
    nelements = random.randint(0, table_size)
    elements = [
        ChainedElement(random.randint(0, table_size - 1))
        for _ in range(nelements)
    ]
    table = Array.indexed(0, table_size - 1)

    for element in elements:
        list_ = table[element.key]
        if list_:
            list_.prev = element
        element.next = list_
        table[element.key] = element
    return table, elements
Ejemplo n.º 35
0
def get_random_chained_hash_table(max_value=999):
    table_size = random.randint(1, 10)
    nelements = random.randint(0, 3 * table_size)
    elements = [
        ChainedElement(random.randint(0, max_value)) for _ in range(nelements)
    ]
    table = Array.indexed(0, table_size - 1)
    h = modular_hash

    for element in elements:
        list_ = table[h(element.key, table_size)]
        if list_:
            list_.prev = element
        element.next = list_
        table[h(element.key, table_size)] = element
    return table, elements, h
Ejemplo n.º 36
0
def counting_sort_in_place(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]
    C_ = Array(C.elements, start=0)
    i = 1
    while i <= A.length - 1:
        key = A[i]
        if C_[key - 1] < i <= C_[key]:
            i = i + 1
        else:
            A[i], A[C[key]] = A[C[key]], A[i]
            C[key] = C[key] - 1
Ejemplo n.º 37
0
def intersecting_chords(C):
    n = C.length // 2
    P = Array.indexed(1, n)
    for k in between(1, n):
        P[k] = 0
    intersections = 0
    T = RedBlackTree(sentinel=OSNode(None))
    for k in between(1, 2 * n):
        j = C[k]
        if P[j] == 0:
            P[j] = k
            os_insert(T, OSNode(k))
        else:
            x = os_search(T, P[j])
            intersections = intersections + T.root.size - os_rank(T, x)
            os_delete(T, x)
    return intersections
Ejemplo n.º 38
0
def tasks_scheduling_(d, w):
    n = d.length
    tasks = list(zip(['a' + str(i) for i in between(1, n)], d, w))
    tasks.sort(key=lambda t: t[2], reverse=True)
    schedule = Array.indexed(1, n)
    for task in tasks:
        i = task[1]
        while i >= 1 and schedule[i] is not None:
            i -= 1
        if i >= 1:
            schedule[i] = task[0]
        else:
            j = n
            while schedule[j] is not None:
                j -= 1
            schedule[j] = task[0]
    return schedule
Ejemplo n.º 39
0
def counting_in_range(A, k, a, b):
    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]
    if 0 < a <= b <= k:
        return C[b] - C[a - 1]
    if 0 < a <= k < b:
        return C[k] - C[a - 1]
    if a <= 0 <= b <= k:
        return C[b]
    if a <= 0 <= k < b:
        return C[k]
    if a > k or b < 0:
        return 0
Ejemplo n.º 40
0
def lcs_length__(X, Y):
    m = X.length
    n = Y.length
    if m < n:
        return lcs_length__(Y, X)
    C = Array.indexed(0, n)
    for j in between(0, n):
        C[j] = 0
    for i in between(1, m):
        p = C[0]
        for j in between(1, n):
            r = C[j]
            if X[i] == Y[j]:
                C[j] = p + 1
            else:
                C[j] = max(C[j], C[j - 1])
            p = r
    return C[n]
Ejemplo n.º 41
0
def _monge_minimums_indices(A):
    m = A.rows
    n = A.columns
    if m == 0:
        return Array([])
    A_ = Matrix([A[2 * j] for j in between(1, m // 2)])
    minimums_indices_even_rows = _monge_minimums_indices(A_)
    minimums_indices = Array.indexed(1, m)
    for j in between(1, m // 2):
        minimums_indices[2 * j] = minimums_indices_even_rows[j]
    for j in between(1, math.ceil(m / 2)):
        i = 2 * j - 1
        prev_minimum_index = minimums_indices[i - 1] if i > 1 else 1
        next_minimum_index = minimums_indices[i + 1] if i < m else n
        minimum = min([A[i, k] for k in between(prev_minimum_index, next_minimum_index)])
        for k in between(prev_minimum_index, next_minimum_index):
            if A[i, k] == minimum:
                minimums_indices[i] = k
                break
    return minimums_indices
Ejemplo n.º 42
0
def dynamic_binary_delete(A, x):
    i = 0
    while A[i].length == 0:
        i = i + 1
    y = A[i][2**i - 1]
    j = -1
    l = None
    while l is None:
        j = j + 1
        l = iterative_binary_search(A[j], x)
    A[j][l] = y
    while l > 1 and A[j][l] < A[j][l - 1]:
        A[j][l], A[j][l - 1] = A[j][l - 1], A[j][l]
    while l < A[j].length and A[j][l] > A[j][l + 1]:
        A[j][l], A[j][l + 1] = A[j][l + 1], A[j][l]
    for r in between(0, i - 1):
        A[r] = Array.indexed(1, 2**r)
        for t in between(1, 2**r):
            A[r][t] = A[i][2**r - 2 + t]
    A[i] = Array([])
Ejemplo n.º 43
0
def activity_scheduler(s, f):
    n = s.length
    A = Array.indexed(1, n)
    F = Array(list(rbetween(n, 1)))
    F.top = n
    B = RedBlackTree()
    # events contains triples (a, b, c) where a = 0 if the event is finish of an activity and 1 if it is start,
    # b as the activity number, and c as the start time or the finish time
    events = [(0, i + 1, finish_time) for i, finish_time in enumerate(f)] + \
             [(1, i + 1, start_time) for i, start_time in enumerate(s)]
    events.sort(key=lambda e: (e[2], e[0]))
    for e in events:
        if e[0] == 1:
            hall_number = pop(F)
            A[e[1]] = hall_number
            rb_insert(B, Node(e[1], data=hall_number), sentinel=B.nil)
        else:
            hall = rb_search(B.root, e[1], sentinel=B.nil)
            push(F, hall.data)
            rb_delete(B, hall, sentinel=B.nil)
    return A
Ejemplo n.º 44
0
def merge_sorted_lists(lists):
    k = lists.length
    Q = Array.indexed(1, k)
    Q.heap_size = 0
    for list_ in lists:
        if list_.head is not None:
            x = list_.head
            list_.head = list_.head.next
            x.next = None
            _min_heap_insert_pair(Q, (x, list_))
    merged_list = List()
    tail = None
    while Q.heap_size > 0:
        element, list_ = _heap_extract_min_pair(Q)
        if merged_list.head is None:
            tail = merged_list.head = element
        else:
            tail.next = element
            tail = tail.next
        if list_.head is not None:
            _min_heap_insert_pair(Q, (list_.head, list_))
            list_.head = list_.head.next
    return merged_list
Ejemplo n.º 45
0
def perfect_hashing_init(K):
    max_key = max(K)
    # from Bertrand's postulate, for each n >= 1, there is a prime p, such that n < p <= 2n
    p = random.choice(list(sieve.primerange(max_key + 1, 2 * max_key + 1)))
    m = K.length
    T = Array.indexed(0, m - 1)
    h = _get_random_universal_hash_function(p, m)
    mapped_keys = [[] for _ in range(m)]
    for k in K:
        mapped_keys[h(k)].append(k)
    secondary_sizes = [len(keys)**2 for keys in mapped_keys]
    for j, size in enumerate(secondary_sizes):
        if size == 1:
            T[j] = (lambda _: 0, Array([mapped_keys[j][0]], start=0))
        elif size > 1:
            h_ = None
            S = None
            while S is None:
                h_ = _get_random_universal_hash_function(p, size)
                S = _construct_secondary_hash_table_no_collisions(
                    mapped_keys[j], size, h_)
            T[j] = (h_, S)
    return T, h
Ejemplo n.º 46
0
    def test_in_place_chained_hash_table(self):
        table_size = random.randint(1, 20)
        keys, _ = get_random_unique_array(max_size=table_size, max_value=99)
        elements = [Element(key) for key in keys]
        table = Array.indexed(0, table_size - 1)
        table.free = 0
        for i in range(table_size):
            table[i] = FreePosition(i - 1, i + 1)
        table[table_size - 1].next = -1
        h = lambda k, m: k % m

        for element in elements:
            in_place_chained_hash_insert(table, element, h)

        for key in range(100):
            actual_element = in_place_chained_hash_search(table, key, h)

            if key in keys:
                assert_that(actual_element.key, is_(equal_to(key)))
                in_place_chained_hash_delete(table, actual_element, h)
            else:
                assert_that(actual_element, is_(none()))

        assert_in_place_hash_table_clear(table)
Ejemplo n.º 47
0
def persistent_rb_insert(T, z):
    path_length = _get_path_length_from_root_to_node(T, z)
    S = Array.indexed(1, path_length + 1)
    S.top = 0
    y = T.nil
    x = T.root
    T_ = RedBlackTree(sentinel=T.nil)
    y_ = T_.nil
    push(S, y_)
    while x is not T.nil:
        y = x
        x_ = rb.ParentlessNode.clone(x)
        if y_ is T_.nil:
            T_.root = x_
        else:
            if x is y_.left:
                y_.left = x_
            else:
                y_.right = x_
        y_ = x_
        push(S, y_)
        if z.key < x.key:
            x = x.left
        else:
            x = x.right
    if y is T.nil:
        T_.root = z
    else:
        if z.key < y.key:
            y_.left = z
        else:
            y_.right = z
    z.left = z.right = T.nil
    z.color = Red
    _persistent_rb_insert_fixup(T_, S, z)
    return T_
Ejemplo n.º 48
0
def persistent_rb_delete(T, z):
    T_ = RedBlackTree()
    T_.root = T_.nil = T.nil
    if z.left is T.nil or z.right is T.nil:
        y = z
    else:
        y = rb_successor(z, T.nil)
    path_length = _get_path_length_from_root_to_node(T, y)
    S = Array.indexed(1, path_length + 1)
    S.top = 0
    p = T.root
    r = T.nil
    p_ = r_ = T_.nil
    push(S, p_)
    z_ = T.nil
    while p is not y:
        p_ = rb.ParentlessNode.clone(p)
        push(S, p_)
        if p is z:
            z_ = p_
        if r_ is T_.nil:
            T_.root = p_
        else:
            if p is r_.left:
                r_.left = p_
            else:
                r_.right = p_
        r = p
        r_ = p_
        if y.key < p.key:
            p = p.left
        else:
            p = p.right
    if y.left is not T.nil:
        x = y.left
    else:
        x = y.right
    if y.color == Black:
        if x is not T.nil:
            x_ = rb.ParentlessNode.clone(x)
        else:
            x_ = T.nil
        if y is T.root:
            T_.root = x_
        else:
            if y is r.left:
                p_.left = x_
            else:
                p_.right = x_
        if y is not z:
            z_.key = y.key
            z_.data = y.data
        persistent_rb_delete_fixup(T_, S, x_)
    else:
        if y is r.left:
            p_.left = x
        else:
            p_.right = x
        if y is not z:
            z_.key = y.key
            z_.data = y.data
    return T_
Ejemplo n.º 49
0
 def test_create_empty_array_with_custom_indexes(self):
     array = Array.indexed(3, 7)
     assert_that(array.length, is_(equal_to(5)))
     assert_that(array.start, is_(equal_to(3)))
     assert_that(array[4], is_(none()))