Skip to content

Commit b7cbfa1

Browse files
author
Joe Webster
committed
Adding day 16 part 2... stupid boolean logic and off by one errors... probabyl. Whatever a star is a star
1 parent 2d017eb commit b7cbfa1

File tree

3 files changed

+143
-30
lines changed

3 files changed

+143
-30
lines changed

Diff for: 16/__init__.py

+121-30
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1+
import pprint
2+
3+
import sys
4+
sys.path.append('..')
5+
6+
import lib.text
7+
18
class BITSPacketDecoder(object):
29
def __init__(self, packet):
310
self.packet = packet
411
self.bits = self.hex2bin(self.packet)
12+
self.bit_labels = ''
513
self.index = 0
614

715
def hex2bin(self, hex_string):
@@ -15,24 +23,29 @@ def bits_left(self):
1523
ret = len(self.bits) - self.index
1624
return ret
1725

18-
def read(self, read_len):
26+
def read(self, read_len, bit_label):
1927
if self.bits_left() < read_len:
2028
print("read underrun")
2129
return None
2230

2331
ret = self.bits[self.index:self.index+read_len]
2432

25-
#print(self.bits)
26-
#print(' ' * self.index + '*' * read_len + ' = ' + ret + ' (' + str(int(ret, 2)) + ')')
27-
#print()
33+
preview_width = 60
34+
skip = max(self.index - preview_width, 0)
35+
36+
print(self.bits[skip:skip+preview_width*2])
37+
print(self.bit_labels[skip:] + lib.text.bcolor('green', bit_label * read_len) + " -> %s (dec %s)" % (ret, str(int(ret, 2))))
38+
print()
39+
40+
self.bit_labels += bit_label * read_len
2841

2942
self.index += read_len
3043

3144
return ret
3245

3346
def read_packet(self):
34-
version = int(self.read(3), 2)
35-
type_id = int(self.read(3), 2)
47+
version = int(self.read(3, 'V'), 2)
48+
type_id = int(self.read(3, 'T'), 2)
3649

3750
print('version: %s type_id: %s' % (version, type_id))
3851

@@ -47,28 +60,38 @@ def parse_payload_4(self, version, type_id):
4760
bit_string = ""
4861
more = 1
4962
while more:
50-
more = int(self.read(1))
51-
bit_string += self.read(4)
63+
more = int(self.read(1, 'n'))
64+
bit_string += self.read(4, 'N')
5265

5366
return {'version': version, 'type_id': type_id, 'literal': int(bit_string, 2)}
5467

5568
def parse_payload_op(self, version, type_id):
5669
subpackets = []
5770

58-
length_type_id = int(self.read(1))
71+
length_type_id = int(self.read(1, 'I'))
72+
73+
subpacket_length = None
74+
subpacket_count = None
5975

6076
if length_type_id == 0:
61-
subpacket_length = int(self.read(15), 2)
77+
subpacket_length = int(self.read(15, 'L'), 2)
78+
bit_stop = self.index + subpacket_length
6279
elif length_type_id == 1:
63-
subpacket_count = int(self.read(11), 2)
80+
subpacket_count = int(self.read(11, 'C'), 2)
81+
82+
packet_count = 0
83+
while (
84+
(subpacket_count and packet_count < subpacket_count)
85+
or
86+
(subpacket_length and self.index < bit_stop)
87+
) and self.bits_left() >= 11:
6488

65-
while self.bits_left() > 12:
6689
subpacket = self.read_packet()
90+
packet_count += 1
6791
if subpacket:
6892
subpackets.append(subpacket)
6993
else:
70-
print("no subpacket?, breaking")
71-
break
94+
raise ValueError('no subpacket when expecting subpacket')
7295

7396
return {'version': version, 'type_id': type_id, 'subpackets': subpackets}
7497

@@ -89,15 +112,79 @@ def get_version_sum(self, packet):
89112

90113
return version_sum
91114

