Beispiel #1
0
    def test_treeset(self):
        ts = TreeSet([3,7,2,7,1,3])
        self.assertEqual(ts, [1, 2, 3, 7])

        ts.add(4)
        self.assertEqual(ts, [1, 2, 3, 4, 7])

        ts.add(4)
        self.assertEqual(ts, [1, 2, 3, 4, 7])

        ts.remove(7)
        self.assertEqual(ts, [1, 2, 3, 4])

        ts.remove(5)
        self.assertEqual(ts, [1, 2, 3, 4])

        ts.addAll([3,4,5,6])
        self.assertEqual(ts, [1, 2, 3, 4, 5, 6])

        ts.pop(3)
        self.assertEqual(ts, [1, 2, 3, 5, 6])

        self.assertEqual(ts[0], 1)

        self.assertEqual(ts[-1], 6)

        self.assertTrue(1 in ts)
        self.assertFalse(100 in ts)

        for i, element in enumerate(TreeSet([1,3,1])):
            if i==0:
                self.assertEqual(element, 1)
            elif i==1:
                self.assertEqual(element, 3)
            else:
                raise Exception

        ts_copy = ts.clone()
        self.assertEqual(ts, [1, 2, 3, 5, 6])

        self.assertEqual(ts.floor(4), 3)
        self.assertEqual(ts.ceiling(4), 5)
        self.assertEqual(ts.floor(3), 3)
        self.assertEqual(ts.ceiling(3), 3)

        ts.clear()
        self.assertEqual(ts._treeset, [])
Beispiel #2
0
    def test_treeset(self):
        ts = TreeSet([3, 7, 2, 7, 1, 3])
        self.assertEqual(ts, [1, 2, 3, 7])

        ts.add(4)
        self.assertEqual(ts, [1, 2, 3, 4, 7])

        ts.add(4)
        self.assertEqual(ts, [1, 2, 3, 4, 7])

        ts.remove(7)
        self.assertEqual(ts, [1, 2, 3, 4])

        ts.remove(5)
        self.assertEqual(ts, [1, 2, 3, 4])

        ts.addAll([3, 4, 5, 6])
        self.assertEqual(ts, [1, 2, 3, 4, 5, 6])

        ts.pop(3)
        self.assertEqual(ts, [1, 2, 3, 5, 6])

        self.assertEqual(ts[0], 1)

        self.assertEqual(ts[-1], 6)

        self.assertTrue(1 in ts)
        self.assertFalse(100 in ts)

        for i, element in enumerate(TreeSet([1, 3, 1])):
            if i == 0:
                self.assertEqual(element, 1)
            elif i == 1:
                self.assertEqual(element, 3)
            else:
                raise Exception

        ts_copy = ts.clone()
        self.assertEqual(ts, [1, 2, 3, 5, 6])

        self.assertEqual(ts.floor(4), 3)
        self.assertEqual(ts.ceiling(4), 5)
        self.assertEqual(ts.floor(3), 3)
        self.assertEqual(ts.ceiling(3), 3)

        ts.clear()
        self.assertEqual(ts._treeset, [])
Beispiel #3
0
class TreeMap(dict):
    """
    "TreeMap" is a dictionary with sorted keys similar to java TreeMap.
    Keys, iteration, items, values will all return values ordered by key.
    Otherwise it should behave just like the builtin dict.
    """
    def __init__(self, seq=None, **kwargs):
        if seq is None:
            super().__init__(**kwargs)
        else:
            super().__init__(seq, **kwargs)
        self.sorted_keys = TreeSet(super().keys())

    def __setitem__(self, key, value):
        super().__setitem__(key, value)
        self.sorted_keys.add(key)

    def __delitem__(self, key):
        super().__delitem__(key)
        self.sorted_keys.remove(key)

    def keys(self):
        return self.sorted_keys

    def items(self):
        return [(k, self[k]) for k in self.sorted_keys]

    def __iter__(self):
        for k in self.sorted_keys:
            yield k

    def values(self):
        for k in self.sorted_keys:
            yield self[k]

    def clear(self):
        super().clear()
        self.sorted_keys.clear()
Beispiel #4
0
    def test_remove(self):
        treesetA = TreeSet()
        for i in [5, 19, 21, 25]:
            treesetA.add(i)

        treesetA.remove(21)
        treesetB = TreeSet()
        for i in [5, 19, 25]:
            treesetB.add(i)
        self.assertEquals(treesetA, treesetB)

        treesetA.remove(5)
        treesetA.remove(25)
        treesetC = TreeSet()
        for i in [19]:
            treesetC.add(i)
        self.assertEquals(treesetA, treesetC)

        treesetA.remove(19)
        self.assertTrue(treesetA.isempty())
