Example #1
0
  def busiestServers(self, k: int, arrival: List[int], load: List[int]) -> List[int]:
      minheap = []
      s_list = SortedList()
      [s_list.add(i) for i in range(k)]
      count = {i:0 for i in range(k)}
 
      for i in range(len(arrival)):
          while minheap and minheap[0][0] <= arrival[i]:
              _, server = heapq.heappop(minheap)
              s_list.add(server)
      
          start_server = i % k 
          idx = s_list.bisect_left(start_server)
          if idx >= len(s_list):
              idx = s_list.bisect_left(0)
          if idx >= len(s_list):
              continue
          chosen_server = s_list[idx]
          count[chosen_server] += 1
          heapq.heappush(minheap, (arrival[i]+load[i],  chosen_server))
          s_list.discard(chosen_server)
      
      max_val = max(list(count.values()))
      ans = []
      for key, value in count.items():
          if value == max_val:
              ans.append(key)
      return ans
Example #2
0
    def busiestServers(self, k, arrival, load):
        """
        :type k: int
        :type arrival: List[int]
        :type load: List[int]
        :rtype: List[int]
        """
        num_used = [0] * k
        idle = SortedList([_ for _ in xrange(k)])
        hq = []
        for i, x in enumerate(arrival):
            while hq and x >= hq[0][0]:
                idle.add(hq[0][1])
                heappop(hq)
            if len(hq) == k: continue

            idx = idle.bisect_left(i % k)

            if idx == len(idle): target_i = idle[0]
            else: target_i = idle[idx]
            idle.discard(target_i)
            heappush(hq, [x + load[i], target_i])
            num_used[target_i] += 1
        maxi = max(num_used)
        return [i for i, x in enumerate(num_used) if x == maxi]
Example #3
0
def _test5():
    """
    网址:http://www.grantjenks.com/docs/sortedcontainers/sortedlist.html
    """
    from sortedcontainers import SortedList
    # 定义
    sl = SortedList(key=lambda x: -x)  # 降序
    sl = SortedList([3, 1, 2, 1, 5, 4])  # 升序
    print(sl)  # SortedList([1, 1, 2, 3, 4, 5])
    # 插入、删除元素
    sl.add(3)
    sl.add(3)
    sl.discard(2)  # SortedList([1, 1, 3, 3, 3, 4, 5])
    print(sl)
    # 统计某个元素出现的次数
    print(sl.count(3))  # 3
    # 返回第一个和最后一个元素
    print(sl[0])  # 1
    print(sl[-1])  # 5
    # 遍历 set
    for e in sl:
        print(e, end=", ")  # 1, 1, 3, 3, 3, 4, 5,
    print()
    # 判断某元素是否存在
    print(2 in sl)  # False
    # bisect_left() / bisect_right()
    print(sl.bisect_left(3))  # 返回大于等于3的最小元素对应的下标    2
    print(sl.bisect_right(3))  # 返回大于3的最小元素对应的下标    5
    # 清空
    sl.clear()
    print(len(sl))  # 0
    print(len(sl) == 0)  # True
Example #4
0
    def topological_sort(g, l):

        t = []
        i = 0

        for graph in g:
            t1 = []
            visited = [0 for j in range(l[i])]
            seq = graph.vs.select(lambda vertex: graph.indegree(vertex) == 0 and visited[vertex.index] == 0)
            indices = SortedList()
            for vs in seq:
                indices.add(vs.index)
            while len(indices) > 0:
                start = random.choice(indices)
                if visited[start] == 1:
                    indices.discard(start)
                    continue
                indices.discard(start)
                visited[start] = 1
                t1, visited = DFS(graph, visited, start, t1)
            t1.reverse()
            t.append(t1)
            del t1
            visited = []
            i += 1

        return t
    def minimumDifference(self, nums: List[int]) -> int:
        m = len(nums)
        n = m // 3

        left = SortedList(nums[:n])
        right = SortedList(nums[n:])
        sumLeft = sum(left)
        sumRight = sum(right[-n:])
        res = sumLeft - sumRight

        for i in range(n, 2 * n):
            index = right.bisect_left(nums[i])

            if index >= len(right) - n:
                sumRight -= nums[i]
                sumRight += right[-n - 1]

            index = left.bisect_left(nums[i])

            if index < n:
                sumLeft += nums[i]
                sumLeft -= left[n - 1]

            right.discard(nums[i])
            left.add(nums[i])

            res = min(res, sumLeft - sumRight)

        return res
