Mercurial > lbo > hg > aoc22
view 2022/09/09.jl @ 73:2c6477929e58
Day 16 Part 1
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Fri, 29 Dec 2023 09:53:19 +0100 |
parents | 05ddc45b4210 |
children |
line wrap: on
line source
const test_input::String = "R 4 U 4 L 3 D 1 R 4 D 1 L 5 R 2"; const test_input2::String = "R 5 U 8 L 8 D 3 R 17 D 10 L 25 U 20"; @enum Direction begin U D L R end function to_direction(c::Char)::Direction if c == 'U' U elseif c == 'D' D elseif c == 'L' L elseif c == 'R' R end end struct Step direction::Direction n::Int end function parse_input(lines::Iter)::Vector{Step} where {Iter} v = Vector{Step}(); for l in lines a, b = split(l, ' '); push!(v, Step(to_direction(a[1]), parse(Int, b))); end v end function wheretogo(H::Tuple{Int,Int}, T::Tuple{Int,Int})::Vector{Direction} # This might have a more elegant solution... if H == T [] elseif H[1]==T[1] if abs(H[2]-T[2]) < 2 [] else (H[2] > T[2] ? [U] : [D]) end elseif H[2]==T[2] if abs(H[1]-T[1]) < 2 [] else (H[1] < T[1] ? [L] : [R]) end elseif abs(H[1]-T[1]) + abs(H[2]-T[2]) == 3 # diagonal if abs(H[1]-T[1]) > abs(H[2]-T[2]) snd = (H[2]-T[2]) > 0 ? U : D; (H[1]-T[1]) > 0 ? ([R, snd]) : ([L, snd]) else snd = (H[1]-T[1]) > 0 ? R : L; (H[2]-T[2]) > 0 ? ([U, snd]) : ([D, snd]) end elseif abs(H[1]-T[1])==abs(H[2]-T[2]) && abs(H[1]-T[1]) > 1 [(H[1]>T[1] ? R : L), (H[2]>T[2] ? U : D)] else if abs(H[1]-T[1])+abs(H[2]-T[2]) == 2 [] else error("unhandled case: ", H, T) end end end function apply(p::Tuple{Int,Int}, dir::Direction)::Tuple{Int,Int} if dir == U p .+ (0,1) elseif dir == D p .+ (0,-1) elseif dir == L p .+ (-1,0) else p .+ (1,0) end end function process1(v::Vector{Step}; ntails=1)::Int H = (0, 0); T = [(0,0) for i in 1:ntails]; visited = Set{Tuple{Int,Int}}([H]) for step in v for i = 1:step.n H = apply(H, step.direction); # Tail follow pred = H for (i,t) in enumerate(T) wtg = wheretogo(pred, t); for w in wtg::Vector{Direction} T[i] = apply(T[i], w); end pred = T[i]; end push!(visited, pred); end end length(visited) end println("test input (should be 13):"); println(process1(parse_input(split(test_input, '\n')))); println("part 1:"); open("09/input.txt"; read=true) do fh @time println(process1(parse_input(eachline(fh)))); end println("part 2:"); println(process1(parse_input(split(test_input2, '\n')); ntails=9)); open("09/input.txt"; read=true) do fh @time println(process1(parse_input(eachline(fh)); ntails=9)); end