123456789101112131415161718192021222324252627 |
- #!/usr/bin/python3
-
- """Solution for day 13 of Advent of Code 2016.
-
- Performs a breadth-first search of the maze, for up to 100 steps. Distances of each square are kept in a dictionary,
- which is also used to prevent back-tracking.
- """
-
- import itertools
-
- input = 1364
-
- high = lambda x: sum([1 for d in bin(x) if d == '1'])
- wall = lambda x, y: high(x*x + 3*x + 2*x*y + y + y*y + input) % 2 == 1
- all_moves = lambda x, y: [(x-1, y), (x+1, y), (x, y-1), (x, y+1)]
- moves = lambda x, y: (m for m in all_moves(x, y) if m[0] >= 0 and m[1] >= 0 and not wall(*m))
- queue = {(1, 1)}
- distance = {}
-
- for step in range(100):
- # Merge in all the new distances from the queue, if they're not present
- distance = dict(list(distance.items()) + list(dict.fromkeys(queue, step).items()))
- # Calculate all moves from all places in the queue, and skip any places we've already visited
- queue = set(itertools.chain.from_iterable(moves(*c) for c in queue)) - set(distance.keys())
-
- print("Part 1: %s" % distance[(31, 39)])
- print("Part 2: %s" % sum(1 for s in distance.values() if s <= 50))
|