--- /dev/null
+#!/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)