1234567891011121314151617181920212223242526272829303132333435 |
- #!/usr/bin/python3
-
- """Solution for day 20 of Advent of Code 2016.
-
- This solution first compresses the blacklist by merging overlapping sections, using functools.reduce and the merge
- function below. For example, [(0, 100), (50, 150)] becomes (0, 150). The blacklist is then inverted to become a
- whitelist, which gives both answers pretty easily.
- """
-
- import functools
-
- def merge(x, y):
- if y[0] <= x[-1][1] + 1:
- # This entry overlaps with the last one, combine them
- x[-1] = (x[-1][0], max(y[1], x[-1][1]))
- else:
- # New, non-overlapping entry, just append it to our list
- x.append(y)
- return x
-
- with open('data/20.txt', 'r') as file:
- ranges = sorted(list(map(lambda x: tuple(map(int, x.strip().split('-'))), file.readlines())))
- blacklist = functools.reduce(merge, ranges[1:], [ranges[0]])
-
- whitelist = []
- last = 0
- for pair in blacklist:
- if pair[0] > last:
- whitelist.append((last, pair[0] - 1))
- last = pair[1] + 1
- if last < 4294967295:
- whitelist.append((last, 4294967295))
-
- print("Part 1: %s" % whitelist[0][0])
- print("Part 2: %s" % sum(map(lambda p: 1 + p[1] - p[0], whitelist)))
|