File: blocklist.py

package info (click to toggle)
ion 3.2.1%2Bdfsg-1.1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 23,768 kB
  • ctags: 11,049
  • sloc: ansic: 141,798; sh: 22,848; makefile: 7,818; python: 1,638; sql: 311; perl: 197; awk: 178; xml: 50; java: 19
file content (115 lines) | stat: -rwxr-xr-x 3,656 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/python
# blocklist.py
# Turns a list of elements:                 [ 1 2 3 4 7 8 9 17 ]
# into a list of block tuples:              [ (1, 4) (7, 9) (17, 17) ]
#   or a list of block-length tuples:       [ (1, 4) (+3, 2) (+8, 1) ]
#
#	Author: Andrew Jenkins
#				University of Colorado at Boulder
#	Copyright (c) 2008-2011, Regents of the University of Colorado.
#	This work was supported by NASA contracts NNJ05HE10G, NNC06CB40C, and
#	NNC07CB47C.	

def listToBlocks(list):
    list = sorted(list)
    i = 0
    toReturn = [ ]
    while i < len(list):
        j = i
        while j+1 < len(list) and list[j+1] - list[i] == (j - i + 1):
            j += 1
        toReturn.append((list[i], list[j]))
        i = j + 1
    return toReturn

def blocksToLengthBlocks(blocks):
    toReturn = [ ]
    lastEnd = None
    for i in blocks:
        if (lastEnd == None):
            toReturn.append((i[0], i[1] - i[0] + 1))
        else:
            toReturn.append((i[0]-lastEnd, i[1]-i[0] + 1))
        lastEnd = i[1]
    return toReturn

def listToLengthBlocks(list):
    return blocksToLengthBlocks(listToBlocks(list))

def lengthBlocksToBlocks(lengthBlocks):
    toReturn = [ ]
    lastEnd = None
    for i in lengthBlocks:
        if (lastEnd == None):
            toReturn.append((i[0], i[0] + i[1] - 1))
            lastEnd = i[0] + i[1] - 1
        else:
            toReturn.append((lastEnd + i[0], lastEnd + i[0] + i[1] - 1))
            lastEnd = lastEnd + i[0] + i[1] - 1
    return toReturn

def blocksToList(blocks):
    toReturn = [ ]
    for i in blocks:
        toReturn.extend(range(i[0], i[1] + 1))
    return toReturn

def lengthBlocksToList(lengthBlocks):
    return blocksToList(lengthBlocksToBlocks(lengthBlocks))

def mergeBlocks(blocks):
    toReturn = [ ]
    for (curstart, curend) in sorted(blocks):
        try:
            (prevstart, prevend) = toReturn[-1]
            if prevend + 1 >= curstart:
                toReturn[-1] = (prevstart, curend)
            else:
                toReturn.append((curstart, curend))
        except IndexError:
            toReturn.append((curstart, curend))
    return toReturn

def mergeLengthBlocks(lengthBlocks):
    return blocksToLengthBlocks(mergeBlocks(lengthBlocksToBlocks(lengthBlocks)))

if __name__ == '__main__':
    testCase1 = [ [1,2,3,4,7,8,9,17],
                  [(1,4),(7,9),(17,17)],
                  [(1,4),(3,3),(8,1)] ]
    
    testCase2 = [ [1],
                  [ (1,1) ],
                  [ (1,1) ] ]
    
    testCase3 = [ range(1,75) + range(77,86),
                  [ (1,74), (77, 85) ],
                  [ (1,74), (3, 9) ] ]

    for i in [ testCase1, testCase2, testCase3 ]:
        assert listToBlocks(i[0]) == i[1]
        assert listToLengthBlocks(i[0]) == i[2]
        assert blocksToList(i[1]) == i[0]
        assert lengthBlocksToList(i[2]) == i[0]
        assert blocksToLengthBlocks(i[1]) == i[2]
        assert lengthBlocksToBlocks(i[2]) == i[1]

    mergeTestCase1 = [ [ (1, 10), (11, 20) ],
                       [ (1, 20) ],
                       [ (1, 20) ] ]

    mergeTestCase2 = [ [ (1, 15), (11, 20) ],
                       [ (1, 20) ],
                       [ (1, 20) ] ]

    mergeTestCase3 = [ [ (1, 9), (11, 20) ],
                       [ (1, 9), (11, 20) ],
                       [ (1, 9), (2, 10) ] ]

    mergeTestCase4 = [ [ (11, 20), (1, 5), (6, 10) ],
                       [ (1, 20) ],
                       [ (1, 20) ] ]

    for i in [ mergeTestCase1, mergeTestCase2, mergeTestCase3, mergeTestCase4 ]:
        assert mergeBlocks(i[0]) == i[1]
        assert mergeLengthBlocks(blocksToLengthBlocks(i[0])) == i[2]