view 09/09.jl @ 13:dfed6e6ea69b

Day 09 part 1
author Lewin Bormann <lbo@spheniscida.de>
date Sun, 11 Dec 2022 10:48:43 +0100
parents
children 4bad3ee77ef2
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";

@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}
    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
    else
        []
    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})::Int
    H = (0, 0);
    T = (0, 0);
    visited = Set{Tuple{Int,Int}}([T])

    for step in v
        for i = 1:step.n
            H = apply(H, step.direction);
            wtg = wheretogo(H, T);
            for w in wtg::Vector{Direction}
                T = apply(T, w);
            end
            @show T
            push!(visited, T);
        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
    println(process1(parse_input(eachline(fh))));
end