view 08/08.jl @ 12:ecf80e49d919

Day 08
author Lewin Bormann <lbo@spheniscida.de>
date Sat, 10 Dec 2022 21:41:58 +0100
parents
children
line wrap: on
line source


const input = "08/input.txt"

const short = "30373
25512
65332
33549
35390";

function parse_trees(lines::Vector{S})::Matrix{Int} where {S <: AbstractString}
    m = zeros(length(lines), length(lines[1]));
    for (i, line) in enumerate(lines)
        for (j, c) in enumerate(line)
            m[i,j] = parse(Int, c);
        end
    end
    m
end

function visibility(row_or_col::AbstractVector{Int})::Vector{Bool}
    v = zeros(Bool, length(row_or_col));
    highest = row_or_col[begin];
    v[begin] = true;
    for i in eachindex(row_or_col)
        if row_or_col[i] > highest
            v[i] = true;
            highest = row_or_col[i];
        end
    end
    v
end

function is_visible(m::Matrix{Int})::Matrix{Bool}
    rows, cols = size(m);
    v = zeros(Bool, size(m));

    # Row-wise
    for row in 1:rows
        v_forward = @views visibility(m[row,:]);
        v_backward = @views visibility(m[row,end:-1:begin]);
        reverse!(v_backward);
        v[row,:] .= v_forward .| v_backward;
    end
    # Col-wise
    for col in 1:cols
        v_down = @views visibility(m[:,col]);
        v_up = @views visibility(m[end:-1:begin,col]);
        reverse!(v_up);
        v[:,col] .|= v_down .| v_up;
    end
    
    v
end

function find_scenic_distance(v::AbstractVector{Int})::Int
    ref = v[1];
    for i = 2:length(v)
        if v[i] >= ref
            return i-1;
        end
    end
    return length(v)-1;
end

function scenic_score(m::Matrix{Int}, row::Int, col::Int)::Int
    v = m[row, col];

    l = find_scenic_distance(@view m[row, col:-1:begin]);
    r = find_scenic_distance(@view m[row, col:end]);
    u = find_scenic_distance(@view m[row:-1:begin, col]);
    d = find_scenic_distance(@view m[row:end, col]);
    l*r*u*d
end

function scenic_scores(m::Matrix{Int})::Matrix{Int}
    s = zeros(Int, size(m));
    for ix in CartesianIndices(size(m))
        s[ix] = scenic_score(m, Tuple(ix)...);
    end
    s
end

println("Real challenge, part 1:");
inp_lines = readlines(input);
trees = parse_trees(inp_lines);
println(sum(is_visible(trees)));

println("Part two:");
ss = scenic_scores(trees);
println("max scenic score: ", maximum(ss));