92-
def parse_packets(self, data):
93-
print(data)
94-
bd = BITSPacketDecoder(data)
95-
print(bd.bits)
96-
print()
115+
def evaluate_packet(self, packet, depth=0):
116+
type_id = packet['type_id']
117+
118+
if type_id == 4 and 'subpackets' in packet:
119+
raise ValueError('WTF')
120+
121+
if type_id == 4:
122+
return packet['literal']
123+
124+
if 'subpackets' in packet:
125+
values = []
126+
for subpacket in packet['subpackets']:
127+
values.append(self.evaluate_packet(subpacket, depth+1))
128+
129+
print((' ' * depth) + str(depth) + ' eval %s of %s' % (type_id, values))
130+
131+
if type_id == 0:
132+
ret = sum(values)
133+
print("sum %s = %s" % (values, ret))
134+
return ret
135+
elif type_id == 1:
136+
product = 1
137+
for v in values:
138+
product *= v
139+
print("product %s = %s" % (values, product))
140+
return product
141+
elif type_id == 2:
142+
ret = min(values)
143+
print("min %s = %s" % (values, ret))
144+
return ret
145+
elif type_id == 3:
146+
ret = max(values)
147+
print("max %s = %s" % (values, ret))
148+
return ret
149+
elif type_id == 4:
150+
raise ValueError("WTF srsly")
151+
elif type_id == 5:
152+
ret = 1 if values[0] > values[1] else 0
153+
print("%s gt %s = %s" % (values[0], values[1], ret))
154+
return ret
155+
elif type_id == 6:
156+
ret = 1 if values[0] < values[1] else 0
157+
print("%s lt %s = %s" % (values[0], values[1], ret))
158+
return ret
159+
elif type_id == 7:
160+
ret = 1 if values[0] == values[1] else 0
161+
print("%s eq %s = %s" % (values[0], values[1], ret))
162+
return ret
163+
else:
164+
raise ValueError('Unknown type_id %s' % type_id)
165+
166+
print('mystery packet')
167+
pprint.pprint(packet)
168+
raise ValueError('WTF')
97169

98-
packets = bd.read_packet()
170+
def parse_packets(self, transmissions):
171+
ret = {}
172+
for transmission in transmissions:
173+
print(transmission)
99174

100-
return packets
175+
bd = BITSPacketDecoder(transmission)
176+
177+
parsed_transmission = bd.read_packet()
178+
print(parsed_transmission)
179+
180+
if bd.bits_left():
181+
leftovers = bd.read(bd.bits_left(), 'x')
182+
if int(leftovers):
183+
raise ValueError("Left bits on the table: %s" % leftovers)
184+
185+
ret.update({transmission: parsed_transmission})
186+
187+
return ret
101188

102189
def get_data():
103190
return [l.rstrip() for l in open('data.txt', 'r').readlines()]
@@ -108,20 +195,24 @@ def get_test_data():
108195
def solution_part_1(data):
109196
bits = BITS()
110197
bits.load_data(data)
111-
packets = bits.parse_packets(data)
112-
version_sum = bits.get_version_sum(packets)
113-
print('version_sum', version_sum)
198+
parsed_transmissions = bits.parse_packets(data)
199+
200+
for transmission, parsed_transmission in parsed_transmissions.items():
201+
version_sum = bits.get_version_sum(parsed_transmission)
202+
print('version_sum', version_sum)
114203

115204
def solution_part_2(data):
116205
bits = BITS()
117206
bits.load_data(data)
118-
packets = bits.parse_packets(data)
119-
result = bits.evaluate_packets(packets)
120-
print('eval results', result)
207+
parsed_transmissions = bits.parse_packets(data)
208+
for transmission, parsed_transmission in parsed_transmissions.items():
209+
print(transmission)
210+
result = bits.evaluate_packet(parsed_transmission)
211+
print('eval results', result)
121212

122213
if __name__ == '__main__':
123-
solution_part_1(get_test_data())
124-
solution_part_1(get_data())
214+
#solution_part_1(get_test_data())
215+
#solution_part_1(get_data())
125216

126217
#solution_part_2(get_test_data())
127-
#solution_part_2(get_data())
218+
solution_part_2(get_data())

Diff for: 16/test_data.txt

+8
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,11 @@ EE00D40C823060
55
620080001611562C8802118E34
66
C0015000016115A2E0802F182340
77
A0016C880162017C3686B18A3D4780
8+
C200B40A82
9+
04005AC33890
10+
880086C3E88112
11+
CE00C43D881120
12+
D8005AC2A8F0
13+
F600BC2D8F
14+
9C005AC2F8F0
15+
9C0141080250320F1802104A08

Diff for: lib/text/__init__.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
def bcolor(color, text):
2+
colors = {
3+
'bred': '\033[31;1m',
4+
'redbg': '\033[41m',
5+
'red': '\033[91m',
6+
'green': '\033[92m',
7+
'greenbg': '\033[42m',
8+
'yellow': '\033[93m',
9+
'blue': '\033[94m',
10+
'bluebg': '\033[44m',
11+
'reset': '\033[0m'
12+
}
13+
14+
return colors[color] + str(text) + colors['reset']

0 commit comments

Comments
 (0)