-
Notifications
You must be signed in to change notification settings - Fork 0
/
day13.py
113 lines (69 loc) · 2.55 KB
/
day13.py
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import numpy as np
from collections import namedtuple
fav_number = 1352
State = namedtuple('State', ['at', 'steps', 'dist'])
def is_wall(x, y):
i = x*x + 3*x + 2*x*y + y + y*y + fav_number
bits = str(bin(i))[2:]
return (bits.count('1') % 2) == 1
def generate_map(size_x, size_y):
wall_map = np.zeros((size_x, size_y))
for x in range(size_x):
for y in range(size_y):
if is_wall(x, y):
wall_map[x, y] = -1
return wall_map
def valid_pos(at, map_size):
if at[0] < 0 or at[1] < 0 or at[0] >= map_size[0] or at[1] >= map_size[1]:
return False
else:
return True
def get_dist(v):
return np.linalg.norm(v, ord=1)
if __name__ == '__main__':
start = np.array([1, 1])
target = np.array([31, 39])
map_size = target + 25
steps = [np.array([0, 1]), np.array([0, -1]), np.array([1, 0]), np.array([-1, 0])]
wall_map = generate_map(map_size[0], map_size[1])
states = [State(start, 0, get_dist(target-start))]
while True:
dist_min = np.sum(map_size)
i_min = -1
# Get best current location
for i, state in enumerate(states):
if state.dist < dist_min:
dist_min = state.dist
i_min = i
state = states[i_min]
del states[i_min]
wall_map[state.at[0], state.at[1]] = 1
if dist_min == 0:
break
# Generate new steps
states_new = []
for step in steps:
new_pos = state.at + step
if not valid_pos(new_pos, map_size) or wall_map[new_pos[0], new_pos[1]] != 0:
continue
new_state = State(new_pos, state.steps + 1, get_dist(target-new_pos))
states_new.append(new_state)
states.extend(states_new)
print('Minimum distance to target: {}'.format(state.steps))
# Reset map
wall_map = generate_map(map_size[0], map_size[1])
positions = [start]
wall_map[start[0], start[1]] = 1
total_fields = 1
for a in range(50):
positions_new = []
for position in positions:
for step in steps:
position_new = position + step
if not valid_pos(position_new, map_size) or wall_map[position_new[0], position_new[1]] != 0:
continue
wall_map[position_new[0], position_new[1]] = 1
positions_new.append(position_new)
total_fields += 1
positions = positions_new
print('Total positions accessible in 50 steps: {}'.format(total_fields))