-
Notifications
You must be signed in to change notification settings - Fork 0
/
13.py
executable file
·92 lines (78 loc) · 2.55 KB
/
13.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/python3
# run it as
# ./13.py inputs/13 [--one | --two] [--debug]
import sys
import logging
from itertools import zip_longest
from functools import total_ordering
import math
if '--debug' in sys.argv:
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger()
EXTRA_PACKETS = [[[2]], [[6]]]
def gimme_pairs():
with open(sys.argv[1]) as f:
return zip(*[(eval(line.strip()) for line in f.readlines() if line.strip())]*2)
def gimme_packets():
with open(sys.argv[1]) as f:
return (eval(line.strip()) for line in f.readlines() if line.strip())
@total_ordering
class Packet:
def __init__(self, value):
self.value = value
def __eq__(self, other):
# is this even approved by Vatican?
return str(self.value) == str(other.value)
def __lt__(self, other):
comp = compare(self.value, other.value)
assert comp is not None
return comp
def __repr__(self):
return repr(self.value)
def compare(left, right):
"""
there probably is some cool math optimization to avoid all these steps
"""
logger.info(f'left is {left}, right is {right}')
if left is None:
return True
elif right is None:
return False
if type(left) == type(right) == list:
# zip_longest puts "None" when out of items
for pair in zip_longest(left, right):
comp = compare(*pair)
logger.info(comp)
if comp is not None:
return comp
if type(left) != type(right):
if type(left) == int:
left = [left]
elif type(right) == int:
right = [right]
return compare(left, right)
if type(left) == type(right) == int:
if left < right:
return True
elif left > right:
return False
else:
return None
if __name__ == '__main__':
if '--one' in sys.argv:
indexes = []
for index, pair in enumerate(gimme_pairs(), start=1):
logger.info(pair)
if Packet(pair[0]) < Packet(pair[1]):
indexes.append(index)
print('part one answer:', sum(indexes))
if '--two' in sys.argv:
packets = list(gimme_packets())
for _ in EXTRA_PACKETS:
packets.append(_)
indexes = []
for index, packet in enumerate(sorted([Packet(x) for x in packets]), start=1):
logger.error(f'{index}, {packet}')
if packet.value in EXTRA_PACKETS:
indexes.append(index)
print('part two answer:', math.prod(indexes))