Beispiel #5
0
    def sweep_line_algorithm(self):
        self.current = Point()

        pointsPQ = PriorityQueue()
        tree = TreeSet()

        pointsPQ.pushAll([seg.p for seg in self.segments])
        pointsPQ.pushAll([seg.q for seg in self.segments])

        res = 0
        #print [str(x) for x in pointsPQ]

        while not pointsPQ.isEmpty():

            self.current.__update__(pointsPQ.pop())

            #print "Round", current

            if self.current.status == 'left':
                #print "Adding", self.current.segment
                low, high = tree.add_high_low(self.current.segment)

                low = tree.lower(self.current.segment)
                high = tree.higher(self.current.segment)
                #print "Actual:", self.current.segment
                #print "Low:", low, self.current.segment.intersect(low) if low else False
                #print "High:", high, self.current.segment.intersect(high) if high else False

                if low:
                    if self.current.segment.intersect(low):
                        a = self.current.segment.intersection_point(low)
                        #print "Adding a:", a, self.current.segment, low
                        pointsPQ.push(a)

                if high:
                    if self.current.segment.intersect(high):
                        a = self.current.segment.intersection_point(high)
                        #print "Adding 2:", a, self.current.segment, high
                        pointsPQ.push(a)

            elif self.current.status == "right":
                low = tree.lower(self.current.segment)
                high = tree.higher(self.current.segment)

                if low and high:
                    if low.intersect(high):
                        a = low.intersection_point(high)
                        #print "Adding 3:", a, low, high
                        pointsPQ.push(a)

                tree.remove(self.current.segment)
                #print "Removing", self.current.segment

            elif self.current.status == "int":
                # exchange the position in tree of the two segments intersecting in current
                s1, s2 = self.current.segment
                #print "Between, swapping:", str(s1), str(s2)

                tree.swap(s1, s2)

                #print "After swap:", s1, s2, s1 is tree.lower(s2), s2 is tree.lower(s1)
                #print "Modifying segments starts"
                old_s1 = s1.p.node
                old_s2 = s2.p.node

                s1.set_p_node(self.current.node)
                s2.set_p_node(self.current.node)

                #print "Tree after modification:", [str(x) for x in tree]

                # s1
                if s1 is tree.lower(s2):
                    #print "... s1, s2, ..."

                    low = tree.lower(s1)
                    #print "s1:", s1, "low:", low, s1.intersect(low) if low else False

                    if low is not None:
                        if s1.intersect(low):
                            pointsPQ.push(s1.intersection_point(low))

                    high = tree.higher(s2)
                    #print "s2:", s2, "high:", high, s2.intersect(high) if high else False

                    if high is not None:
                        if s2.intersect(high):
                            pointsPQ.push(s2.intersection_point(high))

                elif s2 is tree.lower(s1):
                    #print "... s2, s1, ..."

                    high = tree.higher(s1)
                    #print "s1:", s1, "high:", high, s1.intersect(high) if high else False

                    if high is not None:
                        if s1.intersect(high):
                            pointsPQ.push(s1.intersection_point(high))

                    low = tree.lower(s2)
                    #print "s2:", s2, "low:", low, s2.intersect(low) if low else False

                    if low is not None:
                        if s2.intersect(low):
                            pointsPQ.push(s2.intersection_point(low))

                else:
                    print "Error"  #raise SweepPlaneException("Intersection point error!")
                res += 1

                s1.set_p_node(old_s1)
                s2.set_p_node(old_s2)

            else:
                print "Error 2"  #raise SweepPlaneException("Node without status!")
            #print "Tree", [str(x) for x in tree]
            #print ""
        self.nodes = self.nodes[:self.original_n_nodes]
        return res
