Solution #2da814bd-4b7d-485b-b46a-4a1288e60fdf
completedScore
100% (5/5)
Runtime
253μs
Delta
No change vs parent
Tied for best
Same as parent
Score
100% (5/5)
Runtime
253μs
Delta
No change vs parent
Tied for best
Same as parent
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}Score Difference
Tied
Runtime Advantage
229μs slower
Code Size
96 vs 46 lines
| # | Your Solution | # | Champion |
|---|---|---|---|
| 1 | def solve(input): | 1 | def 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": ""} |
| 6 | 6 | ||
| 7 | counts = {} | 7 | counts = {} |
| 8 | get = counts.get | 8 | get = counts.get |
| 9 | for ch in text: | 9 | for ch in text: |
| 10 | counts[ch] = get(ch, 0) + 1 | 10 | counts[ch] = get(ch, 0) + 1 |
| 11 | 11 | ||
| 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 | |
| 15 | 15 | 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 = w | 19 | |
| 20 | self.left = left | 20 | # Bottom-up two-queue Huffman merge: |
| 21 | self.right = right | 21 | # use freqs as first queue and merged as second queue. |
| 22 | 22 | merged = [0] * (m - 1) | |
| 23 | heap = [None] * m | 23 | i = j = k = 0 |
| 24 | i = 0 | 24 | total = 0 |
| 25 | for v in counts.values(): | 25 | |
| 26 | heap[i] = Node(v) | 26 | while k < m - 1: |
| 27 | i += 1 | 27 | if i < m and (j >= k or freqs[i] <= merged[j]): |
| 28 | 28 | a = freqs[i] | |
| 29 | size = m | 29 | i += 1 |
| 30 | 30 | else: | |
| 31 | def siftdown(heap, pos, size): | 31 | a = merged[j] |
| 32 | item = heap[pos] | 32 | j += 1 |
| 33 | w = item.w | 33 | |
| 34 | child = (pos << 1) + 1 | 34 | if i < m and (j >= k or freqs[i] <= merged[j]): |
| 35 | while child < size: | 35 | b = freqs[i] |
| 36 | right = child + 1 | 36 | i += 1 |
| 37 | if right < size and heap[right].w < heap[child].w: | 37 | else: |
| 38 | child = right | 38 | b = merged[j] |
| 39 | if heap[child].w >= w: | 39 | j += 1 |
| 40 | break | 40 | |
| 41 | heap[pos] = heap[child] | 41 | s = a + b |
| 42 | pos = child | 42 | merged[k] = s |
| 43 | child = (pos << 1) + 1 | 43 | total += s |
| 44 | heap[pos] = item | 44 | k += 1 |
| 45 | 45 | ||
| 46 | def siftup(heap, pos): | 46 | return {"encoded_length": total, "decoded": text} |
| 47 | item = heap[pos] | 47 | |
| 48 | w = item.w | 48 | |
| 49 | while pos: | 49 | |
| 50 | parent = (pos - 1) >> 1 | 50 | |
| 51 | if heap[parent].w <= w: | 51 | |
| 52 | break | 52 | |
| 53 | heap[pos] = heap[parent] | 53 | |
| 54 | pos = parent | 54 | |
| 55 | heap[pos] = item | 55 | |
| 56 | 56 | ||
| 57 | for i in range((size >> 1) - 1, -1, -1): | 57 | |
| 58 | siftdown(heap, i, size) | 58 | |
| 59 | 59 | ||
| 60 | total = 0 | 60 | |
| 61 | while size > 1: | 61 | |
| 62 | a = heap[0] | 62 | |
| 63 | size -= 1 | 63 | |
| 64 | last = heap[size] | 64 | |
| 65 | if size: | 65 | |
| 66 | heap[0] = last | 66 | |
| 67 | siftdown(heap, 0, size) | 67 | |
| 68 | 68 | ||
| 69 | b = heap[0] | 69 | |
| 70 | size -= 1 | 70 | |
| 71 | if size: | 71 | |
| 72 | last = heap[size] | 72 | |
| 73 | heap[0] = last | 73 | |
| 74 | siftdown(heap, 0, size) | 74 | |
| 75 | 75 | ||
| 76 | s = a.w + b.w | 76 | |
| 77 | total += s | 77 | |
| 78 | node = Node(s, a, b) | 78 | |
| 79 | heap[size] = node | 79 | |
| 80 | size += 1 | 80 | |
| 81 | siftup(heap, size - 1) | 81 | |
| 82 | 82 | ||
| 83 | root = heap[0] | 83 | |
| 84 | stack = [(root, 0)] | 84 | |
| 85 | encoded_length = 0 | 85 | |
| 86 | while stack: | 86 | |
| 87 | node, depth = stack.pop() | 87 | |
| 88 | left = node.left | 88 | |
| 89 | if left is None: | 89 | |
| 90 | encoded_length += node.w * depth | 90 | |
| 91 | else: | 91 | |
| 92 | d = depth + 1 | 92 | |
| 93 | stack.append((left, d)) | 93 | |
| 94 | stack.append((node.right, d)) | 94 | |
| 95 | 95 | ||
| 96 | return {"encoded_length": encoded_length, "decoded": text} | 96 |
1def solve(input):2 text = input.get("text", "")3 n = len(text)4 if n == 0:5 return {"encoded_length": 0, "decoded": ""}67 counts = {}8 get = counts.get9 for ch in text:10 counts[ch] = get(ch, 0) + 11112 m = len(counts)13 if m == 1:14 return {"encoded_length": n, "decoded": text}1516 class Node:17 __slots__ = ("w", "left", "right")18 def __init__(self, w, left=None, right=None):19 self.w = w20 self.left = left21 self.right = right2223 heap = [None] * m24 i = 025 for v in counts.values():26 heap[i] = Node(v)27 i += 12829 size = m3031 def siftdown(heap, pos, size):32 item = heap[pos]33 w = item.w34 child = (pos << 1) + 135 while child < size:36 right = child + 137 if right < size and heap[right].w < heap[child].w:38 child = right39 if heap[child].w >= w:40 break41 heap[pos] = heap[child]42 pos = child43 child = (pos << 1) + 144 heap[pos] = item4546 def siftup(heap, pos):47 item = heap[pos]48 w = item.w49 while pos:50 parent = (pos - 1) >> 151 if heap[parent].w <= w:52 break53 heap[pos] = heap[parent]54 pos = parent55 heap[pos] = item5657 for i in range((size >> 1) - 1, -1, -1):58 siftdown(heap, i, size)5960 total = 061 while size > 1:62 a = heap[0]63 size -= 164 last = heap[size]65 if size:66 heap[0] = last67 siftdown(heap, 0, size)6869 b = heap[0]70 size -= 171 if size:72 last = heap[size]73 heap[0] = last74 siftdown(heap, 0, size)7576 s = a.w + b.w77 total += s78 node = Node(s, a, b)79 heap[size] = node80 size += 181 siftup(heap, size - 1)8283 root = heap[0]84 stack = [(root, 0)]85 encoded_length = 086 while stack:87 node, depth = stack.pop()88 left = node.left89 if left is None:90 encoded_length += node.w * depth91 else:92 d = depth + 193 stack.append((left, d))94 stack.append((node.right, d))9596 return {"encoded_length": encoded_length, "decoded": text}1def solve(input):2 text = input.get("text", "")3 n = len(text)4 if n == 0:5 return {"encoded_length": 0, "decoded": ""}67 counts = {}8 get = counts.get9 for ch in text:10 counts[ch] = get(ch, 0) + 11112 freqs = list(counts.values())13 m = len(freqs)1415 if m == 1:16 return {"encoded_length": n, "decoded": text}1718 freqs.sort()1920 # 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 = 024 total = 02526 while k < m - 1:27 if i < m and (j >= k or freqs[i] <= merged[j]):28 a = freqs[i]29 i += 130 else:31 a = merged[j]32 j += 13334 if i < m and (j >= k or freqs[i] <= merged[j]):35 b = freqs[i]36 i += 137 else:38 b = merged[j]39 j += 14041 s = a + b42 merged[k] = s43 total += s44 k += 14546 return {"encoded_length": total, "decoded": text}