Day 16 2020 - this has debugging prints allllll over the place!
[advent-of-code-2020.git] / day16 / tt.py
diff --git a/day16/tt.py b/day16/tt.py
new file mode 100755 (executable)
index 0000000..96d3781
--- /dev/null
@@ -0,0 +1,134 @@
+#!/usr/bin/python3
+
+import sys
+
+filename="p1_71.txt"
+if len(sys.argv) > 1:
+    filename=sys.argv[1]
+
+rules={}
+myticket=[]
+tickets=[]
+inrules=True
+inmyticket=False
+intickets=False
+
+for line in open(filename, "r"):
+    line=line.rstrip()
+
+    # skip blank lines
+    if line == '':
+        continue
+
+    if line == 'your ticket:':
+        inrules=False
+        inmyticket=True
+        continue
+    elif line == 'nearby tickets:':
+        inmyticket=False
+        intickets=True
+        continue
+
+    # we've got a line of data - woo!
+    if inrules:
+        (rule,data) = line.split(": ")
+        ranges = [[int(a) for a in rule.split("-")] for rule in data.split(" or ")]
+        rules[rule]=ranges
+        continue
+
+    if inmyticket:
+        myticket=[int(a) for a in line.split(",")]
+        continue
+
+    if intickets:
+        tickets.append([int(a) for a in line.split(",")])
+
+def check_rules(value):
+    for rule in rules.keys():
+        for valrange in rules[rule]:
+            if value >= valrange[0] and value <= valrange[1]:
+                return True
+    return False
+
+def get_invalid_fields(ticket):
+    invalid_fields=[]
+    for point in ticket:
+        if not check_rules(point):
+            invalid_fields.append(point)
+
+    return invalid_fields
+
+print("Rules: ")
+print(rules)
+print("My ticket: ", ",".join([str(a) for a in myticket]))
+print("Nearby tickets:")
+bad_fields=[]
+valid_tickets=[]
+
+for ticket in tickets:
+    print(",".join([str(a) for a in ticket]))
+    ticket_bad_fields=get_invalid_fields(ticket)
+    if len(ticket_bad_fields) > 0:
+        bad_fields.extend(ticket_bad_fields)
+    else:
+        valid_tickets.append(ticket)
+
+print("Part 1:", sum(bad_fields))
+
+possible_fields=[[k for k in rules.keys()] for i in range(len(myticket))]
+
+def check_field(field, ranges):
+    print("Field:", field,"\nRanges:", ranges)
+    for valrange in ranges:
+        if field >= valrange[0] and field <= valrange[1]:
+            return True
+
+    return False
+
+def check_fields(possible_fields, ticket):
+    print("Check Possible fields:",possible_fields)
+    print("Check ticket:", ticket)
+    for number,field in enumerate(ticket):
+        new_possibles=[]
+        print(possible_fields[number])
+        for possible_rule in possible_fields[number]:
+            print("Possible rule:", possible_rule)
+            ranges=rules[possible_rule]
+            print("Ranges:", ranges)
+            if check_field(field, ranges):
+                new_possibles.append(possible_rule)
+        possible_fields[number]=new_possibles
+
+print(possible_fields)
+
+for ticket in valid_tickets:
+    print(possible_fields)
+    print(ticket)
+    print(rules)
+    check_fields(possible_fields, ticket)
+    if sum([len(fields) for fields in possible_fields]) == len(myticket):
+        # we have all the fields, lets break from our loop
+        break
+
+# loop until we only have one possible for each field
+while sum([len(fields) for fields in possible_fields]) != len(myticket):
+    for a,fields in enumerate(possible_fields):
+        if len(fields) == 1:
+            continue
+        else:
+            for b,fields2 in enumerate(possible_fields):
+                if len(fields2) == 1:
+                    if fields2[0] in fields:
+                        fields.remove(fields2[0])
+                        break
+
+print(possible_fields)
+actual_fields=[f[0] for f in possible_fields]
+
+# loop through the fields that have 'departure' at the start
+mult=1
+for a,field in enumerate(actual_fields):
+    if field[:9] == "departure":
+        mult*=myticket[a]
+
+print("Part 2:", mult)