Solution #62082b2d-9da5-46b1-994d-9b75f5adee57

completed

Score

100% (5/5)

Runtime

251μs

Delta

No change vs parent

Tied for best

Same as parent

Solution Lineage

Current100%Same as parent
2a708353100%Same as parent
a0f415b0100%First in chain

Code

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

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

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

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

    heap = [Node(f, None, None, ch) for ch, f in freq.items()]
    size = len(heap)

    def sift_down(i, size, heap):
        item = heap[i]
        iw = item.w
        while True:
            l = (i << 1) + 1
            if l >= size:
                break
            r = l + 1
            c = l
            cw = heap[l].w
            if r < size:
                rw = heap[r].w
                if rw < cw:
                    c = r
                    cw = rw
            if cw >= iw:
                break
            heap[i] = heap[c]
            i = c
        heap[i] = item

    def sift_up(i, heap):
        item = heap[i]
        iw = item.w
        while i:
            p = (i - 1) >> 1
            pw = heap[p].w
            if pw <= iw:
                break
            heap[i] = heap[p]
            i = p
        heap[i] = item

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

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

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

        parent = Node(a.w + b.w, a, b, None)
        if size < len(heap):
            heap[size] = parent
        else:
            heap.append(parent)
        sift_up(size, heap)
        size += 1

    root = heap[0]
    encoded_length = 0
    stack = [(root, 0)]
    append = stack.append
    pop = stack.pop

    while stack:
        node, depth = pop()
        ch = node.ch
        if ch is not None:
            encoded_length += node.w * depth
        else:
            nd = depth + 1
            append((node.left, nd))
            append((node.right, nd))

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

Compare with Champion

Score Difference

Tied

Runtime Advantage

227μs slower

Code Size

102 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 not n:4 if n == 0:
5 return {"encoded_length": 0, "decoded": ""}5 return {"encoded_length": 0, "decoded": ""}
66
7 freq = {}7 counts = {}
8 get = freq.get8 get = counts.get
9 for ch in text:9 for ch in text:
10 freq[ch] = get(ch, 0) + 110 counts[ch] = get(ch, 0) + 1
1111
12 m = len(freq)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", "ch")17
18 def __init__(self, w, left=None, right=None, ch=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.
22 self.ch = ch22 merged = [0] * (m - 1)
2323 i = j = k = 0
24 heap = [Node(f, None, None, ch) for ch, f in freq.items()]24 total = 0
25 size = len(heap)25
2626 while k < m - 1:
27 def sift_down(i, size, heap):27 if i < m and (j >= k or freqs[i] <= merged[j]):
28 item = heap[i]28 a = freqs[i]
29 iw = item.w29 i += 1
30 while True:30 else:
31 l = (i << 1) + 131 a = merged[j]
32 if l >= size:32 j += 1
33 break33
34 r = l + 134 if i < m and (j >= k or freqs[i] <= merged[j]):
35 c = l35 b = freqs[i]
36 cw = heap[l].w36 i += 1
37 if r < size:37 else:
38 rw = heap[r].w38 b = merged[j]
39 if rw < cw:39 j += 1
40 c = r40
41 cw = rw41 s = a + b
42 if cw >= iw:42 merged[k] = s
43 break43 total += s
44 heap[i] = heap[c]44 k += 1
45 i = c45
46 heap[i] = item46 return {"encoded_length": total, "decoded": text}
4747
48 def sift_up(i, heap):48
49 item = heap[i]49
50 iw = item.w50
51 while i:51
52 p = (i - 1) >> 152
53 pw = heap[p].w53
54 if pw <= iw:54
55 break55
56 heap[i] = heap[p]56
57 i = p57
58 heap[i] = item58
5959
60 for i in range((size >> 1) - 1, -1, -1):60
61 sift_down(i, size, heap)61
6262
63 while size > 1:63
64 a = heap[0]64
65 size -= 165
66 last = heap[size]66
67 if size:67
68 heap[0] = last68
69 sift_down(0, size, heap)69
7070
71 b = heap[0]71
72 size -= 172
73 if size:73
74 last = heap[size]74
75 heap[0] = last75
76 sift_down(0, size, heap)76
7777
78 parent = Node(a.w + b.w, a, b, None)78
79 if size < len(heap):79
80 heap[size] = parent80
81 else:81
82 heap.append(parent)82
83 sift_up(size, heap)83
84 size += 184
8585
86 root = heap[0]86
87 encoded_length = 087
88 stack = [(root, 0)]88
89 append = stack.append89
90 pop = stack.pop90
9191
92 while stack:92
93 node, depth = pop()93
94 ch = node.ch94
95 if ch is not None:95
96 encoded_length += node.w * depth96
97 else:97
98 nd = depth + 198
99 append((node.left, nd))99
100 append((node.right, nd))100
101101
102 return {"encoded_length": encoded_length, "decoded": text}102
Your Solution
100% (5/5)251μs
1def solve(input):
2 text = input.get("text", "")
3 n = len(text)
4 if not n:
5 return {"encoded_length": 0, "decoded": ""}
6
7 freq = {}
8 get = freq.get
9 for ch in text:
10 freq[ch] = get(ch, 0) + 1
11
12 m = len(freq)
13 if m == 1:
14 return {"encoded_length": n, "decoded": text}
15
16 class Node:
17 __slots__ = ("w", "left", "right", "ch")
18 def __init__(self, w, left=None, right=None, ch=None):
19 self.w = w
20 self.left = left
21 self.right = right
22 self.ch = ch
23
24 heap = [Node(f, None, None, ch) for ch, f in freq.items()]
25 size = len(heap)
26
27 def sift_down(i, size, heap):
28 item = heap[i]
29 iw = item.w
30 while True:
31 l = (i << 1) + 1
32 if l >= size:
33 break
34 r = l + 1
35 c = l
36 cw = heap[l].w
37 if r < size:
38 rw = heap[r].w
39 if rw < cw:
40 c = r
41 cw = rw
42 if cw >= iw:
43 break
44 heap[i] = heap[c]
45 i = c
46 heap[i] = item
47
48 def sift_up(i, heap):
49 item = heap[i]
50 iw = item.w
51 while i:
52 p = (i - 1) >> 1
53 pw = heap[p].w
54 if pw <= iw:
55 break
56 heap[i] = heap[p]
57 i = p
58 heap[i] = item
59
60 for i in range((size >> 1) - 1, -1, -1):
61 sift_down(i, size, heap)
62
63 while size > 1:
64 a = heap[0]
65 size -= 1
66 last = heap[size]
67 if size:
68 heap[0] = last
69 sift_down(0, size, heap)
70
71 b = heap[0]
72 size -= 1
73 if size:
74 last = heap[size]
75 heap[0] = last
76 sift_down(0, size, heap)
77
78 parent = Node(a.w + b.w, a, b, None)
79 if size < len(heap):
80 heap[size] = parent
81 else:
82 heap.append(parent)
83 sift_up(size, heap)
84 size += 1
85
86 root = heap[0]
87 encoded_length = 0
88 stack = [(root, 0)]
89 append = stack.append
90 pop = stack.pop
91
92 while stack:
93 node, depth = pop()
94 ch = node.ch
95 if ch is not None:
96 encoded_length += node.w * depth
97 else:
98 nd = depth + 1
99 append((node.left, nd))
100 append((node.right, nd))
101
102 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}