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.
136 lines
2.7 KiB
136 lines
2.7 KiB
import "aoc" for AoC
|
|
|
|
class Forest {
|
|
construct new(w, h) {
|
|
_w = w
|
|
_h = h
|
|
_trees = List.filled(w*h, 0)
|
|
}
|
|
|
|
w { _w }
|
|
h { _h }
|
|
|
|
get(x, y) { _trees[x+_w*y] }
|
|
set(x, y, t) { _trees[x+_w*y] = t }
|
|
|
|
visible_cardinal(x, y) {
|
|
if(x == 0 || y == 0 || x == w-1 || y == h-1) {
|
|
return true
|
|
}
|
|
|
|
var t = get(x, y)
|
|
|
|
var vis = true
|
|
for(xi in 0...x) {
|
|
if(get(xi, y) >= t) {
|
|
vis = false
|
|
break
|
|
}
|
|
}
|
|
if(vis) return true
|
|
|
|
vis = true
|
|
for(yi in 0...y) {
|
|
if(get(x, yi) >= t) {
|
|
vis = false
|
|
break
|
|
}
|
|
}
|
|
if(vis) return true
|
|
|
|
vis = true
|
|
for(xi in (x+1)...w) {
|
|
if(get(xi, y) >= t) {
|
|
vis = false
|
|
break
|
|
}
|
|
}
|
|
if(vis) return true
|
|
|
|
vis = true
|
|
for(yi in (y+1)...h) {
|
|
if(get(x, yi) >= t) {
|
|
vis = false
|
|
break
|
|
}
|
|
}
|
|
if(vis) return true
|
|
|
|
return false
|
|
}
|
|
|
|
score(x, y) {
|
|
if(x == 0 || y == 0 || x == w-1 || y == h-1) {
|
|
return 0
|
|
}
|
|
|
|
var t = get(x, y)
|
|
|
|
var score_left = 0
|
|
for(xi in (x-1)..0) {
|
|
score_left = score_left + 1
|
|
if(get(xi, y) >= t) {
|
|
break
|
|
}
|
|
}
|
|
|
|
var score_up = 0
|
|
for(yi in (y-1)..0) {
|
|
score_up = score_up + 1
|
|
if(get(x, yi) >= t) {
|
|
break
|
|
}
|
|
}
|
|
|
|
var score_right = 0
|
|
for(xi in (x+1)...(_w)) {
|
|
score_right = score_right + 1
|
|
if(get(xi, y) >= t) {
|
|
break
|
|
}
|
|
}
|
|
|
|
var score_down = 0
|
|
for(yi in (y+1)...(_h)) {
|
|
score_down = score_down + 1
|
|
if(get(x, yi) >= t) {
|
|
break
|
|
}
|
|
}
|
|
|
|
return score_left * score_up * score_right * score_down
|
|
}
|
|
}
|
|
|
|
var input = AoC.input
|
|
var row_count = input.where {|x| x == "\n"}.count
|
|
var lines = input.split("\n").where {|x| x != ""}
|
|
|
|
var forest = null
|
|
var x = 0
|
|
for(line in lines) {
|
|
if(!forest) forest = Forest.new(line.count, row_count)
|
|
var y = 0
|
|
for(tree in line) {
|
|
forest.set(x, y, Num.fromString(tree))
|
|
y = y + 1
|
|
}
|
|
x = x + 1
|
|
}
|
|
|
|
var total_visible = 0
|
|
var best_score = 0
|
|
for(x in 0...forest.w) {
|
|
for(y in 0...forest.h) {
|
|
if(forest.visible_cardinal(x, y)) {
|
|
total_visible = total_visible + 1
|
|
}
|
|
var score = forest.score(x, y)
|
|
if(score > best_score) {
|
|
best_score = score
|
|
}
|
|
}
|
|
}
|
|
|
|
System.print(total_visible)
|
|
System.print(best_score) |