Ejemplo n.º 1
0
def part_one():
    with open('data.txt', 'r') as f:
        data = f.read()

    fields, your_ticket, nearby_tickets = data.split('\n\n')

    # Build dictionary of fields and valid ranges
    all_ranges = RangeSet()
    fields = fields.split('\n')
    fields_dict = {}
    for field_line in fields:
        field_name, field_ranges = field_line.split(':')
        field_ranges = field_ranges.split('or')
        for field_range in field_ranges:
            if field_name in fields_dict:
                fields_dict[field_name] = fields_dict[field_name].union(
                    RangeSet(field_range))
            else:
                fields_dict[field_name] = RangeSet(field_range)
            all_ranges = all_ranges.union(RangeSet(field_range))

    # Nearby tickets
    part_one_answer = 0
    nearby_tickets = nearby_tickets.split('\n')[1:]
    for ticket in nearby_tickets:
        for field_value in ticket.split(','):
            if field_value not in all_ranges:
                part_one_answer += int(field_value)

    return part_one_answer
Ejemplo n.º 2
0
 def testUnion(self):
     """test RangeSet.union()"""
     r1 = RangeSet("1-100,102,105-242,800")
     self.assertEqual(len(r1), 240)
     r2 = RangeSet("243-799,1924-1984")
     self.assertEqual(len(r2), 618)
     r3 = r1.union(r2)
     self.assertEqual(type(r3), RangeSet)
     self.assertEqual(r3.padding, None)
     self.assertEqual(len(r3), 240 + 618)
     self.assertEqual(str(r3), "1-100,102,105-800,1924-1984")
     r4 = r1 | r2
     self.assertEqual(len(r4), 240 + 618)
     self.assertEqual(str(r4), "1-100,102,105-800,1924-1984")
     # test with overlap
     r2 = RangeSet("200-799")
     r3 = r1.union(r2)
     self.assertEqual(len(r3), 797)
     self.assertEqual(str(r3), "1-100,102,105-800")
     r4 = r1 | r2
     self.assertEqual(len(r4), 797)
     self.assertEqual(str(r4), "1-100,102,105-800")
Ejemplo n.º 3
0
 def testUnion(self):
     """test RangeSet.union()"""
     r1 = RangeSet("1-100,102,105-242,800")
     self.assertEqual(len(r1), 240)
     r2 = RangeSet("243-799,1924-1984")
     self.assertEqual(len(r2), 618)
     r3 = r1.union(r2)
     self.assertEqual(type(r3), RangeSet)
     self.assertEqual(r3.padding, None)
     self.assertEqual(len(r3), 240+618) 
     self.assertEqual(str(r3), "1-100,102,105-800,1924-1984")
     r4 = r1 | r2
     self.assertEqual(len(r4), 240+618) 
     self.assertEqual(str(r4), "1-100,102,105-800,1924-1984")
     # test with overlap
     r2 = RangeSet("200-799")
     r3 = r1.union(r2)
     self.assertEqual(len(r3), 797)
     self.assertEqual(str(r3), "1-100,102,105-800")
     r4 = r1 | r2
     self.assertEqual(len(r4), 797)
     self.assertEqual(str(r4), "1-100,102,105-800")
Ejemplo n.º 4
0
def part_two():
    with open('data.txt', 'r') as f:
        data = f.read()

    fields, your_ticket, nearby_tickets = data.split('\n\n')

    # Build dictionary of fields and valid ranges
    all_ranges = RangeSet()
    fields = fields.split('\n')
    for field_line in fields:
        field_name, field_ranges = field_line.split(':')
        field_ranges = field_ranges.split('or')
        for field_range in field_ranges:
            if field_name in fields_dict:
                fields_dict[field_name]['range'] = fields_dict[field_name][
                    'range'].union(RangeSet(field_range))
            else:
                fields_dict[field_name] = {
                    'range': RangeSet(field_range),
                    'possible_indexes': []
                }
            all_ranges = all_ranges.union(RangeSet(field_range))

    # Nearby tickets
    valid_tickets = []
    nearby_tickets = nearby_tickets.split('\n')[1:]
    for ticket in nearby_tickets:
        all_fields_ok = True
        for field_value in ticket.split(','):
            if field_value not in all_ranges:
                all_fields_ok = False
        if all_fields_ok:
            valid_tickets.append([int(x) for x in ticket.split(',')])

    # Include own ticket to valid_tickets
    your_ticket = [int(x) for x in your_ticket.split('\n')[1].split(',')]
    valid_tickets.append(your_ticket)

    # pprint(valid_tickets, width=120)

    for field in fields_dict:
        for i in range(len(your_ticket)):
            # is field valid for all tickets index i?
            field_valid_for_all = True
            for valid_ticket in valid_tickets:
                if valid_ticket[i] not in fields_dict[field]['range']:
                    field_valid_for_all = False
                    break
            if field_valid_for_all:
                fields_dict[field]['possible_indexes'].append(i)

    pprint(fields_dict, width=120)

    solution = solve(fields_dict.keys(), is_solution_valid,
                     len(fields_dict.keys()))

    result = 1
    for i in range(len(solution)):
        if solution[i].startswith('departure'):
            result *= your_ticket[i]

    return result