-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path11.jl
182 lines (140 loc) · 4.07 KB
/
11.jl
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
import Printf.@printf
struct InputSpec
path
width
height
end
struct CoordWithVis
coord::CartesianIndex
visiblecoords::Vector{CartesianIndex}
end
function parseinput(inputpath, offset)
coords = Vector{CartesianIndex}()
for (y, line) in enumerate(eachline(inputpath))
for (x, char) in enumerate(line)
if char == 'L'
push!(coords, CartesianIndex(y+offset, x+offset))
end
end
end
return coords
end
function calcdirections()
directions = collect(Base.product(-1:1, -1:1))
directions = [(directions)...]
directions = filter(x -> (x[1] != 0 || x[2] != 0), directions)
# @show directions
return directions
end
function calculate_coords_with_visible_coords(inputspec)
coords = parseinput(inputspec.path, 0)
grid = falses(inputspec.height, inputspec.width)
directions = calcdirections()
for coord in coords
grid[coord] = true
end
coords_with_vis = Vector{CoordWithVis}()
for coord in coords
visiblecoords = Vector{CartesianIndex}()
for direction in directions
x = coord[2] + direction[1]
y = coord[1] + direction[2]
while (x >= 1) && (x <= inputspec.width) && (y >= 1) && (y <= inputspec.height)
if grid[y, x]
push!(visiblecoords, CartesianIndex(y, x))
break
else
x += direction[1]
y += direction[2]
end
end
end
push!(coords_with_vis, CoordWithVis(coord, visiblecoords))
end
# @show coords_with_vis
return coords_with_vis
end
function solvevisible(inputspec)
currentgrid = falses(inputspec.height, inputspec.width)
nextgrid = falses(inputspec.height, inputspec.width)
allcoordwithvis = calculate_coords_with_visible_coords(inputspec)
anychanged = true
iterationcount = 0
while anychanged
anychanged = false
iterationcount += 1
for coordwithvis in allcoordwithvis
coord = coordwithvis.coord
visiblecoords = coordwithvis.visiblecoords
isoccupied = currentgrid[coord]
occupiedcount = count(vc -> (currentgrid[vc]), visiblecoords)
if isoccupied && occupiedcount >= 5
nextgrid[coord] = false
anychanged = true
elseif !isoccupied && occupiedcount == 0
nextgrid[coord] = true
anychanged = true
else
nextgrid[coord] = isoccupied
end
end
currentgrid, nextgrid = nextgrid, currentgrid
end
@printf("iterationcount: %i, filledseats: %i\r\n", iterationcount, count(b->(b), currentgrid))
end
# i'm oversizing the array by +2 in each direction
# to avoid doing conditional checks
function solveneighbor(inputspec)
xsize = inputspec.width + 2 # Julia arrays start at 1
ysize = inputspec.height + 2
currentgrid = falses(ysize, xsize)
nextgrid = falses(ysize, xsize)
coords = parseinput(inputspec.path, 1)
anychanged = true
iterationcount = 0
while anychanged
anychanged = false
iterationcount += 1
for coord in coords
# @show coord
subarray = view(currentgrid, coord[1]-1:coord[1]+1, coord[2]-1:coord[2]+1)
currentvalue = subarray[2, 2]
neighborcount = count(b->(b), subarray) - (currentvalue ? 1 : 0)
if currentvalue && neighborcount >= 4
nextgrid[coord] = false
anychanged = true
elseif !currentvalue && neighborcount == 0
nextgrid[coord] = true
anychanged = true
# else
# nextgrid[coord] = currentvalue
end
# @show coord, subarray, currentvalue, neighborcount
end
# printgrid(nextgrid)
# bulk copying turns out to execute faster
copyto!(currentgrid, nextgrid)
# tempgrid = currentgrid
# currentgrid = nextgrid
# nextgrid = tempgrid
end
@printf("iterationcount: %i, filledseats: %i\r\n", iterationcount, count(b->(b), nextgrid))
end
function printgrid(grid)
# TODO: make better
@show grid
end
function solve()
# inputspec = InputSpec("11.input.sample", 10, 10)
inputspec = InputSpec("11.input", 92, 94)
# @time begin
# println("neighbor:")
# solveneighbor(inputspec)
# end
# println("")
@time begin
println("visible:")
solvevisible(inputspec)
end
end
solve()