Skip to content

Commit c07a17c

Browse files
committed
Day 16 Python solutions
1 parent 9f8846d commit c07a17c

File tree

2 files changed

+256
-0
lines changed

2 files changed

+256
-0
lines changed

16-1.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#!/usr/bin/env python
2+
3+
class Packet:
4+
def __init__(self, version, t):
5+
self.version = version
6+
self.t = t
7+
8+
def score(self):
9+
return self.version
10+
11+
def __str__(self):
12+
return f"<{self.__class__.__name__}: version={self.version}, type={self.t}>"
13+
14+
15+
class Literal(Packet):
16+
def __init__(self, version, t):
17+
super().__init__(version, t)
18+
self.data = -1
19+
20+
def parse(self, bits):
21+
b = ''
22+
while True:
23+
cont = int(bits[0])
24+
group = bits[1:5]
25+
bits = bits[5:]
26+
b += ''.join(group)
27+
if cont == 0:
28+
break
29+
self.data = int(b, 2)
30+
return bits
31+
32+
def __str__(self):
33+
return f"<{self.__class__.__name__}: version={self.version}, type={self.t}, data={self.data}>"
34+
35+
36+
class Operator(Packet):
37+
def __init__(self, version, t):
38+
super().__init__(version, t)
39+
self.sub_packets = []
40+
41+
def parse(self, bits):
42+
length_type_id = int(''.join(bits[0:1]))
43+
bits = bits[1:]
44+
if length_type_id == 0:
45+
sub_packet_length = int(''.join(bits[0:15]), 2)
46+
bits = bits[15:]
47+
self.sub_packets = parse_packets(bits[0:sub_packet_length])
48+
bits = bits[sub_packet_length:]
49+
elif length_type_id == 1:
50+
num_sub_packets = int(''.join(bits[0:11]), 2)
51+
bits = bits[11:]
52+
for _ in range(num_sub_packets):
53+
sub_packet, bits = parse_packet(bits)
54+
self.sub_packets.append(sub_packet)
55+
return bits
56+
57+
def score(self):
58+
score = self.version
59+
for p in self.sub_packets:
60+
score += p.score()
61+
return score
62+
63+
def __str__(self):
64+
s = f"<{self.__class__.__name__}: version={self.version}, type={self.t}, sub_packets=[\n"
65+
for p in self.sub_packets:
66+
s += str(p) + "\n"
67+
s += ">"
68+
return s
69+
70+
71+
def parse_packet(bits):
72+
version = int(''.join(bits[0:3]), 2)
73+
bits = bits[3:]
74+
t = int(''.join(bits[0:3]), 2)
75+
bits = bits[3:]
76+
if t == 4:
77+
packet = Literal(version, t)
78+
else:
79+
packet = Operator(version, t)
80+
bits = packet.parse(bits)
81+
return (packet, bits)
82+
83+
84+
def parse_packets(bits):
85+
packets = []
86+
while not all(b == '0' for b in bits):
87+
packet, bits = parse_packet(bits)
88+
packets.append(packet)
89+
return packets
90+
91+
92+
lines = [list(line.strip()) for line in open('16.input').readlines()]
93+
packets = []
94+
for line in lines:
95+
binary = []
96+
for h in line:
97+
binary += list(format(int(h, 16), '0>4b'))
98+
packets.append(binary)
99+
100+
for p in packets:
101+
packet, _ = parse_packet(p)
102+
print(packet.score())

