X-Git-Url: https://git.sommitrealweird.co.uk/advent-of-code-2020.git/blobdiff_plain/a3646324ce6a3441425f24c318df246b610f529d..3aa6b63e97b8dac07ff655a8c40595b2cecb6753:/day16/tt.py diff --git a/day16/tt.py b/day16/tt.py new file mode 100755 index 0000000..96d3781 --- /dev/null +++ b/day16/tt.py @@ -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)