Digital Plumber

Part 1


In [45]:
import csv
from collections import defaultdict

def parse(input_path):
    pipes = defaultdict(set)
    with open(input_path, 'rt') as f_input:
        csv_reader = csv.reader(f_input, delimiter=' ')
        for l in csv_reader:
            pipes[int(l[0])] = set([int(n.rstrip(',')) for n in l[2:]])
    for k in pipes:
        for n in pipes[k]:
            pipes[n].add(k)
    return pipes

def connected(node, pipes):
    neighbors = pipes[node]
    pending = list(neighbors)
    while pending:
        alice = pending.pop(0)
        for bob in pipes[alice]:
            if bob in neighbors:
                pass
            else:
                neighbors.add(bob)
                pending.append(bob)
    return neighbors

def length_neighborhood(input_path, node):
    pipes = parse(input_path)
    return len(connected(node, pipes))

Test


In [53]:
assert(length_neighborhood('input.test1.txt', 0) == 6)

Solution


In [47]:
length_neighborhood('input.txt', 0)


Out[47]:
141

Part 2


In [51]:
def no_groups(input_path):
    pipes = parse(input_path)
    covered = set()
    group_count = 0
    for node in pipes:
        if node not in covered:
            neighbors = connected(node, pipes)
            covered = covered.union(neighbors)
            group_count += 1
    return group_count

Test


In [54]:
assert(no_groups('input.test1.txt') == 2)

Solution


In [55]:
no_groups('input.txt')


Out[55]:
171