Solution #e227904f-5ec6-4b63-bdb8-5775a409c53d

completed

Score

100% (5/5)

Runtime

145μs

Delta

No change vs parent

Tied for best

Same as parent

Solution Lineage

Current100%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 not n:
        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", "nxt")
        def __init__(self, w, nxt=None):
            self.w = w
            self.nxt = nxt

    head = None
    for v in counts.values():
        head = Node(v, head)

    bins = [None] * (n + 1)
    cur = head
    while cur is not None:
        nxt = cur.nxt
        w = cur.w
        cur.nxt = bins[w]
        bins[w] = cur
        cur = nxt

    sorted_head = None
    sorted_tail = None
    i = 1
    while i <= n:
        node = bins[i]
        while node is not None:
            nxt = node.nxt
            node.nxt = None
            if sorted_head is None:
                sorted_head = node
                sorted_tail = node
            else:
                sorted_tail.nxt = node
                sorted_tail = node
            node = nxt
        i += 1

    q1 = sorted_head
    q2 = None
    q2_tail = None
    total = 0
    remaining = m

    while remaining > 1:
        if q2 is None or (q1 is not None and q1.w <= q2.w):
            a = q1
            q1 = q1.nxt
            wa = a.w
        else:
            a = q2
            q2 = q2.nxt
            wa = a.w

        if q2 is None or (q1 is not None and q1.w <= q2.w):
            b = q1
            q1 = q1.nxt
            wb = b.w
        else:
            b = q2
            q2 = q2.nxt
            wb = b.w

        s = wa + wb
        total += s
        node = Node(s)
        if q2 is None:
            q2 = node
            q2_tail = node
        else:
            q2_tail.nxt = node
            q2_tail = node
        remaining -= 1

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

Compare with Champion

Score Difference

Tied

Runtime Advantage

121μs slower

Code Size

88 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 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", "nxt")17
18 def __init__(self, w, nxt=None):18 freqs.sort()
19 self.w = w19
20 self.nxt = nxt20 # Bottom-up two-queue Huffman merge:
2121 # use freqs as first queue and merged as second queue.
22 head = None22 merged = [0] * (m - 1)
23 for v in counts.values():23 i = j = k = 0
24 head = Node(v, head)24 total = 0
2525
26 bins = [None] * (n + 1)26 while k < m - 1:
27 cur = head27 if i < m and (j >= k or freqs[i] <= merged[j]):
28 while cur is not None:28 a = freqs[i]
29 nxt = cur.nxt29 i += 1
30 w = cur.w30 else:
31 cur.nxt = bins[w]31 a = merged[j]
32 bins[w] = cur32 j += 1
33 cur = nxt33
3434 if i < m and (j >= k or freqs[i] <= merged[j]):
35 sorted_head = None35 b = freqs[i]
36 sorted_tail = None36 i += 1
37 i = 137 else:
38 while i <= n:38 b = merged[j]
39 node = bins[i]39 j += 1
40 while node is not None:40
41 nxt = node.nxt41 s = a + b
42 node.nxt = None42 merged[k] = s
43 if sorted_head is None:43 total += s
44 sorted_head = node44 k += 1
45 sorted_tail = node45
46 else:46 return {"encoded_length": total, "decoded": text}
47 sorted_tail.nxt = node47
48 sorted_tail = node48
49 node = nxt49
50 i += 150
5151
52 q1 = sorted_head52
53 q2 = None53
54 q2_tail = None54
55 total = 055
56 remaining = m56
5757
58 while remaining > 1:58
59 if q2 is None or (q1 is not None and q1.w <= q2.w):59
60 a = q160
61 q1 = q1.nxt61
62 wa = a.w62
63 else:63
64 a = q264
65 q2 = q2.nxt65
66 wa = a.w66
6767
68 if q2 is None or (q1 is not None and q1.w <= q2.w):68
69 b = q169
70 q1 = q1.nxt70
71 wb = b.w71
72 else:72
73 b = q273
74 q2 = q2.nxt74
75 wb = b.w75
7676
77 s = wa + wb77
78 total += s78
79 node = Node(s)79
80 if q2 is None:80
81 q2 = node81
82 q2_tail = node82
83 else:83
84 q2_tail.nxt = node84
85 q2_tail = node85
86 remaining -= 186
8787
88 return {"encoded_length": total, "decoded": text}88
Your Solution
100% (5/5)145μ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 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", "nxt")
18 def __init__(self, w, nxt=None):
19 self.w = w
20 self.nxt = nxt
21
22 head = None
23 for v in counts.values():
24 head = Node(v, head)
25
26 bins = [None] * (n + 1)
27 cur = head
28 while cur is not None:
29 nxt = cur.nxt
30 w = cur.w
31 cur.nxt = bins[w]
32 bins[w] = cur
33 cur = nxt
34
35 sorted_head = None
36 sorted_tail = None
37 i = 1
38 while i <= n:
39 node = bins[i]
40 while node is not None:
41 nxt = node.nxt
42 node.nxt = None
43 if sorted_head is None:
44 sorted_head = node
45 sorted_tail = node
46 else:
47 sorted_tail.nxt = node
48 sorted_tail = node
49 node = nxt
50 i += 1
51
52 q1 = sorted_head
53 q2 = None
54 q2_tail = None
55 total = 0
56 remaining = m
57
58 while remaining > 1:
59 if q2 is None or (q1 is not None and q1.w <= q2.w):
60 a = q1
61 q1 = q1.nxt
62 wa = a.w
63 else:
64 a = q2
65 q2 = q2.nxt
66 wa = a.w
67
68 if q2 is None or (q1 is not None and q1.w <= q2.w):
69 b = q1
70 q1 = q1.nxt
71 wb = b.w
72 else:
73 b = q2
74 q2 = q2.nxt
75 wb = b.w
76
77 s = wa + wb
78 total += s
79 node = Node(s)
80 if q2 is None:
81 q2 = node
82 q2_tail = node
83 else:
84 q2_tail.nxt = node
85 q2_tail = node
86 remaining -= 1
87
88 return {"encoded_length": total, "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}