Example #6
0
class OrderBook(object):
    def __init__(self):
        self.buy_orders = SortedList()
        self.sell_orders = SortedList()
        self.buy_mapping = {}
        self.sell_mapping = {}

    def add_order(self, order):
        if order.order_id in self.buy_mapping or order.order_id in self.sell_mapping:
            raise DuplicateOrderException
        if order.order_side == ORDER_BUY_SIDE:
            return self._try_buy(order)
        else:
            return self._try_sell(order)

    def cancel_order(self, order_id):
        if order_id in self.buy_mapping:
            order = self.buy_mapping[order_id]
            self.buy_orders.discard(order)
            del self.buy_mapping[order_id]
            return
        if order_id in self.sell_mapping:
            order = self.sell_mapping[order_id]
            self.sell_orders.discard(order)
            del self.sell_mapping[order_id]
            return
        raise UnknownOrderException

    def _try_buy(self, order):
        trades = []
        while self.sell_orders and order.price >= self.sell_orders[
                0].price and order.quantity > 0:
            resting_order = self.sell_orders[0]
            trades.append(self._trade(order, resting_order))
            if resting_order.quantity == 0:
                self.sell_orders.pop(0)
        if order.quantity > 0:
            self.buy_orders.add(order)
            self.buy_mapping[order.order_id] = order
        return trades

    def _trade(self, order, resting_order):
        quantity = min(resting_order.quantity, order.quantity)
        price = resting_order.price
        resting_order.quantity -= quantity
        order.quantity -= quantity
        return Trade(quantity, price, order, resting_order)

    def _try_sell(self, order):
        trades = []
        while self.buy_orders and order.price <= self.buy_orders[
                0].price and order.quantity > 0:
            resting_order = self.buy_orders[0]
            trades.append(self._trade(order, resting_order))
            if resting_order.quantity == 0:
                self.buy_orders.pop(0)
        if order.quantity > 0:
            self.sell_orders.add(order)
            self.sell_mapping[order.order_id] = order
        return trades
Example #7
0
    def assignTasks(self, servers, tasks):
        """
        :type servers: List[int]
        :type tasks: List[int]
        :rtype: List[int]
        """

        n, m = len(servers), len(tasks)
        serversSorted = SortedList([[servers[i], i, 0] for i in range(n)])

        res = []
        for i in range(m):
            tsk = tasks[i]
            found = 0
            minServerAvaiTime = float('inf')
            for j, server in enumerate(serversSorted):
                if server[2] < minServerAvaiTime:
                    minServerAvaiTime = server[2]
                    candidateServer = server[:]
                if server[2] <= i:
                    found = 1
                    res.append(server[1])
                    tmpserver = server[:]
                    tmpserver[2] = i + tsk
                    serversSorted.discard(server)
                    serversSorted.add(tmpserver)
                    break
            # 上一个错就是没考虑万一当前服务器都不可用怎么办——只能等到最近的那个candidate服务器可用了
            if not found:
                res.append(candidateServer[1])
                tmpserver = candidateServer[:]
                tmpserver[2] = i + tsk
                serversSorted.discard(candidateServer)
                serversSorted.add(tmpserver)
        return res
