You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
2.7 KiB

#!/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()