-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathadvent_of_code_13.py
More file actions
77 lines (58 loc) · 2.24 KB
/
advent_of_code_13.py
File metadata and controls
77 lines (58 loc) · 2.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
my_input = 1358
test_input = 10
current_location = (1, 1)
def f(x, y):
return x * x + 3 * x + 2 * x * y + y + y * y
def get_field_type(x, y, magic_number):
assert x >= 0 and y >= 0
val = f(x, y) + magic_number
bin_val = bin(val)[2:] # binary in python starts with 0b...
number_of_ones = len(filter(lambda x: x == '1', list(bin_val)))
if number_of_ones % 2 == 0:
return "."
else:
return "#"
def get_neighbours(x, y):
return (x + 1, y), (x - 1, y), (x, y - 1), (x, y + 1)
def can_step_on(x, y, magic_number):
if x < 0 or y < 0:
return False
return get_field_type(x, y, magic_number) != "#"
def find_path_in_maze(start, end, magic_number):
if get_field_type(start[0], start[1], magic_number) == "#" or \
get_field_type(end[0], end[1], magic_number) == "#":
return []
queue = [(start, [start])]
visited = set(start)
while queue:
position, path = queue.pop(0)
if position == end:
return path
for p in get_neighbours(*position):
if can_step_on(p[0], p[1], magic_number) and p not in visited:
queue.append((p, path + [p]))
visited.add(p)
return []
path = find_path_in_maze(current_location, (7, 4), test_input)
print("Fewest steps: {}".format(len(path) - 1))
path = find_path_in_maze(current_location, (31,39), my_input)
print("Fewest steps: {}".format(len(path) - 1))
def locations_reachable_in_steps(start, magic_number, steps):
if get_field_type(start[0], start[1], magic_number) == "#":
return 0
queue = [start]
distances = {start: 0}
visited = set([start])
while queue:
position = queue.pop(0)
distance = distances[position]
for p in get_neighbours(*position):
if can_step_on(p[0], p[1], magic_number) and p not in visited:
if p in distances:
distances[p] = min(distances[p], distance + 1)
else:
distances[p] = distance + 1
queue.append(p)
visited.add(p)
return len(filter(lambda ((x, y), d): d <= steps, distances.items()))
print("Can reach {} locations".format(locations_reachable_in_steps(current_location, my_input, 50)))