You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
3.1 KiB
120 lines
3.1 KiB
5 years ago
|
lines = {}
|
||
|
for text in io.lines(arg[1]) do
|
||
|
line = {}
|
||
|
for dir, dist in string.gmatch(text, "(%a)(%d+),") do
|
||
|
table.insert(line, {dir=dir, dist=tonumber(dist)})
|
||
|
end
|
||
|
table.insert(lines, line)
|
||
|
end
|
||
|
|
||
|
function manhattan(x, y)
|
||
|
return math.abs(x) + math.abs(y)
|
||
|
end
|
||
|
function sum(table)
|
||
|
out = 0
|
||
|
for _, x in ipairs(table) do
|
||
|
out = out + x
|
||
|
end
|
||
|
return out
|
||
|
end
|
||
|
|
||
|
board = {}
|
||
|
intersect_p1 = nil
|
||
|
intersect_p2 = nil
|
||
|
function add_trace(x, y, index, steps)
|
||
|
if not board[y] then
|
||
|
board[y] = {}
|
||
|
end
|
||
|
if not board[y][x] then
|
||
|
board[y][x] = {}
|
||
|
end
|
||
|
if not board[y][x][index] or steps < board[y][x][index] then
|
||
|
board[y][x][index] = steps
|
||
|
end
|
||
|
if #board[y][x] > 1 then
|
||
|
if not intersect_p1 or manhattan(x, y) < intersect_p1 then
|
||
|
intersect_p1 = manhattan(x, y)
|
||
|
end
|
||
|
if not intersect_p2 or sum(board[y][x]) < intersect_p2 then
|
||
|
intersect_p2 = sum(board[y][x])
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
min_x = 0
|
||
|
max_x = 0
|
||
|
min_y = 0
|
||
|
max_y = 0
|
||
|
for line_index, line in ipairs(lines) do
|
||
|
pos_x = 0
|
||
|
pos_y = 0
|
||
|
steps = 0
|
||
|
for trace_index, trace in ipairs(line) do
|
||
|
if trace.dir == "U" then
|
||
|
for y = pos_y + 1, pos_y + trace.dist do
|
||
|
steps = steps + 1
|
||
|
add_trace(pos_x, y, line_index, steps)
|
||
|
end
|
||
|
pos_y = pos_y + trace.dist
|
||
|
elseif trace.dir == "D" then
|
||
|
for y = pos_y - 1, pos_y - trace.dist, -1 do
|
||
|
steps = steps + 1
|
||
|
add_trace(pos_x, y, line_index, steps)
|
||
|
end
|
||
|
pos_y = pos_y - trace.dist
|
||
|
elseif trace.dir == "L" then
|
||
|
for x = pos_x - 1, pos_x - trace.dist, -1 do
|
||
|
steps = steps + 1
|
||
|
add_trace(x, pos_y, line_index, steps)
|
||
|
end
|
||
|
pos_x = pos_x - trace.dist
|
||
|
elseif trace.dir == "R" then
|
||
|
for x = pos_x + 1, pos_x + trace.dist do
|
||
|
steps = steps + 1
|
||
|
add_trace(x, pos_y, line_index, steps)
|
||
|
end
|
||
|
pos_x = pos_x + trace.dist
|
||
|
end
|
||
|
|
||
|
if pos_x > max_x then
|
||
|
max_x = pos_x
|
||
|
end
|
||
|
if pos_x < min_x then
|
||
|
min_x = pos_x
|
||
|
end
|
||
|
if pos_y > max_y then
|
||
|
max_y = pos_y
|
||
|
end
|
||
|
if pos_x < min_y then
|
||
|
min_y = pos_y
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
print("Part 1:", intersect_p1)
|
||
|
print("Part 2:", intersect_p2)
|
||
|
|
||
|
if arg[2] then
|
||
|
out = io.open(arg[2], "w")
|
||
|
out:write(string.format("P3\n%d %d\n255\n", max_x - min_x + 1, max_y - min_y + 1))
|
||
|
for y = min_y, max_y do
|
||
|
for x = min_x, max_x do
|
||
|
if not board[y] then
|
||
|
out:write("255 255 255 ")
|
||
|
elseif not board[y][x] then
|
||
|
out:write("255 255 255 ")
|
||
|
else
|
||
|
for i = 1, 3 do
|
||
|
if board[y][x][i] then
|
||
|
out:write("255 ")
|
||
|
else
|
||
|
out:write("0 ")
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
out:write("\n")
|
||
|
end
|
||
|
out:close()
|
||
|
end
|