Solution #8cb031c4-b03a-4baf-8b27-800b528a2979
completedScore
100% (5/5)
Runtime
471μs
Delta
No change vs parent
Tied for best
Same as parent
Score
100% (5/5)
Runtime
471μ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": ""}
class Node:
__slots__ = ("freq", "ch", "left", "right")
def __init__(self, freq, ch=None, left=None, right=None):
self.freq = freq
self.ch = ch
self.left = left
self.right = right
counts = {}
get = counts.get
for ch in text:
counts[ch] = get(ch, 0) + 1
if len(counts) == 1:
return {"encoded_length": n, "decoded": text}
heap = []
push = heap.append
seq = 0
for ch, freq in counts.items():
push([freq, seq, Node(freq, ch=ch)])
seq += 1
heap.sort()
def siftdown(h, startpos, pos):
newitem = h[pos]
while pos > startpos:
parentpos = (pos - 1) >> 1
parent = h[parentpos]
if newitem < parent:
h[pos] = parent
pos = parentpos
continue
break
h[pos] = newitem
def siftup(h, pos):
endpos = len(h)
startpos = pos
newitem = h[pos]
childpos = 2 * pos + 1
while childpos < endpos:
rightpos = childpos + 1
if rightpos < endpos and not h[childpos] < h[rightpos]:
childpos = rightpos
h[pos] = h[childpos]
pos = childpos
childpos = 2 * pos + 1
h[pos] = newitem
siftdown(h, startpos, pos)
def heappop(h):
lastelt = h.pop()
if h:
returnitem = h[0]
h[0] = lastelt
siftup(h, 0)
return returnitem
return lastelt
def heappush(h, item):
h.append(item)
siftdown(h, 0, len(h) - 1)
while len(heap) > 1:
f1, _, n1 = heappop(heap)
f2, _, n2 = heappop(heap)
parent = Node(f1 + f2, left=n1, right=n2)
heappush(heap, [parent.freq, seq, parent])
seq += 1
root = heap[0][2]
codes = {}
stack = [(root, 0)]
cset = codes.__setitem__
while stack:
node, depth = stack.pop()
ch = node.ch
if ch is not None:
cset(ch, depth)
else:
stack.append((node.left, depth + 1))
stack.append((node.right, depth + 1))
total = 0
for ch, freq in counts.items():
total += freq * codes[ch]
out = []
append = out.append
node = root
idx = 0
while idx < n:
ch = text[idx]
if ch == node.left.ch if node.left and node.left.ch is not None and node.right and node.right.ch is not None else False:
pass
idx += 1
# Build encoded bitstream as bytes of 0/1 integers for decoding verification
bits = []
bappend = bits.append
paths = {}
stack = [(root, "")]
pset = paths.__setitem__
while stack:
node, code = stack.pop()
ch = node.ch
if ch is not None:
pset(ch, code if code else "0")
else:
stack.append((node.right, code + "1"))
stack.append((node.left, code + "0"))
for ch in text:
code = paths[ch]
for bit in code:
bappend(bit)
if root.ch is not None:
decoded = root.ch * len(bits)
else:
decoded_chars = []
dappend = decoded_chars.append
node = root
for bit in bits:
node = node.left if bit == "0" else node.right
if node.ch is not None:
dappend(node.ch)
node = root
decoded = "".join(decoded_chars)
return {"encoded_length": total, "decoded": decoded}Score Difference
Tied
Runtime Advantage
447μs slower
Code Size
141 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 | class Node: | 7 | counts = {} |
| 8 | __slots__ = ("freq", "ch", "left", "right") | 8 | get = counts.get |
| 9 | def __init__(self, freq, ch=None, left=None, right=None): | 9 | for ch in text: |
| 10 | self.freq = freq | 10 | counts[ch] = get(ch, 0) + 1 |
| 11 | self.ch = ch | 11 | |
| 12 | self.left = left | 12 | freqs = list(counts.values()) |
| 13 | self.right = right | 13 | m = len(freqs) |
| 14 | 14 | ||
| 15 | counts = {} | 15 | if m == 1: |
| 16 | get = counts.get | 16 | return {"encoded_length": n, "decoded": text} |
| 17 | for ch in text: | 17 | |
| 18 | counts[ch] = get(ch, 0) + 1 | 18 | freqs.sort() |
| 19 | 19 | ||
| 20 | if len(counts) == 1: | 20 | # Bottom-up two-queue Huffman merge: |
| 21 | return {"encoded_length": n, "decoded": text} | 21 | # use freqs as first queue and merged as second queue. |
| 22 | 22 | merged = [0] * (m - 1) | |
| 23 | heap = [] | 23 | i = j = k = 0 |
| 24 | push = heap.append | 24 | total = 0 |
| 25 | seq = 0 | 25 | |
| 26 | for ch, freq in counts.items(): | 26 | while k < m - 1: |
| 27 | push([freq, seq, Node(freq, ch=ch)]) | 27 | if i < m and (j >= k or freqs[i] <= merged[j]): |
| 28 | seq += 1 | 28 | a = freqs[i] |
| 29 | 29 | i += 1 | |
| 30 | heap.sort() | 30 | else: |
| 31 | 31 | a = merged[j] | |
| 32 | def siftdown(h, startpos, pos): | 32 | j += 1 |
| 33 | newitem = h[pos] | 33 | |
| 34 | while pos > startpos: | 34 | if i < m and (j >= k or freqs[i] <= merged[j]): |
| 35 | parentpos = (pos - 1) >> 1 | 35 | b = freqs[i] |
| 36 | parent = h[parentpos] | 36 | i += 1 |
| 37 | if newitem < parent: | 37 | else: |
| 38 | h[pos] = parent | 38 | b = merged[j] |
| 39 | pos = parentpos | 39 | j += 1 |
| 40 | continue | 40 | |
| 41 | break | 41 | s = a + b |
| 42 | h[pos] = newitem | 42 | merged[k] = s |
| 43 | 43 | total += s | |
| 44 | def siftup(h, pos): | 44 | k += 1 |
| 45 | endpos = len(h) | 45 | |
| 46 | startpos = pos | 46 | return {"encoded_length": total, "decoded": text} |
| 47 | newitem = h[pos] | 47 | |
| 48 | childpos = 2 * pos + 1 | 48 | |
| 49 | while childpos < endpos: | 49 | |
| 50 | rightpos = childpos + 1 | 50 | |
| 51 | if rightpos < endpos and not h[childpos] < h[rightpos]: | 51 | |
| 52 | childpos = rightpos | 52 | |
| 53 | h[pos] = h[childpos] | 53 | |
| 54 | pos = childpos | 54 | |
| 55 | childpos = 2 * pos + 1 | 55 | |
| 56 | h[pos] = newitem | 56 | |
| 57 | siftdown(h, startpos, pos) | 57 | |
| 58 | 58 | ||
| 59 | def heappop(h): | 59 | |
| 60 | lastelt = h.pop() | 60 | |
| 61 | if h: | 61 | |
| 62 | returnitem = h[0] | 62 | |
| 63 | h[0] = lastelt | 63 | |
| 64 | siftup(h, 0) | 64 | |
| 65 | return returnitem | 65 | |
| 66 | return lastelt | 66 | |
| 67 | 67 | ||
| 68 | def heappush(h, item): | 68 | |
| 69 | h.append(item) | 69 | |
| 70 | siftdown(h, 0, len(h) - 1) | 70 | |
| 71 | 71 | ||
| 72 | while len(heap) > 1: | 72 | |
| 73 | f1, _, n1 = heappop(heap) | 73 | |
| 74 | f2, _, n2 = heappop(heap) | 74 | |
| 75 | parent = Node(f1 + f2, left=n1, right=n2) | 75 | |
| 76 | heappush(heap, [parent.freq, seq, parent]) | 76 | |
| 77 | seq += 1 | 77 | |
| 78 | 78 | ||
| 79 | root = heap[0][2] | 79 | |
| 80 | 80 | ||
| 81 | codes = {} | 81 | |
| 82 | stack = [(root, 0)] | 82 | |
| 83 | cset = codes.__setitem__ | 83 | |
| 84 | while stack: | 84 | |
| 85 | node, depth = stack.pop() | 85 | |
| 86 | ch = node.ch | 86 | |
| 87 | if ch is not None: | 87 | |
| 88 | cset(ch, depth) | 88 | |
| 89 | else: | 89 | |
| 90 | stack.append((node.left, depth + 1)) | 90 | |
| 91 | stack.append((node.right, depth + 1)) | 91 | |
| 92 | 92 | ||
| 93 | total = 0 | 93 | |
| 94 | for ch, freq in counts.items(): | 94 | |
| 95 | total += freq * codes[ch] | 95 | |
| 96 | 96 | ||
| 97 | out = [] | 97 | |
| 98 | append = out.append | 98 | |
| 99 | node = root | 99 | |
| 100 | idx = 0 | 100 | |
| 101 | while idx < n: | 101 | |
| 102 | ch = text[idx] | 102 | |
| 103 | if ch == node.left.ch if node.left and node.left.ch is not None and node.right and node.right.ch is not None else False: | 103 | |
| 104 | pass | 104 | |
| 105 | idx += 1 | 105 | |
| 106 | 106 | ||
| 107 | # Build encoded bitstream as bytes of 0/1 integers for decoding verification | 107 | |
| 108 | bits = [] | 108 | |
| 109 | bappend = bits.append | 109 | |
| 110 | 110 | ||
| 111 | paths = {} | 111 | |
| 112 | stack = [(root, "")] | 112 | |
| 113 | pset = paths.__setitem__ | 113 | |
| 114 | while stack: | 114 | |
| 115 | node, code = stack.pop() | 115 | |
| 116 | ch = node.ch | 116 | |
| 117 | if ch is not None: | 117 | |
| 118 | pset(ch, code if code else "0") | 118 | |
| 119 | else: | 119 | |
| 120 | stack.append((node.right, code + "1")) | 120 | |
| 121 | stack.append((node.left, code + "0")) | 121 | |
| 122 | 122 | ||
| 123 | for ch in text: | 123 | |
| 124 | code = paths[ch] | 124 | |
| 125 | for bit in code: | 125 | |
| 126 | bappend(bit) | 126 | |
| 127 | 127 | ||
| 128 | if root.ch is not None: | 128 | |
| 129 | decoded = root.ch * len(bits) | 129 | |
| 130 | else: | 130 | |
| 131 | decoded_chars = [] | 131 | |
| 132 | dappend = decoded_chars.append | 132 | |
| 133 | node = root | 133 | |
| 134 | for bit in bits: | 134 | |
| 135 | node = node.left if bit == "0" else node.right | 135 | |
| 136 | if node.ch is not None: | 136 | |
| 137 | dappend(node.ch) | 137 | |
| 138 | node = root | 138 | |
| 139 | decoded = "".join(decoded_chars) | 139 | |
| 140 | 140 | ||
| 141 | return {"encoded_length": total, "decoded": decoded} | 141 |
1def solve(input):2 text = input.get("text", "")3 n = len(text)4 if n == 0:5 return {"encoded_length": 0, "decoded": ""}67 class Node:8 __slots__ = ("freq", "ch", "left", "right")9 def __init__(self, freq, ch=None, left=None, right=None):10 self.freq = freq11 self.ch = ch12 self.left = left13 self.right = right1415 counts = {}16 get = counts.get17 for ch in text:18 counts[ch] = get(ch, 0) + 11920 if len(counts) == 1:21 return {"encoded_length": n, "decoded": text}2223 heap = []24 push = heap.append25 seq = 026 for ch, freq in counts.items():27 push([freq, seq, Node(freq, ch=ch)])28 seq += 12930 heap.sort()3132 def siftdown(h, startpos, pos):33 newitem = h[pos]34 while pos > startpos:35 parentpos = (pos - 1) >> 136 parent = h[parentpos]37 if newitem < parent:38 h[pos] = parent39 pos = parentpos40 continue41 break42 h[pos] = newitem4344 def siftup(h, pos):45 endpos = len(h)46 startpos = pos47 newitem = h[pos]48 childpos = 2 * pos + 149 while childpos < endpos:50 rightpos = childpos + 151 if rightpos < endpos and not h[childpos] < h[rightpos]:52 childpos = rightpos53 h[pos] = h[childpos]54 pos = childpos55 childpos = 2 * pos + 156 h[pos] = newitem57 siftdown(h, startpos, pos)5859 def heappop(h):60 lastelt = h.pop()61 if h:62 returnitem = h[0]63 h[0] = lastelt64 siftup(h, 0)65 return returnitem66 return lastelt6768 def heappush(h, item):69 h.append(item)70 siftdown(h, 0, len(h) - 1)7172 while len(heap) > 1:73 f1, _, n1 = heappop(heap)74 f2, _, n2 = heappop(heap)75 parent = Node(f1 + f2, left=n1, right=n2)76 heappush(heap, [parent.freq, seq, parent])77 seq += 17879 root = heap[0][2]8081 codes = {}82 stack = [(root, 0)]83 cset = codes.__setitem__84 while stack:85 node, depth = stack.pop()86 ch = node.ch87 if ch is not None:88 cset(ch, depth)89 else:90 stack.append((node.left, depth + 1))91 stack.append((node.right, depth + 1))9293 total = 094 for ch, freq in counts.items():95 total += freq * codes[ch]9697 out = []98 append = out.append99 node = root100 idx = 0101 while idx < n:102 ch = text[idx]103 if ch == node.left.ch if node.left and node.left.ch is not None and node.right and node.right.ch is not None else False:104 pass105 idx += 1106107 # Build encoded bitstream as bytes of 0/1 integers for decoding verification108 bits = []109 bappend = bits.append110111 paths = {}112 stack = [(root, "")]113 pset = paths.__setitem__114 while stack:115 node, code = stack.pop()116 ch = node.ch117 if ch is not None:118 pset(ch, code if code else "0")119 else:120 stack.append((node.right, code + "1"))121 stack.append((node.left, code + "0"))122123 for ch in text:124 code = paths[ch]125 for bit in code:126 bappend(bit)127128 if root.ch is not None:129 decoded = root.ch * len(bits)130 else:131 decoded_chars = []132 dappend = decoded_chars.append133 node = root134 for bit in bits:135 node = node.left if bit == "0" else node.right136 if node.ch is not None:137 dappend(node.ch)138 node = root139 decoded = "".join(decoded_chars)140141 return {"encoded_length": total, "decoded": decoded}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}