16-2.py

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
#!/usr/bin/env python
2+
3+
class Packet:
4+
def __init__(self, version, t):
5+
self.version = version
6+
self.t = t
7+
8+
def __str__(self):
9+
return f"<{self.__class__.__name__}: version={self.version}, type={self.t}>"
10+
11+
12+
class Literal(Packet):
13+
def __init__(self, version, t):
14+
super().__init__(version, t)
15+
self.data = -1
16+
17+
def parse(self, bits):
18+
b = ''
19+
while True:
20+
cont = int(bits[0])
21+
group = bits[1:5]
22+
bits = bits[5:]
23+
b += ''.join(group)
24+
if cont == 0:
25+
break
26+
self.data = int(b, 2)
27+
return bits
28+
29+
def score(self):
30+
return self.data
31+
32+
def __str__(self):
33+
return f"<{self.__class__.__name__}: version={self.version}, type={self.t}, data={self.data}>"
34+
35+
36+
class Operator(Packet):
37+
def __init__(self, version, t):
38+
super().__init__(version, t)
39+
self.sub_packets = []
40+
41+
def parse(self, bits):
42+
length_type_id = int(''.join(bits[0:1]))
43+
bits = bits[1:]
44+
if length_type_id == 0:
45+
sub_packet_length = int(''.join(bits[0:15]), 2)
46+
bits = bits[15:]
47+
self.sub_packets = parse_packets(bits[0:sub_packet_length])
48+
bits = bits[sub_packet_length:]
49+
elif length_type_id == 1:
50+
num_sub_packets = int(''.join(bits[0:11]), 2)
51+
bits = bits[11:]
52+
for _ in range(num_sub_packets):
53+
sub_packet, bits = parse_packet(bits)
54+
self.sub_packets.append(sub_packet)
55+
return bits
56+
57+
def __str__(self):
58+
s = f"<{self.__class__.__name__}: version={self.version}, type={self.t}, sub_packets=[\n"
59+
for p in self.sub_packets:
60+
s += str(p) + "\n"
61+
s += ">"
62+
return s
63+
64+
65+
class Sum(Operator):
66+
def score(self):
67+
return sum([p.score() for p in self.sub_packets])
68+
69+
70+
class Product(Operator):
71+
def score(self):
72+
score = 1
73+
for p in self.sub_packets:
74+
score *= p.score()
75+
return score
76+
77+
78+
class Minimum(Operator):
79+
def score(self):
80+
return min([p.score() for p in self.sub_packets])
81+
82+
83+
class Maximum(Operator):
84+
def score(self):
85+
return max([p.score() for p in self.sub_packets])
86+
87+
88+
class GreaterThan(Operator):
89+
def score(self):
90+
if self.sub_packets[0].score() > self.sub_packets[1].score():
91+
return 1
92+
else:
93+
return 0
94+
95+
96+
class LessThan(Operator):
97+
def score(self):
98+
if self.sub_packets[0].score() < self.sub_packets[1].score():
99+
return 1
100+
else:
101+
return 0
102+
103+
class EqualTo(Operator):
104+
def score(self):
105+
if self.sub_packets[0].score() == self.sub_packets[1].score():
106+
return 1
107+
else:
108+
return 0
109+
110+
111+
def parse_packet(bits):
112+
version = int(''.join(bits[0:3]), 2)
113+
bits = bits[3:]
114+
t = int(''.join(bits[0:3]), 2)
115+
bits = bits[3:]
116+
if t == 0:
117+
packet = Sum(version, t)
118+
if t == 1:
119+
packet = Product(version, t)
120+
if t == 2:
121+
packet = Minimum(version, t)
122+
if t == 3:
123+
packet = Maximum(version, t)
124+
if t == 4:
125+
packet = Literal(version, t)
126+
if t == 5:
127+
packet = GreaterThan(version, t)
128+
if t == 6:
129+
packet = LessThan(version, t)
130+
if t == 7:
131+
packet = EqualTo(version, t)
132+
bits = packet.parse(bits)
133+
return (packet, bits)
134+
135+
136+
def parse_packets(bits):
137+
packets = []
138+
while not all(b == '0' for b in bits):
139+
packet, bits = parse_packet(bits)
140+
packets.append(packet)
141+
return packets
142+
143+
144+
lines = [list(line.strip()) for line in open('16.input').readlines()]
145+
packets = []
146+
for line in lines:
147+
binary = []
148+
for h in line:
149+
binary += list(format(int(h, 16), '0>4b'))
150+
packets.append(binary)
151+
152+
for p in packets:
153+
packet, _ = parse_packet(p)
154+
print(packet.score())

0 commit comments

Comments
 (0)