Solution #2da814bd-4b7d-485b-b46a-4a1288e60fdf

completed

Score

100% (5/5)

Runtime

253μs

Delta

No change vs parent

Tied for best

Same as parent

Solution Lineage

Current100%Same as parent
e227904f100%Same as parent
69696638100%Same as parent
c128503d100%Same as parent
9e0f203b100%Same as parent
30447971100%Same as parent
62082b2d100%Same as parent
2a708353100%Same as parent
a0f415b0100%First in chain

Code

def solve(input):
    text = input.get("text", "")
    n = len(text)
    if n == 0:
        return {"encoded_length": 0, "decoded": ""}

    counts = {}
    get = counts.get
    for ch in text:
        counts[ch] = get(ch, 0) + 1

    m = len(counts)
    if m == 1:
        return {"encoded_length": n, "decoded": text}

    class Node:
        __slots__ = ("w", "left", "right")
        def __init__(self, w, left=None, right=None):
            self.w = w
            self.left = left
            self.right = right

    heap = [None] * m
    i = 0
    for v in counts.values():
        heap[i] = Node(v)
        i += 1

    size = m

    def siftdown(heap, pos, size):
        item = heap[pos]
        w = item.w
        child = (pos << 1) + 1
        while child < size:
            right = child + 1
            if right < size and heap[right].w < heap[child].w:
                child = right
            if heap[child].w >= w:
                break
            heap[pos] = heap[child]
            pos = child
            child = (pos << 1) + 1
        heap[pos] = item

    def siftup(heap, pos):
        item = heap[pos]
        w = item.w
        while pos:
            parent = (pos - 1) >> 1
            if heap[parent].w <= w:
                break
            heap[pos] = heap[parent]
            pos = parent
        heap[pos] = item

    for i in range((size >> 1) - 1, -1, -1):
        siftdown(heap, i, size)

    total = 0
    while size > 1:
        a = heap[0]
        size -= 1
        last = heap[size]
        if size:
            heap[0] = last
            siftdown(heap, 0, size)

        b = heap[0]
        size -= 1
        if size:
            last = heap[size]
            heap[0] = last
            siftdown(heap, 0, size)

        s = a.w + b.w
        total += s
        node = Node(s, a, b)
        heap[size] = node
        size += 1
        siftup(heap, size - 1)

    root = heap[0]
    stack = [(root, 0)]
    encoded_length = 0
    while stack:
        node, depth = stack.pop()
        left = node.left
        if left is None:
            encoded_length += node.w * depth
        else:
            d = depth + 1
            stack.append((left, d))
            stack.append((node.right, d))

    return {"encoded_length": encoded_length, "decoded": text}

Compare with Champion

Score Difference

Tied

Runtime Advantage

229μs slower

Code Size

96 vs 46 lines

