Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import re
- import sys
- from pprint import pprint
- def advent_day25_part1(filestr):
- field = [x for x in filestr.split('\n') if x]
- nrows, ncols = len(field), len(field[0])
- connections = {}
- for line in field:
- m = re.split(r'[: ]+', line)
- x = m[0]
- for y in m[1:]:
- connections.setdefault(x, set()).add(y)
- connections.setdefault(y, set()).add(x)
- def group(item, ignore=set()):
- visited = set()
- q = [item]
- while q:
- i = q.pop()
- if i in visited:
- continue
- visited.add(i)
- for j in connections[i]:
- segment = (min(i, j), max(i, j))
- if segment not in ignore:
- q.append(j)
- return visited
- def walkspan(start):
- q = [(start, tuple())]
- span = {}
- while q:
- item, path = q.pop(0)
- if item in span:
- continue
- path += (item,)
- if len(path) > 1:
- span[item] = path
- for child in connections[item]:
- q.append((child, path))
- return span
- spans = {}
- for item in connections.keys():
- spans[item] = walkspan(item)
- def countworn(spans):
- worn = {}
- for span in spans.values():
- for route in span.values():
- n0 = route[0]
- for n1 in route[1:]:
- p = (min(n0, n1), max(n0, n1))
- if p in worn:
- worn[p] += 1
- else:
- worn[p] = 1
- n0 = n1
- return worn
- worn = countworn(spans)
- worn_ranked = sorted(worn.items(), key=lambda x: -x[1])
- ignore = set(x[0] for x in worn_ranked[:3])
- print('num nodes', len(connections))
- print('top 10 visited segments')
- pprint(worn_ranked[:10])
- print('cuts', ignore)
- g1 = group(worn_ranked[0][0][0], ignore)
- g2 = group(worn_ranked[0][0][1], ignore)
- print('group 1 size', len(g1))
- print('group 2 size', len(g2))
- print('product', len(g1) * len(g2))
- def readfile(file_path):
- with open(file_path, 'r') as file:
- return file.read()
- if __name__ == '__main__':
- if len(sys.argv) >= 2:
- filestr = readfile(sys.argv[1])
- else:
- filestr = ''
- advent_day25_part1(filestr)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement