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