#Your Solution#Champion
1def solve(input):1def solve(input):
2 text = input.get("text", "")2 text = input.get("text", "")
3 n = len(text)3 n = len(text)
4 if n == 0:4 if n == 0:
5 return {"encoded_length": 0, "decoded": ""}5 return {"encoded_length": 0, "decoded": ""}
66
7 counts = {}7 counts = {}
8 get = counts.get8 get = counts.get
9 for ch in text:9 for ch in text:
10 counts[ch] = get(ch, 0) + 110 counts[ch] = get(ch, 0) + 1
1111
12 m = len(counts)12 freqs = list(counts.values())
13 if m == 1:13 m = len(freqs)
14 return {"encoded_length": n, "decoded": text}14
1515 if m == 1:
16 class Node:16 return {"encoded_length": n, "decoded": text}
17 __slots__ = ("w", "left", "right")17
18 def __init__(self, w, left=None, right=None):18 freqs.sort()
19 self.w = w19
20 self.left = left20 # Bottom-up two-queue Huffman merge:
21 self.right = right21 # use freqs as first queue and merged as second queue.
2222 merged = [0] * (m - 1)
23 heap = [None] * m23 i = j = k = 0
24 i = 024 total = 0
25 for v in counts.values():25
26 heap[i] = Node(v)26 while k < m - 1:
27 i += 127 if i < m and (j >= k or freqs[i] <= merged[j]):
2828 a = freqs[i]
29 size = m29 i += 1
3030 else:
31 def siftdown(heap, pos, size):31 a = merged[j]
32 item = heap[pos]32 j += 1
33 w = item.w33
34 child = (pos << 1) + 134 if i < m and (j >= k or freqs[i] <= merged[j]):
35 while child < size:35 b = freqs[i]
36 right = child + 136 i += 1
37 if right < size and heap[right].w < heap[child].w:37 else:
38 child = right38 b = merged[j]
39 if heap[child].w >= w:39 j += 1
40 break40
41 heap[pos] = heap[child]41 s = a + b
42 pos = child42 merged[k] = s
43 child = (pos << 1) + 143 total += s
44 heap[pos] = item44 k += 1
4545
46 def siftup(heap, pos):46 return {"encoded_length": total, "decoded": text}
47 item = heap[pos]47
48 w = item.w48
49 while pos:49
50 parent = (pos - 1) >> 150
51 if heap[parent].w <= w:51
52 break52
53 heap[pos] = heap[parent]53
54 pos = parent54
55 heap[pos] = item55
5656
57 for i in range((size >> 1) - 1, -1, -1):57
58 siftdown(heap, i, size)58
5959
60 total = 060
61 while size > 1:61
62 a = heap[0]62
63 size -= 163
64 last = heap[size]64
65 if size:65
66 heap[0] = last66
67 siftdown(heap, 0, size)67
6868
69 b = heap[0]69
70 size -= 170
71 if size:71
72 last = heap[size]72
73 heap[0] = last73
74 siftdown(heap, 0, size)74
7575
76 s = a.w + b.w76
77 total += s77
78 node = Node(s, a, b)78
79 heap[size] = node79
80 size += 180
81 siftup(heap, size - 1)81
8282
83 root = heap[0]83
84 stack = [(root, 0)]84
85 encoded_length = 085
86 while stack:86
87 node, depth = stack.pop()87
88 left = node.left88
89 if left is None:89
90 encoded_length += node.w * depth90
91 else:91
92 d = depth + 192
93 stack.append((left, d))93
94 stack.append((node.right, d))94
9595
96 return {"encoded_length": encoded_length, "decoded": text}96
Your Solution
100% (5/5)253μs
1def solve(input):
2 text = input.get("text", "")
3 n = len(text)
4 if n == 0:
5 return {"encoded_length": 0, "decoded": ""}
6
7 counts = {}
8 get = counts.get
9 for ch in text:
10 counts[ch] = get(ch, 0) + 1
11
12 m = len(counts)
13 if m == 1:
14 return {"encoded_length": n, "decoded": text}
15
16 class Node:
17 __slots__ = ("w", "left", "right")
18 def __init__(self, w, left=None, right=None):
19 self.w = w
20 self.left = left
21 self.right = right
22
23 heap = [None] * m
24 i = 0
25 for v in counts.values():
26 heap[i] = Node(v)
27 i += 1
28
29 size = m
30
31 def siftdown(heap, pos, size):
32 item = heap[pos]
33 w = item.w
34 child = (pos << 1) + 1
35 while child < size:
36 right = child + 1
37 if right < size and heap[right].w < heap[child].w:
38 child = right
39 if heap[child].w >= w:
40 break
41 heap[pos] = heap[child]
42 pos = child
43 child = (pos << 1) + 1
44 heap[pos] = item
45
46 def siftup(heap, pos):
47 item = heap[pos]
48 w = item.w
49 while pos:
50 parent = (pos - 1) >> 1
51 if heap[parent].w <= w:
52 break
53 heap[pos] = heap[parent]
54 pos = parent
55 heap[pos] = item
56
57 for i in range((size >> 1) - 1, -1, -1):
58 siftdown(heap, i, size)
59
60 total = 0
61 while size > 1:
62 a = heap[0]
63 size -= 1
64 last = heap[size]
65 if size:
66 heap[0] = last
67 siftdown(heap, 0, size)
68
69 b = heap[0]
70 size -= 1
71 if size:
72 last = heap[size]
73 heap[0] = last
74 siftdown(heap, 0, size)
75
76 s = a.w + b.w
77 total += s
78 node = Node(s, a, b)
79 heap[size] = node
80 size += 1
81 siftup(heap, size - 1)
82
83 root = heap[0]
84 stack = [(root, 0)]
85 encoded_length = 0
86 while stack:
87 node, depth = stack.pop()
88 left = node.left
89 if left is None:
90 encoded_length += node.w * depth
91 else:
92 d = depth + 1
93 stack.append((left, d))
94 stack.append((node.right, d))
95
96 return {"encoded_length": encoded_length, "decoded": text}
Champion
100% (5/5)24μs
1def solve(input):
2 text = input.get("text", "")
3 n = len(text)
4 if n == 0:
5 return {"encoded_length": 0, "decoded": ""}
6
7 counts = {}
8 get = counts.get
9 for ch in text:
10 counts[ch] = get(ch, 0) + 1
11
12 freqs = list(counts.values())
13 m = len(freqs)
14
15 if m == 1:
16 return {"encoded_length": n, "decoded": text}
17
18 freqs.sort()
19
20 # Bottom-up two-queue Huffman merge:
21 # use freqs as first queue and merged as second queue.
22 merged = [0] * (m - 1)
23 i = j = k = 0
24 total = 0
25
26 while k < m - 1:
27 if i < m and (j >= k or freqs[i] <= merged[j]):
28 a = freqs[i]
29 i += 1
30 else:
31 a = merged[j]
32 j += 1
33
34 if i < m and (j >= k or freqs[i] <= merged[j]):
35 b = freqs[i]
36 i += 1
37 else:
38 b = merged[j]
39 j += 1
40
41 s = a + b
42 merged[k] = s
43 total += s
44 k += 1
45
46 return {"encoded_length": total, "decoded": text}