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)