Sean McLemon | Advent of Code

Home | Czech | Blog | GitHub | Advent Of Code | Notes


2017-12-12 - Digital Plumber

(original .ipynb)
test_input_str = """0 <-> 2
1 <-> 1
2 <-> 0, 3, 4
3 <-> 2, 4
4 <-> 2, 3, 6
5 <-> 6
6 <-> 4, 5"""

puzzle_input_str = open("puzzle_input/day12.txt").read()

def parse_input(input_str):
    lines = input_str.split("\n")
    for line in lines:
        program_str, connections_str = line.split(" <-> ")
        program = int(program_str)
        connections = [int(s) for s in connections_str.split(", ")]
        yield (program, connections)

def find_members(program, groups):
    visited = set()
    queue = [program]
    while len(queue) > 0:
        program = queue.pop(0)

        if program in visited:
            continue

        visited.add(program)
        queue += groups[program]
        
    return visited
        
def part_one(input_str):
    groups = {}
    connection_data = parse_input(input_str)
    for program, connections in connection_data:
        groups[program] = connections

    return len(find_members(0, groups))
    
assert 6 == part_one(test_input_str)

print("part one:", part_one(puzzle_input_str))
part one: 169
def part_two(input_str):
    connection_data = list(parse_input(input_str))
    groups = {}
    
    for program, connections in connection_data:
        groups[program] = connections
        
    all_visited = set()
    total_groups = 0
    for program, connections in connection_data:
        if program in all_visited:
            continue
        all_visited.update(find_members(program, groups))
        total_groups += 1
    
    return total_groups

assert 2 == part_two(test_input_str)
print("part two:", part_two(puzzle_input_str))
part two: 179