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