<filename>2020/day16.py<gh_stars>0
import re

class solve_day(object):

    with open('inputs/day16.txt', 'r') as f:
        data = f.readlines()
        data = [d.strip() for d in data]


    def part1(self):

        my_ticket_idx_start = [i for i,x in enumerate(self.data) if 'your ticket' in x][0]

        fields = []
        fields.append([x for i,x in enumerate(self.data) if i < my_ticket_idx_start-1])
        fields = fields[0]

        nearby_tickets = [x for i,x in enumerate(self.data) if i>my_ticket_idx_start+3]
        nearby_tickets = [x.split(',') for x in nearby_tickets]

        field_dict = {}

        for field in fields:
            field_split = field.split(':')

            # get ranges
            first_range = field_split[1][[x.start() for x in re.finditer(' ', field_split[1])][0]+1:[x.start() for x in re.finditer(' ', field_split[1])][1]]
            second_range = field_split[1][[x.start() for x in re.finditer(' ', field_split[1])][2]+1:]

            range_list = []

            for r in [first_range, second_range]:
                range_list.append([r[:[x.start() for x in re.finditer('-', r)][0]], r[[x.start() for x in re.finditer('-', r)][0]+1:]])

            # get the field name and add to dict
            field_dict[field_split[0][:-1]] = range_list

        invalid_ticket_values = []

        all_range_checks = [r for ranges in [x for x in field_dict.values()] for r in ranges]

        for ticket in nearby_tickets:
            for ticket_value in ticket:
                check_count = 0
                for check in all_range_checks:
                    if int(ticket_value) >= int(check[0]) and int(ticket_value) <= int(check[1]):
                        check_count += 1
                if check_count == 0:
                    invalid_ticket_values.append(ticket_value)

        return sum([int(x) for x in invalid_ticket_values])


    def part2(self):

        my_ticket_idx_start = [i for i,x in enumerate(self.data) if 'your ticket' in x][0]

        fields = []
        fields.append([x for i,x in enumerate(self.data) if i < my_ticket_idx_start-1])
        fields = fields[0]

        my_ticket = [x for i,x in enumerate(self.data) if i>my_ticket_idx_start and i <= my_ticket_idx_start+1]

        nearby_tickets = [x for i,x in enumerate(self.data) if i>my_ticket_idx_start+3]
        nearby_tickets = [x.split(',') for x in nearby_tickets]

        # print(fields)
        # print(my_ticket)
        # print(nearby_tickets)

        field_dict = {}

        for field in fields:
            field_split = field.split(':')

            # print(field_split[0], field_split[1])

            # get ranges
            first_range = field_split[1][[x.start() for x in re.finditer(' ', field_split[1])][0]+1:[x.start() for x in re.finditer(' ', field_split[1])][1]]
            second_range = field_split[1][[x.start() for x in re.finditer(' ', field_split[1])][2]+1:]

            range_list = []

            for r in [first_range, second_range]:
                try:
                    range_list.append([r[:[x.start() for x in re.finditer('-', r)][0]], r[[x.start() for x in re.finditer('-', r)][0]+1:]])
                except:
                    print(f'error: {r}')


            # get the field name and add to dict
            field_dict[field_split[0][:-1]] = range_list


        invalid_ticket_idx = []

        all_range_checks = [r for ranges in [x for x in field_dict.values()] for r in ranges]

        # exclude tickets with invalid
        for i, ticket in enumerate(nearby_tickets):
            # print(f'ticket: {ticket}, idx: {i}')
            for ticket_value in ticket:
                # print(f'ticket_value: {ticket_value}')
                check_count = 0
                for check in all_range_checks:
                    # print(f'check: {check}')
                    if int(ticket_value) >= int(check[0]) and int(ticket_value) <= int(check[1]):
                        check_count += 1
                if check_count == 0:
                    invalid_ticket_idx.append(i)

        # print(invalid_ticket_idx)

        # keep valid tickets
        valid_tickets = [x for i,x in enumerate(nearby_tickets) if i not in invalid_ticket_idx]

        # print(len(nearby_tickets))
        # print(len(invalid_ticket_idx))
        # print(len(valid_tickets))

        
        


        return 0


if __name__ == '__main__':
    s = solve_day()

    # print(f'Part 1: {s.part1()}')
    print(f'Part 2: {s.part2()}')