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
						
					
					
				
			
		
		
	
	
							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()
 |