Day 16 2020 - this has debugging prints allllll over the place!
[advent-of-code-2020.git] / day16 / tt.py
1 #!/usr/bin/python3
2
3 import sys
4
5 filename="p1_71.txt"
6 if len(sys.argv) > 1:
7     filename=sys.argv[1]
8
9 rules={}
10 myticket=[]
11 tickets=[]
12 inrules=True
13 inmyticket=False
14 intickets=False
15
16 for line in open(filename, "r"):
17     line=line.rstrip()
18
19     # skip blank lines
20     if line == '':
21         continue
22
23     if line == 'your ticket:':
24         inrules=False
25         inmyticket=True
26         continue
27     elif line == 'nearby tickets:':
28         inmyticket=False
29         intickets=True
30         continue
31
32     # we've got a line of data - woo!
33     if inrules:
34         (rule,data) = line.split(": ")
35         ranges = [[int(a) for a in rule.split("-")] for rule in data.split(" or ")]
36         rules[rule]=ranges
37         continue
38
39     if inmyticket:
40         myticket=[int(a) for a in line.split(",")]
41         continue
42
43     if intickets:
44         tickets.append([int(a) for a in line.split(",")])
45
46 def check_rules(value):
47     for rule in rules.keys():
48         for valrange in rules[rule]:
49             if value >= valrange[0] and value <= valrange[1]:
50                 return True
51     return False
52
53 def get_invalid_fields(ticket):
54     invalid_fields=[]
55     for point in ticket:
56         if not check_rules(point):
57             invalid_fields.append(point)
58
59     return invalid_fields
60
61 print("Rules: ")
62 print(rules)
63 print("My ticket: ", ",".join([str(a) for a in myticket]))
64 print("Nearby tickets:")
65 bad_fields=[]
66 valid_tickets=[]
67
68 for ticket in tickets:
69     print(",".join([str(a) for a in ticket]))
70     ticket_bad_fields=get_invalid_fields(ticket)
71     if len(ticket_bad_fields) > 0:
72         bad_fields.extend(ticket_bad_fields)
73     else:
74         valid_tickets.append(ticket)
75
76 print("Part 1:", sum(bad_fields))
77
78 possible_fields=[[k for k in rules.keys()] for i in range(len(myticket))]
79
80 def check_field(field, ranges):
81     print("Field:", field,"\nRanges:", ranges)
82     for valrange in ranges:
83         if field >= valrange[0] and field <= valrange[1]:
84             return True
85
86     return False
87
88 def check_fields(possible_fields, ticket):
89     print("Check Possible fields:",possible_fields)
90     print("Check ticket:", ticket)
91     for number,field in enumerate(ticket):
92         new_possibles=[]
93         print(possible_fields[number])
94         for possible_rule in possible_fields[number]:
95             print("Possible rule:", possible_rule)
96             ranges=rules[possible_rule]
97             print("Ranges:", ranges)
98             if check_field(field, ranges):
99                 new_possibles.append(possible_rule)
100         possible_fields[number]=new_possibles
101
102 print(possible_fields)
103
104 for ticket in valid_tickets:
105     print(possible_fields)
106     print(ticket)
107     print(rules)
108     check_fields(possible_fields, ticket)
109     if sum([len(fields) for fields in possible_fields]) == len(myticket):
110         # we have all the fields, lets break from our loop
111         break
112
113 # loop until we only have one possible for each field
114 while sum([len(fields) for fields in possible_fields]) != len(myticket):
115     for a,fields in enumerate(possible_fields):
116         if len(fields) == 1:
117             continue
118         else:
119             for b,fields2 in enumerate(possible_fields):
120                 if len(fields2) == 1:
121                     if fields2[0] in fields:
122                         fields.remove(fields2[0])
123                         break
124
125 print(possible_fields)
126 actual_fields=[f[0] for f in possible_fields]
127
128 # loop through the fields that have 'departure' at the start
129 mult=1
130 for a,field in enumerate(actual_fields):
131     if field[:9] == "departure":
132         mult*=myticket[a]
133
134 print("Part 2:", mult)