Part 1: Given a map of the form:
###########
#0.1…..2#
#.#######.#
#4…….3#
###########
> Find the shortest route to visit each of the points, starting at `0`.
First, we want to take the map that we were given and simplify it. We know that we want to visit all of the points, so lets take the original map and turn it just into a map of distances between any two named points.
```python
walls = set()
name_to_point = {}
point_to_name = {}
# Load the input file into a set of walls and the location of points of interest
for y, line in enumerate(fileinput.input(args.files)):
for x, c in enumerate(line.strip()):
if c.isdigit():
name_to_point[int(c)] = (x, y)
point_to_name[(x, y)] = int(c)
elif c == '#':
walls.add((x, y))
# Dynamically fill a distance map to a given point
def distances_to(name):
to_scan = queue.Queue()
to_scan.put((name_to_point[name], 0))
scanned = set()
result = {}
while not to_scan.empty():
point, distance = to_scan.get()
if point in point_to_name:
name = point_to_name[point]
if name not in result:
result[name] = distance
if point in scanned:
continue
else:
scanned.add(point)
x, y = point
for xd, yd in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
neighbor = (x + xd, y + yd)
if neighbor not in walls:
to_scan.put((neighbor, distance + 1))
return result
distances = {
name: distances_to(name)
for name in name_to_point
}
names = list(sorted(name_to_point.keys()))
The first part loads the map and the second part will flood fill out from each point. This will find the minimum distance from each named point to the given one, somewhat simplifying the problem.
read more...