package day8 type Solver struct { input [][]byte tallestFromLeft [][]int8 tallestFromRight [][]int8 tallestFromTop [][]int8 tallestFromBottom [][]int8 } func (s *Solver) ParseInput(input []string) { s.input = make([][]byte, len(input)) for i, line := range input { s.input[i] = []byte(line) for x := 0; x < len(s.input[i]); x++ { s.input[i][x] -= '0' } } } func max(a, b int8) int8 { if a > b { return a } else { return b } } func (s *Solver) SolvePart1() any { s.tallestFromLeft = make([][]int8, len(s.input)) for r := 0; r < len(s.input); r++ { s.tallestFromLeft[r] = make([]int8, len(s.input)) for c := 0; c < len(s.input); c++ { if c == 0 { s.tallestFromLeft[r][c] = -1 } else { s.tallestFromLeft[r][c] = max(s.tallestFromLeft[r][c-1], int8(s.input[r][c-1])) } } } //fmt.Println(s.tallestFromLeft) s.tallestFromRight = make([][]int8, len(s.input)) for r := 0; r < len(s.input); r++ { s.tallestFromRight[r] = make([]int8, len(s.input)) for c := len(s.input) - 1; c >= 0; c-- { if c == len(s.input)-1 { s.tallestFromRight[r][c] = -1 } else { s.tallestFromRight[r][c] = max(s.tallestFromRight[r][c+1], int8(s.input[r][c+1])) } } } //fmt.Println(s.tallestFromRight) s.tallestFromBottom = make([][]int8, len(s.input)) for r := 0; r < len(s.input); r++ { s.tallestFromBottom[r] = make([]int8, len(s.input)) } for c := 0; c < len(s.input); c++ { for r := len(s.input) - 1; r >= 0; r-- { if r == len(s.input)-1 { s.tallestFromBottom[r][c] = -1 } else { s.tallestFromBottom[r][c] = max(s.tallestFromBottom[r+1][c], int8(s.input[r+1][c])) } } } //fmt.Println(s.tallestFromBottom) s.tallestFromTop = make([][]int8, len(s.input)) for r := 0; r < len(s.input); r++ { s.tallestFromTop[r] = make([]int8, len(s.input)) } for c := 0; c < len(s.input); c++ { for r := 0; r < len(s.input); r++ { if r == 0 { s.tallestFromTop[r][c] = -1 } else { s.tallestFromTop[r][c] = max(s.tallestFromTop[r-1][c], int8(s.input[r-1][c])) } } } //fmt.Println(s.tallestFromTop) var total int for r := 0; r < len(s.input); r++ { for c := 0; c < len(s.input[0]); c++ { if s.isVisible(r, c) { total += 1 } } } return total } func (s *Solver) isVisible(r, c int) bool { v := int8(s.input[r][c]) return v > s.tallestFromTop[r][c] || v > s.tallestFromBottom[r][c] || v > s.tallestFromLeft[r][c] || v > s.tallestFromRight[r][c] } type D struct { dr, dc int } func (s *Solver) SolvePart2() any { ds := []D{{-1, 0}, {1, 0}, {0, 1}, {0, -1}} bestViewingDistance := 0 for r := 0; r < len(s.input); r++ { for c := 0; c < len(s.input); c++ { viewingDistance := 1 for _, d := range ds { viewingDistance *= s.getViewingDistance(r, c, d) } if viewingDistance > bestViewingDistance { bestViewingDistance = viewingDistance } } } return bestViewingDistance } func (s *Solver) getViewingDistance(r, c int, d D) int { result := 0 v := s.input[r][c] for { r += d.dr c += d.dc if r < 0 || r == len(s.input) || c < 0 || c == len(s.input) { break } result++ if s.input[r][c] >= v { break } } return result }