60 lines
1.5 KiB
Julia
60 lines
1.5 KiB
Julia
|
|
const grid = [ collect(line) for line in readlines("input/6") ]
|
|
|
|
const size = length(grid)
|
|
const startY = findfirst(x -> '^' in values(x), grid)
|
|
const startX = findfirst(x -> x === '^', grid[startY])
|
|
|
|
const Coords = Tuple{Int,Int}
|
|
|
|
const index(pos::Coords)::Char = index(pos[1], pos[2])
|
|
const index(x::Int, y::Int)::Char = x > 0 && y > 0 && x <= size && y <= size ? grid[y][x] : '\0'
|
|
|
|
mutable struct Guard
|
|
Guard() = new(( startX, startY ), ( 0, -1 ))
|
|
pos::Coords
|
|
vel::Coords
|
|
end
|
|
const rotate!(g::Guard) = g.vel = ( -g.vel[2], g.vel[1] )
|
|
|
|
begin
|
|
local visited::Set{Coords} = Set()
|
|
local guard = Guard()
|
|
while index(guard.pos) !== '\0'
|
|
push!(visited, guard.pos)
|
|
while index(guard.pos .+ guard.vel) === '#'
|
|
rotate!(guard)
|
|
end
|
|
guard.pos = guard.pos .+ guard.vel
|
|
end
|
|
|
|
println("Part one ", length(visited))
|
|
end
|
|
|
|
begin
|
|
doesLoop = Threads.Atomic{Int}(0)
|
|
Threads.@threads for y in 1:size
|
|
for x in 1:size
|
|
if index(x, y) !== '.' continue end
|
|
local function tryPatrol()::Bool
|
|
local visited::Set{Pair{Coords,Coords}} = Set()
|
|
local guard = Guard()
|
|
while true
|
|
push!(visited, guard.pos => guard.vel)
|
|
while index(guard.pos .+ guard.vel) === '#' || (guard.pos .+ guard.vel) === (x, y)
|
|
rotate!(guard)
|
|
end
|
|
guard.pos = guard.pos .+ guard.vel
|
|
if index(guard.pos) === '\0' return false end
|
|
if (guard.pos => guard.vel) in visited return true end
|
|
end
|
|
end
|
|
if tryPatrol()
|
|
Threads.atomic_add!(doesLoop, 1)
|
|
end
|
|
end
|
|
end
|
|
|
|
println("Part two ", doesLoop[])
|
|
end
|
|
|