-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathday15.py
More file actions
153 lines (134 loc) · 5.73 KB
/
day15.py
File metadata and controls
153 lines (134 loc) · 5.73 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
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
from opcode_computer import opcode_computer
import numpy as np
with open('/Users/relyea/data/input.txt') as input_file:
inpstring = input_file.readlines()
inpstring = inpstring[0].strip()
amplist = inpstring.split(',')
amplist = [int(a) for a in amplist]
amplist_orig = copy(amplist)
ordered_directions_map = (
(1,4,2,3),
(4,2,3,1),
(2,3,1,4),
(3,1,4,2),
(1,3,2,4),
(3,2,4,1),
(2,4,1,3),
(4,1,3,2)
)
def update_position(direction, position):
if direction == 1:
newposition = (position[0], position[1]+1)
elif direction == 2:
newposition = (position[0], position[1]-1)
elif direction == 3:
newposition = (position[0]+1, position[1])
elif direction == 4:
newposition = (position[0]-1, position[1])
return newposition
def wall_in_that_direction(layout, position, direction):
if layout[update_position(direction, position)] == 1:
return True
else:
return False
def find_next_direction(layout, index_of_directions_to_try, index_of_directions_to_try_offset, position, ordered_directions):
notFound = True
if index_of_directions_to_try[position] == -1:
index_of_directions_to_try[position] = index_of_directions_to_try_offset[position]
while notFound:
nextDirection = ordered_directions[index_of_directions_to_try[position]]
print('FINDING', position, nextDirection)
index_of_directions_to_try[position] = ( index_of_directions_to_try[position] + 1 ) % 4
if not wall_in_that_direction(layout, position, nextDirection):
notFound = False
return nextDirection
def update_attempted_directions(direction, position, index_of_directions_to_try_offset, ordered_directions):
if index_of_directions_to_try_offset[position] == -1:
index_of_directions_to_try_offset[position] = ( ordered_directions.index(direction) + 3 ) % 4
def put_wall_in_direction(direction, position, layout):
layout[update_position(direction, position)] = 1
states = set()
layouts = np.zeros((8,51,51))
for ilayout in range(len(ordered_directions_map)):
layout = np.zeros((51,51)) - 1
index_of_directions_to_try = np.zeros((51,51),dtype=int) - 1
index_of_directions_to_try_offset = np.zeros((51,51),dtype=int) - 1
position = (25,25)
index_of_directions_to_try_offset[position] = 0
index_of_directions_to_try[position] = 0
the_result = -1
op = opcode_computer(list(copy(list(amplist_orig)))+[0]*100000)
while True:
layout[position] = 0 # already seen
direction = find_next_direction(layout, index_of_directions_to_try, index_of_directions_to_try_offset, position, ordered_directions_map[ilayout])
op.input([direction])
the_result = op.run()
print(position, direction, the_result)
if the_result == 2:
position = update_position(direction, position)
layout[position] = 2
break
elif the_result == 1:
newstate = (position[0], position[1], direction)
# if newstate in states:
# assert(1==0)
# else:
# states.add(newstate)
position = update_position(direction, position)
update_attempted_directions(direction, position, index_of_directions_to_try_offset, ordered_directions_map[ilayout])
elif the_result == 0:
put_wall_in_direction(direction, position, layout)
layouts[ilayout,:,:] = layout
uberlayout = layouts[0,:,:]
for ilayout in range(1,len(ordered_directions_map)):
for ii in range(51):
for jj in range(51):
if uberlayout[ii,jj] == -1 and layouts[ilayout,ii,jj] != -1:
uberlayout[ii,jj] = layouts[ilayout,ii,jj]
# flood fill time!
# nah it's not cyclic so just do a tree
# from any spot, you find all adjacent guys whose distances are't in the distance dict
# for each one, set its distance equal to one more and then recurrence it
position = (25,25)
distances = {position: 0}
def find_distance_from_all_points(position):
adjacent_positions = [update_position(direction, position) for direction in [1,2,3,4]]
valid_adjacent_positions = []
for potential_valid_position in adjacent_positions:
if (
potential_valid_position[0] >= 0 and
potential_valid_position[0] < 51 and
potential_valid_position[1] >= 0 and
potential_valid_position[1] < 51 and
uberlayout[potential_valid_position] != 1 and
potential_valid_position not in distances
):
valid_adjacent_positions.append(potential_valid_position)
for newposition in valid_adjacent_positions:
distances[newposition] = distances[position] + 1
find_distance_from_all_points(newposition)
find_distance_from_all_points(position)
position = (7,7)
distances = {position: 0}
def find_distance_from_all_points(position):
adjacent_positions = [update_position(direction, position) for direction in [1,2,3,4]]
valid_adjacent_positions = []
for potential_valid_position in adjacent_positions:
if (
potential_valid_position[0] >= 0 and
potential_valid_position[0] < 51 and
potential_valid_position[1] >= 0 and
potential_valid_position[1] < 51 and
uberlayout[potential_valid_position] == 0 and
potential_valid_position not in distances
):
valid_adjacent_positions.append(potential_valid_position)
for newposition in valid_adjacent_positions:
distances[newposition] = distances[position] + 1
find_distance_from_all_points(newposition)
find_distance_from_all_points(position)
maxdist = 0
for position in distances:
if distances[position] > maxdist:
maxpos = position
maxdist = distances[position]