Beispiel #6
0
def player_split_get_teams_scores(A):
    #sort the array input 
    A.sort()  
    #initialize the variables
    partition1 = list()
    partition2 = list()
    i = 0
    j = len(A)-1
    part1Sum = 0
    part2Sum = 0
    diffSum = 0 
    unused = TreeSet([])
    
    for i in range (len(A)):
        unused.add(i)
        
    while len(unused) > 0:
        i = unused[0]
        j = unused[-1]
        diffSum = part1Sum-part2Sum

        #special case handling when the array is not multiple of 4 then 
        if len(unused) < 4:
            #remaining item placed smaller partition
            if len(unused) == 1:
                if diffSum > 0:
                    partition2.append(A[i])
                    part2Sum += A[i]
                else:
                    partition1.append(A[i])
                    part1Sum += A[i]
            #max in smaller and min in larger partition
            elif len(unused) == 2:
                maxx = max(A[i], A[j])
                minn = min(A[i], A[j])
                if diffSum > 0:
                    partition2.append(maxx)
                    partition1.append(minn)
                    part2Sum += maxx
                    part1Sum += minn

                else:
                    partition1.append(maxx)
                    partition2.append(minn)
                    part1Sum += maxx
                    part2Sum += minn

            #min, middle in smaller particion and max in larger particion 
            elif len(unused) == 3:
                unused.remove(i)
                unused.remove(j)
                middle = unused[0]
                if diffSum > 0:
                    if A[i]+A[middle] > A[j]:
                        partition2.append(A[i])
                        partition2.append(A[middle])
                        partition1.append(A[j])
                        part2Sum += A[i]+A[middle]
                        part1Sum += A[j]
                    else:
                        partition2.append(A[j])
                        partition1.append(A[i])
                        partition1.append(A[middle])
                        part1Sum += A[i]+A[middle]
                        part2Sum += A[j]
                else:
                    if A[i]+A[middle] > A[j]:
                        partition1.append(A[i])
                        partition1.append(A[middle])
                        partition2.append(A[j])
                        part1Sum += A[i]+A[middle]
                        part2Sum += A[j]
                    else:
                        partition1.append(A[j])
                        partition2.append(A[i])
                        partition2.append(A[middle])
                        part2Sum += A[i]+A[middle]
                        part1Sum += A[j]


            diffSum = part1Sum - part2Sum
            break

        #take the largest and the smallest element to create a pair
        pairSum = A[i]+A[j]
    
        if diffSum > 0:
            particion = 2
        else:
            particion = 1
        
        if particion == 1 :
            partition1.append(A[i])
            partition1.append(A[j])
            part1Sum += pairSum
        else:
            partition2.append(A[i])
            partition2.append(A[j])
            part2Sum += pairSum


        diffSum = part1Sum - part2Sum
        #used pair (i, j)
        unused.remove(i)
        unused.remove(j)
        #j last element
        j = unused[-1]

        buddyIndex = unused[0]
        minPairSumDiff = float('-inf')
        #find such buddy A[k], i<=k<j such that value of ((A[j]+A[k])-pairSum) is minimized
        for k in range(buddyIndex, j, 1):
            if k not in unused:
                continue

            compPairSum = A[j]+A[k]
            pairSumDiff = abs(pairSum-compPairSum)

            if pairSumDiff < minPairSumDiff:
                minPairSumDiff = pairSumDiff
                buddyIndex = k


        #add pair (j,buddyIndex) to the other partition
        if j != buddyIndex:
            pairSum = A[j]+A[buddyIndex]
            if particion == 2:
                partition1.append(A[j])
                partition1.append(A[buddyIndex])
                part1Sum += pairSum
            else:
                partition2.append(A[j])
                partition2.append(A[buddyIndex])
                part2Sum += pairSum
            
            #used pair (j, buddyIndex)
            unused.remove(j)
            unused.remove(buddyIndex)

    #optimize by swapping a larger elements in large partition with an small element in smaller partition
    if diffSum != 0:
        partition1.sort()
        partition2.sort()

        diffSum = part1Sum-part2Sum
    
        if diffSum > 0:
            largerPartition = partition1
            smallerPartition = partition2
        else:
            largerPartition = partition2
            smallerPartition = partition1
        
    
        prevDiff = abs(diffSum)
        largePartitonSwapCandidate = -1
        smallPartitonSwapCandidate = -1

        #swap largest element from large partition and smallest from the smaller partition so that sum difference is minimized
        for i in range(len(smallerPartition)):
            for j in range(len(largerPartition)-1, -1, -1):
                largerVal = largerPartition[j]
                smallerVal = smallerPartition[i]

                if largerVal <= smallerVal:
                    continue

                diff = abs(prevDiff - 2* abs(largerVal - smallerVal))
                if diff == 0:
                    largerPartition[j] =  smallerVal
                    smallerPartition[i] =  largerVal
                    return [largerPartition, smallerPartition]

                elif diff < prevDiff:
                    prevDiff = diff
                    largePartitonSwapCandidate = j
                    smallPartitonSwapCandidate = i



        #if found such a pair then swap it.
        if largePartitonSwapCandidate >=0 and smallPartitonSwapCandidate >=0:
            largerVal = largerPartition[largePartitonSwapCandidate]
            smallerVal = smallerPartition[smallPartitonSwapCandidate]
            largerPartition[largePartitonSwapCandidate] =  smallerVal
            smallerPartition[smallPartitonSwapCandidate] =  largerVal
            return [largerPartition, smallerPartition]

                   
    return [partition1, partition2]