Example #8
0
 def reversePairs(self, arr: List[int]) -> int:
     brr = SortedList(arr)
     count = 0
     # anything smaller before larger is discarded.
     for i in range(len(arr)):  # O(nlogn), loop is n, logn inside
         brr.discard(arr[i])
         k = brr.bisect_left((arr[i] + 1) // 2)
         count += k
     return count
def fast_generator(rotors: list):
    from sortedcontainers import SortedList

    intersection_pairs = set()
    intersections_set = set()
    status_array = SortedList()
    event_points: list = []

    for rotor_center in rotors:
        affiliations: list = [
            SemiCircle(circle_center=rotor_center, side=side)
            for side in [SemiCircleSide.left, SemiCircleSide.right]
        ]
        heapq.heappush(
            event_points,
            EventPoint(coordinates=(rotor_center[0], rotor_center[1] + 1),
                       affiliations=affiliations,
                       event_type=EventPointType.upper))
        heapq.heappush(
            event_points,
            EventPoint(coordinates=(rotor_center[0], rotor_center[1] - 1),
                       affiliations=affiliations,
                       event_type=EventPointType.bottom))

    while event_points:
        next_event_point: EventPoint = heapq.heappop(event_points)
        shared.sweep_line_progress = next_event_point.coordinates[1]

        if next_event_point.event_type == EventPointType.upper:
            status_array.update(next_event_point.affiliations)

        if next_event_point.event_type == EventPointType.intersection:
            status_array.discard(next_event_point.affiliations[0])
            status_array.discard(next_event_point.affiliations[1])
            status_array.update(next_event_point.affiliations)

        left_semi_circle_position: int = status_array.index(
            min(next_event_point.affiliations))
        # assert max(next_event_point.affiliations) == status_array[left_semi_circle_position + (-1) ** (next_event_point.event_type == EventPointType.intersection)]

        if next_event_point.event_type == EventPointType.bottom:
            status_array.discard(next_event_point.affiliations[0])
            status_array.discard(next_event_point.affiliations[1])

        refine_intersections(
            intersection_pairs=intersection_pairs,
            intersections_set=intersections_set,
            status_array=status_array,
            event_points=event_points,
            left_semi_circle_position=left_semi_circle_position,
            deletion=next_event_point.event_type == EventPointType.bottom)

    for pair in intersection_pairs:
        yield pair
 def containsNearbyAlmostDuplicate(self, nums, k: int, t: int) -> bool:
     window = SortedList()
     for i in range(len(nums)):
         # 假设这个值是 x,就是 nums[i] - t <= x。我们又要求了 x <= nums[i] + t,所以:
         # nums[i] - t <= x <= nums[i] + t
         j = window.bisect_left(nums[i] - t)
         if j != len(window) and window[j] <= nums[i] + t:
             return True
         window.add(nums[i])
         if len(window) > k:
             window.discard(nums[i - k])
     return False
Example #11
0
class SortedQueue:
    def __init__(self, sz):
        self.size = sz
        self.__list = SortedList()
        self.__queue = collections.deque()
    def add(self, val):
        self.__list.add(val)
        self.__queue.append(val)
        if len(self.__queue) > self.size: self.__list.discard(self.__queue.popleft())
    def __len__(self): return len(self.__queue)
    def get_ratio(self, val):
        ind = min(len(self.__queue) - 1, max(0, int(len(self.__queue) * val)))
        return self.__list[ind]
Example #12
0
    def search(self, start, destination):
        """
        Find the most popular route from start node to destination node 
        through Maximum Probability Product algorithm which is similar to
        Dijkstra's shortest path algorithm.

        :param int start: the start node index
        :param int destination: the destination node index
        :return: the most popular route from the given s to d

        """
        # attribute L records the maximum ρ() value of the route from the
        # start node s to node ni
        for node in self.nodes:
            node.L = 0
        self.nodes[start].L = 1

        # create priority queue sorted by node's attribute L
        priority_queue = SortedList(key=lambda x: x.L)
        priority_queue.add(self.nodes[start])
        # save nodes that have been processed
        scanned_nodes = set()

        while priority_queue:
            # extract node u with maximum L value
            u = priority_queue.pop()
            u_index = self.nodes.index(u)

            # find destination node and return the most popular route
            if u_index == destination:
                return self.get_route(u_index)

            # check node u's adjecent node
            adjacent_node_indexes = [
                index for index in range(len(self.edges[u_index]))
                if self.edges[u_index][index] != -1
            ]
            for v_index in adjacent_node_indexes:
                v = self.nodes[v_index]
                new_L = u.L * self.popularity(v_index, destination)
                if v.L < new_L:
                    # modify node v's attribute L
                    priority_queue.discard(v)
                    v.L = new_L
                    v.parent_index = u_index
                    if v not in scanned_nodes:
                        priority_queue.add(v)
            scanned_nodes.add(u)
Example #13
0
class _WaitingTasksQueue(object):
    """A FIFO queue of tasks that keeps track of RAM limits.

    This class serves two purposes:
    1) It is a FIFO queue for tasks that also supports fast deletion.
    2) It keeps RAM requirements of all tasks in the queue in sorted order.

    This is necessary for the implementation of worker blocking,
    see ``PrioritingScheduler._getNumberOfBlockedAnyCpuWorkers()``
    for more details.
    """

    def __init__(self):
        self._dict = OrderedDict()
        self._tasks_required_ram = SortedList()

    def __contains__(self, task):
        return task in self._dict

    def __len__(self):
        return len(self._dict)

    def __nonzero__(self):
        return bool(self._dict)

    __bool__ = __nonzero__  # for Python 2/3 compatibility

    def add(self, task):
        self._dict[task] = True
        self._tasks_required_ram.add(task.required_ram_mb)

    def remove(self, task):
        del self._dict[task]
        self._tasks_required_ram.discard(task.required_ram_mb)

    def left(self):
        if self._dict:
            return six.next(six.iteritems(self._dict))[0]
        else:
            return None

    def popleft(self):
        task = self._dict.popitem(False)[0]
        self._tasks_required_ram.discard(task.required_ram_mb)
        return task

    def getTasksRequiredRam(self):
        return self._tasks_required_ram
Example #14
0
class _WaitingTasksQueue(object):
    """A FIFO queue of tasks that keeps track of RAM limits.

    This class serves two purposes:
    1) It is a FIFO queue for tasks that also supports fast deletion.
    2) It keeps RAM requirements of all tasks in the queue in sorted order.

    This is necessary for the implementation of worker blocking,
    see ``PrioritingScheduler._getNumberOfBlockedAnyCpuWorkers()``
    for more details.
    """
    def __init__(self):
        self._dict = OrderedDict()
        self._tasks_required_ram = SortedList()

    def __contains__(self, task):
        return task in self._dict

    def __len__(self):
        return len(self._dict)

    def __nonzero__(self):
        return bool(self._dict)

    __bool__ = __nonzero__  # for Python 2/3 compatibility

    def add(self, task):
        self._dict[task] = True
        self._tasks_required_ram.add(task.required_ram_mb)

    def remove(self, task):
        del self._dict[task]
        self._tasks_required_ram.discard(task.required_ram_mb)

    def left(self):
        if self._dict:
            return six.next(six.iteritems(self._dict))[0]
        else:
            return None

    def popleft(self):
        task = self._dict.popitem(False)[0]
        self._tasks_required_ram.discard(task.required_ram_mb)
        return task

    def getTasksRequiredRam(self):
        return self._tasks_required_ram
Example #15
0
    def medianSlidingWindow(self, nums: List[int], k: int) -> List[float]:
        win = SortedList(nums[:k])
        half = k // 2

        def median():
            if k % 2 == 0:
                med = (win[half] + win[half - 1]) / 2
            else:
                med = win[half]
            return med

        ans = [median()]
        for i in range(k, len(nums)):
            win.discard(nums[i - k])
            win.add(nums[i])
            ans.append(median())
        return ans
    def medianSlidingWindow(self, nums: List[int], k: int) -> List[float]:
        def getMedian(stream):
            midIndex = k // 2
            if k % 2 == 0:
                return (stream[midIndex] + stream[midIndex - 1]) / 2
            else:
                return stream[midIndex]

        stream, n = SortedList(nums[:k]), len(nums)
        result = [
            getMedian(stream),
        ]
        for i in range(k, n):
            stream.discard(nums[i - k])
            stream.add(nums[i])
            result.append(getMedian(stream))
        return result
Example #17
0
class MovieRentingSystem(object):
    def __init__(self, n, entries):
        """
        :type n: int
        :type entries: List[List[int]]
        """
        self.movies = defaultdict(SortedList)
        self.shops = defaultdict(dict)
        self.renting = SortedList([])
        for shop, movie, price in entries:
            self.movies[movie].add((price, shop))
            self.shops[shop][movie] = price

    def search(self, movie):
        """
        :type movie: int
        :rtype: List[int]
        """
        return [i[1] for i in list(self.movies[movie].islice(stop=5))]

    def rent(self, shop, movie):
        """
        :type shop: int
        :type movie: int
        :rtype: None
        """
        price = self.shops[shop][movie]
        self.movies[movie].discard((price, shop))
        self.renting.add((price, shop, movie))

    def drop(self, shop, movie):
        """
        :type shop: int
        :type movie: int
        :rtype: None
        """
        price = self.shops[shop][movie]
        self.movies[movie].add((price, shop))
        self.renting.discard((price, shop, movie))

    def report(self):
        """
        :rtype: List[List[int]]
        """
        return [[x, y] for _, x, y in self.renting.islice(stop=5)]
Example #18
0
    def DFS(graph, visited, current_vertex, t1):

        visited[current_vertex] = 1
        seq = graph.vs.select(lambda vertex: graph.are_connected(current_vertex, vertex.index) and visited[vertex.index] == 0)
        indices = SortedList()
        for vs in seq:
            indices.add(vs.index)
        while len(indices) > 0:
            next = random.choice(indices)
            if visited[next] == 1:
                indices.discard(next)
                continue
            indices.discard(next)
            t1, visited = DFS(graph, visited, next, t1)

        t1.append(current_vertex)

        return t1, visited
Example #19
0
def astar(grid, start, end, dims):
    cost = []
    vis = []
    parents = []
    for i in range(dims[0]):
        tmp = []
        for j in range(dims[1]):
            tmp.append((i,j))
        parents.append(tmp)
        vis.append([0]*dims[1])
        cost.append([100000*100]*dims[1])

    cost[start[0]][start[1]] = 0
    costlist = SortedList()
    costlist.add((cost[start[0]][start[1]], start))
    while(True):
        node = costlist[0][1]
        cst = costlist[0][0]
        costlist.discard(costlist[0])
        if vis[node[0]][node[1]]==1:
            continue
        vis[node[0]][node[1]] = 1
        adj = getValid(node, dims)
        flag = 0
        for coord in adj:
            if vis[coord[0]][coord[1]]==1:
                continue
            g = cost[node[0]][node[1]] + grid[coord[0]][coord[1]].cost
            h = heuristic(coord[0], coord[1], end)
            if g<=cost[coord[0]][coord[1]]:
                parents[coord[0]][coord[1]] = node
                costlist.add((g+h,coord))
                cost[coord[0]][coord[1]] = g
            
            if coord==end:
                flag = 1
                break
            
        if flag==1:
            break
    
    # print(cost)
    # print("\n\n")
    return (cost[end[0]][end[1]],getPath(start, end, parents))
Example #20
0
 def containsNearbyAlmostDuplicate(self, nums, k, t):
     if not nums:
         return False
     sl = SortedList()
     for i, n in enumerate(nums):
         fl_it = sl.irange(maximum=n, reverse=True)
         ceil_it = sl.irange(minimum=n, reverse=False)
         try:
             floor = next(fl_it)
         except StopIteration:
             floor = sys.maxsize
         try:
             ceil = next(ceil_it)
         except StopIteration:
             ceil = sys.maxsize
         if abs(ceil - n) <= t or abs(n - floor) <= t:
             return True
         sl.add(n)
         if len(sl) > k:
             sl.discard(nums[i - k])
     return False
    def medianSlidingWindow(self, nums: List[int], k: int) -> List[float]:
        """
        TODO: 数据结构:排序列表
        """
        from sortedcontainers import SortedList

        if len(nums) == 0:
            return []

        ar = SortedList(nums[:k])
        is_odd = k % 2 == 0
        medians = [
            (ar[k // 2 - 1] + ar[k // 2]) / 2.0 if is_odd else ar[k // 2]
        ]

        for i in range(len(nums) - k):
            ar.discard(nums[i])
            ar.add(nums[i + k])
            medians.append((ar[k // 2 - 1] + ar[k // 2]) /
                           2.0 if is_odd else ar[k // 2])
        return medians
Example #22
0
class StockPrice:
    def __init__(self):
        self.price = SortedList()
        self.timePriceMap = {}
        self.maxTimestamp = 0

    def update(self, timestamp: int, price: int) -> None:
        if timestamp in self.timePriceMap:
            self.price.discard(self.timePriceMap[timestamp])
        self.price.add(price)
        self.timePriceMap[timestamp] = price
        self.maxTimestamp = max(self.maxTimestamp, timestamp)

    def current(self) -> int:
        return self.timePriceMap[self.maxTimestamp]

    def maximum(self) -> int:
        return self.price[-1]

    def minimum(self) -> int:
        return self.price[0]
def test_remove():
    slt = SortedList()

    assert slt.discard(0) == None
    assert len(slt) == 0
    slt._check()

    slt = SortedList([1, 2, 2, 2, 3, 3, 5], load=4)

    slt.remove(2)
    slt._check()

    assert all(tup[0] == tup[1] for tup in zip(slt, [1, 2, 2, 3, 3, 5]))
Example #24
0
def test_remove():
    slt = SortedList()

    assert slt.discard(0) == None
    assert len(slt) == 0
    slt._check()

    slt = SortedList([1, 2, 2, 2, 3, 3, 5], load=4)

    slt.remove(2)
    slt._check()

    assert all(tup[0] == tup[1] for tup in zip(slt, [1, 2, 2, 3, 3, 5]))
class MRV:
    def __init__(self, obj):
        self.Ordering = SortedList()
        self.Help = dict()
        for i in range(1, obj.variables + 1):
            self.Ordering.add((len(obj.domains[i]), i))
            self.Help[i] = len(obj.domains[i])

    def finished(self):
        return len(self.Ordering) == 0

    def size(self):
        return len(self.Ordering)

    def minimum(self):
        return self.Ordering[0]

    def remove(self, element):
        self.Ordering.discard(element)

    def add(self, element):
        if element not in self.Ordering:
            self.Ordering.add(element)

    def decrease(self, rem):
        # rem = [length, variable]
        self.remove(rem)
        self.Help[rem[1]] -= 1
        self.add((rem[0] - 1, rem[1]))

    def increase(self, rem):
        self.remove(rem)
        self.Help[rem[1]] += 1
        self.add((rem[0] + 1, rem[1]))

    def correct(self, rem, newLen):
        self.remove((self.Help[rem], rem))
        self.Help[rem] = newLen
        self.add((self.Help[rem], rem))
Example #26
0
    def assignTasks(self, servers, tasks):
        """
        :type servers: List[int]
        :type tasks: List[int]
        :rtype: List[int]
        """

        n, m = len(servers), len(tasks)
        serversSorted = SortedList([[servers[i], i, 0] for i in range(n)])

        res = []
        for i in range(m):
            tsk = tasks[i]
            for j, server in enumerate(serversSorted):
                if server[2] <= i:
                    res.append(server[1])
                    tmpserver = server[:]
                    tmpserver[2] = i + tsk
                    serversSorted.discard(server)
                    serversSorted.add(tmpserver)
                    break
        return res
Example #27
0
class StockPrice:
    def __init__(self):
        self.times = {}
        self.prices = SortedList()
        self.max_time = 0

    def update(self, timestamp: int, price: int) -> None:
        self.max_time = max(self.max_time, timestamp)
        if timestamp in self.times:
            self.prices.discard(self.times[timestamp])

        self.times[timestamp] = price
        self.prices.add(price)

    def current(self) -> int:
        return self.times[self.max_time]

    def maximum(self) -> int:
        return self.prices[-1]

    def minimum(self) -> int:
        return self.prices[0]
    def test_SortedList(self):
        # construct
        sorted_list = SortedList([1, 2, 3, 4])
        sorted_list = SortedList()

        # add
        for i in range(5, 0, -1):
            sorted_list.add(i)

        # adding elements using the update() function
        elements = [10, 9, 8, 7, 6]
        sorted_list.update(elements)

        # prints the updated list in sorted order
        print('list after updating: ', sorted_list)

        # removing a particular element using value
        sorted_list.discard(8)
        # removing all elements
        sorted_list.clear()
        print('list after removing all elements using clear: ', sorted_list)

        return
Example #29
0
class StockPrice(object):
    def __init__(self):
        from sortedcontainers import SortedList
        self.price = SortedList()
        self.timePriceMap = {}
        self.maxTimestamp = 0

    def update(self, timestamp, price):
        """
        :type timestamp: int
        :type price: int
        :rtype: None
        """
        if timestamp in self.timePriceMap:
            self.price.discard(self.timePriceMap[timestamp])
        self.price.add(price)
        self.timePriceMap[timestamp] = price
        self.maxTimestamp = max(self.maxTimestamp, timestamp)

    def current(self):
        """
        :rtype: int
        """
        return self.timePriceMap[self.maxTimestamp]

    def maximum(self):
        """
        :rtype: int
        """
        return self.price[-1]

    def minimum(self):
        """
        :rtype: int
        """
        return self.price[0]
Example #30
0
def test_discard():
    slt = SortedList()

    assert slt.discard(0) == None
    assert len(slt) == 0
    slt._check()

    slt = SortedList([1, 2, 2, 2, 3, 3, 5])
    slt._reset(4)

    slt.discard(6)
    slt._check()
    slt.discard(4)
    slt._check()
    slt.discard(2)
    slt._check()

    assert all(tup[0] == tup[1] for tup in zip(slt, [1, 2, 2, 3, 3, 5]))
def test_discard():
    slt = SortedList()

    assert slt.discard(0) == None
    assert len(slt) == 0
    slt._check()

    slt = SortedList([1, 2, 2, 2, 3, 3, 5])
    slt._reset(4)

    slt.discard(6)
    slt._check()
    slt.discard(4)
    slt._check()
    slt.discard(2)
    slt._check()

    assert all(tup[0] == tup[1] for tup in zip(slt, [1, 2, 2, 3, 3, 5]))
Example #32
0
class _DHTNode(object):
    def __init__(self, n=8, ff=0.80, direction=LEFT_TO_RIGHT, parent=None):
        """
        Defines an instance of a new Dynamic Hash Table.
        :param n: The max number of entries per bucket.
        :param ff: The fill factor for each bucket.
        :param direction: The direction to consume the key from.
        :param parent: A reference to the parent node.
        """
        if n < 3:
            n = 3
        self.n = n
        if ff < 0.25:
            ff = 0.25
        self.ff = ff
        if not (direction == LEFT_TO_RIGHT or direction == RIGHT_TO_LEFT):
            direction = LEFT_TO_RIGHT
        self.n = n
        self.ff = ff
        self.direction = direction
        self.parent = parent
        self.left = SortedList(key=extract_key)
        self.right = SortedList(key=extract_key)

    def add(self, key, value, bkey):
        """
        Adds a key-value pair to the DHT.
        :param key: The key to add.
        :param value: The corresponding value.
        :param bkey: A binary representation of the key.
        """
        bit, ck = consume_bkey(bkey, self.direction)
        if bit == LEFT_BIT:
            if isinstance(self.left, SortedList):
                self.left.add(_IndexEntry(key, value, ck))
                if len(self.left) > self.n * self.ff:
                    self._overflow(LEFT_BIT)
            elif isinstance(self.left, _DHTNode):
                self.left.add(key, value, ck)
            else:
                raise Exception()
        elif bit == RIGHT_BIT:
            if isinstance(self.right, SortedList):
                self.right.add(_IndexEntry(key, value, ck))
                if len(self.right) > self.n * self.ff:
                    self._overflow(RIGHT_BIT)
            elif isinstance(self.right, _DHTNode):
                self.right.add(key, value, ck)
            else:
                raise Exception()
        else:
            raise Exception()

    def contains(self, key, bkey):
        """
        Determines if the DHT contains at lest one key-value entry with the given key.
        :param key: The key to lookup.
        :param bkey: The binary representation of the key.
        :return: True if at least one key-value entry is found corresponding to the given key, False otherwise.
        """
        bit, ck = consume_bkey(bkey, self.direction)
        if bit == LEFT_BIT:
            if isinstance(self.left, SortedList):
                for entry in self.left:
                    if key == entry.key:
                        return True
                return False
            elif isinstance(self.left, _DHTNode):
                return self.left.contains(key, ck)
            else:
                raise Exception()
        elif bit == RIGHT_BIT:
            if isinstance(self.right, SortedList):
                for entry in self.right:
                    if key == entry.key:
                        return True
                return False
            elif isinstance(self.right, _DHTNode):
                return self.right.contains(key, ck)
            else:
                raise Exception()
        else:
            raise Exception()

    def delete(self, key, bkey):
        """
        Deletes the first matching key-value entry from the DHT.
        :param key: The key to lookup.
        :param bkey: The binary representation of the key.
        """
        bit, ck = consume_bkey(bkey, self.direction)
        if bit == LEFT_BIT:
            if isinstance(self.left, SortedList):
                discard = None
                for entry in self.left:
                    if key == entry.key:
                        discard = entry
                        break
                if discard:
                    self.left.discard(discard)
            elif isinstance(self.left, _DHTNode):
                self.left.delete(key, ck)
            else:
                raise Exception()
        elif bit == RIGHT_BIT:
            if isinstance(self.right, SortedList):
                discard = None
                for entry in self.right:
                    if key == entry.key:
                        discard = entry
                        break
                if discard:
                    self.right.discard(discard)
            elif isinstance(self.right, _DHTNode):
                self.right.delete(key, ck)
            else:
                raise Exception()
        else:
            raise Exception()
        if (isinstance(self.left, SortedList) and not self.left
                and isinstance(self.right, SortedList) and not self.right):
            self._underflow()

    def get(self, key, bkey):
        """
        Gets the first matching key-value entry from the key
        :param key: The key to lookup.
        :param bkey: The binary representation of the key.
        :return: True if at least one key-value entry is found corresponding to the given key, False otherwise.
        """
        bit, ck = consume_bkey(bkey, self.direction)
        if bit == LEFT_BIT:
            if isinstance(self.left, SortedList):
                for entry in self.left:
                    if key == entry.key:
                        return entry.value
                return None
            elif isinstance(self.left, _DHTNode):
                return self.left.get(key, ck)
            else:
                raise Exception()
        elif bit == RIGHT_BIT:
            if isinstance(self.right, SortedList):
                for entry in self.right:
                    if key == entry.key:
                        return entry.value
                return None
            elif isinstance(self.right, _DHTNode):
                return self.right.get(key, ck)
            else:
                raise Exception()
        else:
            raise Exception()

    def height(self):
        """
        Gets the height of the DHT.
        :return: The height of the DHT.
        """
        if isinstance(self.left, SortedList) and isinstance(
                self.right, SortedList):
            return 1
        left = 0
        right = 0
        if isinstance(self.left, _DHTNode):
            left = self.left.height() + 1
        if isinstance(self.right, _DHTNode):
            right = self.right.height() + 1
        return max(left, right)

    def traverse(self):
        """
        Traverses the DHT yielding key-value pairs as a Python generator.
        :return: A Python generator over the key-value pairs in the DHT.
        """
        if isinstance(self.left, SortedList):
            for entry in self.left:
                yield entry.key, entry.value
        elif isinstance(self.left, _DHTNode):
            yield from self.left.traverse()
        else:
            raise Exception()
        if isinstance(self.right, SortedList):
            for entry in self.right:
                yield entry.key, entry.value
        elif isinstance(self.right, _DHTNode):
            yield from self.right.traverse()
        else:
            raise Exception()

    def _overflow(self, bit):
        """
        Redistributes the indicated buckets keys to a new left and right bucket. An overflow happens when a bucket
        grows to large, i.e. its total length is greater than its maximum number of entries times its fill factor.
        :param bit: The bit representing the buck that overflowed. One of {LEFT_BIT, RIGHT_BIT}.
        """
        if bit == LEFT_BIT and isinstance(self.left, SortedList):
            new_left = _DHTNode(n=self.n,
                                ff=self.ff,
                                direction=self.direction,
                                parent=self)
            for entry in self.left:
                new_left.add(entry.key, entry.value, entry.bkey)
            self.left.clear()
            self.left = new_left
        elif bit == RIGHT_BIT and isinstance(self.right, SortedList):
            new_right = _DHTNode(n=self.n,
                                 ff=self.ff,
                                 direction=self.direction,
                                 parent=self)
            for entry in self.right:
                new_right.add(entry.key, entry.value, entry.bkey)
            self.right.clear()
            self.right = new_right
        else:
            raise Exception()

    def _underflow(self):
        """
        Coalesces the two buckets pointed to by this this into a single bucket. An underflow occurs when a deletion
        causes a state where by both buckets pointed to by this node are empty. This rule is ignored for the root node.
        """
        # only underflow if we are not the root node, root node cannot underflow
        if self.parent:
            if self.parent.left == self:
                self.parent.left = SortedList(key=extract_key)
            elif self.parent.right == self:
                self.parent.right = SortedList(key=extract_key)
            else:
                raise Exception()
Example #33
0
         clist.append(ivalue)
         cend=ipos
         #cPass = cPass and (windowHigh-windowLow >= variCutoff)
       else:
         evaluateValues(chrom,cstart,cend,clist,cPass)
         clist = [ivalue]
         cstart = ipos
         cend = ipos
         cPass = not options.debug #and (windowHigh-windowLow >= variCutoff)
     # Increase position in window towards center
     posInWindow += 1
   # Overstepped by 1, reset to center
   posInWindow -= 1
   
 # We are centered
 windowValuesSorted.discard(windowValues.pop(0))
 windowValues.append(value)
 windowValuesSorted.add(value)
 #windowLow,windowMedian,windowHigh = quantileS(windowValuesSorted,[0.25,0.5,0.75])
 windowMedian = medianS(windowValuesSorted)
 # Evaluate adjusted value
 if options.smoother:
   helper = windowValues[max(0,posInWindow-SGF_half_window):posInWindow+SGF_half_window+1]
   ivalue = smoother(helper)-windowMedian
 else:
   ivalue = windowValues[posInWindow]-windowMedian
 ipos = pos-windowSize+posInWindow+1
 if options.debug:
   sys.stdout.write("%s\t%d\t%.1f\t%.1f\t(%d)\n"%(chrom,ipos,ivalue,windowValues[posInWindow],posInWindow))
 #print chrom,ipos,ivalue
 if ivalue > 0:
Example #34
0
    ans=[1 for i in range(len(rains))]
    for day,lake in enumerate(rains):
        if lake==0:
            s.add(day)
        else:
            if checkrain.get(lake,-1)==(-1):
                ans[day]=-1
                checkrain[lake]=day
            else:
                x=bisect.bisect_right(s,checkrain[lake])
                if x==len(s):
                    print([])
                else:
                    ans[s[x]]=lake
                    ans[day]=-1
                    s.discard(s[x])
                # if s and checkrain[lake]<s[0]<day:
                #     ans[s[0]]=lake
                #     ans[day]=-1
                #     s.discard(s[0])
                # else:
                #     print([])
                #     break

        
    print(ans)