#!/usr/bin/env julia using Test function is_visible(tree_map, i, j) v = tree_map[i, j] less_v(x) = x < v if all(less_v, tree_map[i, 1:j-1]) return true end if all(less_v, tree_map[i, j+1:end]) return true end if all(less_v, tree_map[1:i-1, j]) return true end if all(less_v, tree_map[i+1:end, j]) return true end return false end function visible_trees_at(tree_map, i, j) nrows, ncols = size(tree_map) v = tree_map[i, j] ge_v(x) = x >= v up_idx = findfirst(ge_v, tree_map[i-1:-1:1, j]) up_score = up_idx === nothing ? i - 1 : up_idx down_idx = findfirst(ge_v, tree_map[i+1:end, j]) down_score = down_idx === nothing ? nrows - i : down_idx left_idx = findfirst(ge_v, tree_map[i, j-1:-1:1]) left_score = left_idx === nothing ? j - 1 : left_idx right_idx = findfirst(ge_v, tree_map[i, j+1:end]) right_score = right_idx === nothing ? ncols - j : right_idx return (up_score, down_score,left_score, right_score) end function scenic_score(tree_map, i, j) return prod(visible_trees_at(tree_map, i, j)) end function read_uint_matrix(io) lines = readlines(io) matrix = Matrix{UInt8}(undef, length(lines), length(lines[1])) for (i, line) in enumerate(lines) matrix[i, :] = parse.(UInt8, collect(line)) end return matrix end function count_visible(tree_map) nrows, ncols = size(tree_map) nvisible = 2 * (nrows + ncols) - 4 nvisible += sum([is_visible(tree_map, i, j) ? 1 : 0 for j in 2:nrows-1 for i in 2:ncols-1]) return nvisible end function max_scenic_score(tree_map) nrows, ncols = size(tree_map) return maximum([scenic_score(tree_map, i, j) for j in 2:nrows-1 for i in 2:ncols-1]) end function visiblility_map(tree_map) nrows, ncols = size(tree_map) vmap = Matrix{NTuple{4, Int}}(undef, nrows-2, ncols-2) for j in 2:nrows-1 for i in 2:ncols-1 vmap[i-1, j-1] = visible_trees_at(tree_map, i, j) end end return vmap end function test() @testset "visible trees" verbose=true begin @test count_visible(read_uint_matrix("example.txt")) == 21 @test count_visible(read_uint_matrix("input.txt")) == 1845 end @testset "max score" verbose=true begin @test max_scenic_score(read_uint_matrix("example.txt")) == 8 @test max_scenic_score(read_uint_matrix("input.txt")) == 230112 end end function main() if size(ARGS, 1) == 0 test() else infile = ARGS[1] println("infile = ", infile) tree_map = read_uint_matrix(infile) println("matrix: ", tree_map) println("visible: ", count_visible(tree_map)) println("max score: ", max_scenic_score(tree_map)) println("visible at: ") display(visiblility_map(tree_map)) println() end end main()