package main import ( "fmt" h "git.bullercodeworks.com/brian/adventofcode/helpers" ) func main() { inp := h.StdinToCoordMap() part1(inp) fmt.Println("") part2(inp) } func part1(inp h.CoordByteMap) { var count int for x := inp.TLX; x <= inp.BRX; x++ { for y := inp.TLY; y <= inp.BRY; y++ { tree := h.Coordinate{X: x, Y: y} if treeIsVisibleFromOutside(inp, tree) { count++ } } } fmt.Println("# Part 1") fmt.Println("Visible tree from the outside:", count) } func part2(inp h.CoordByteMap) { var bestScore int var bestTree h.Coordinate for x := inp.TLX; x <= inp.BRX; x++ { for y := inp.TLY; y <= inp.BRY; y++ { tree := h.Coordinate{X: x, Y: y} ss := scenicScore(inp, tree) if ss > bestScore { bestScore = ss bestTree = tree } } } fmt.Println("# Part 2") fmt.Println("Best Score:", bestScore, "@", bestTree) } func treeIsVisibleFromOutside(inp h.CoordByteMap, pos h.Coordinate) bool { if pos.X == inp.TLX || pos.X == inp.BRX || pos.Y == inp.TLY || pos.Y == inp.BRY { return true } treeHeight := inp.Get(pos) n, e, s, w := true, true, true, true // Check North for y := inp.TLY; y < pos.Y; y++ { if inp.Get(h.Coordinate{X: pos.X, Y: y}) >= treeHeight { n = false break } } if n { return true } // Check East for x := inp.BRX; x > pos.X; x-- { if inp.Get(h.Coordinate{X: x, Y: pos.Y}) >= treeHeight { e = false break } } if e { return true } // Check South for y := inp.BRY; y > pos.Y; y-- { if inp.Get(h.Coordinate{X: pos.X, Y: y}) >= treeHeight { s = false break } } if s { return true } // Check West for x := inp.TLX; x < pos.X; x++ { if inp.Get(h.Coordinate{X: x, Y: pos.Y}) >= treeHeight { w = false break } } if w { return true } return false } func scenicScore(inp h.CoordByteMap, pos h.Coordinate) int { var n, e, s, w int treeHeight := inp.Get(pos) // Find how many trees we can see to the North if pos.Y == inp.TLY { return 0 } else { for y := pos.Y - 1; y >= inp.TLY; y-- { tst := inp.Get(h.Coordinate{X: pos.X, Y: y}) if tst < treeHeight { n++ } else if tst >= treeHeight { n++ break } } if n == 0 { return 0 } } // Find how many trees we can see to the East if pos.X == inp.BRX { return 0 } else { for x := pos.X + 1; x <= inp.BRX; x++ { tst := inp.Get(h.Coordinate{X: x, Y: pos.Y}) if tst < treeHeight { e++ } else if tst >= treeHeight { e++ break } } if e == 0 { return 0 } } // Find how many trees we can see to the South if pos.Y == inp.BRY { return 0 } else { for y := pos.Y + 1; y <= inp.BRY; y++ { tst := inp.Get(h.Coordinate{X: pos.X, Y: y}) if tst < treeHeight { s++ } else if tst >= treeHeight { s++ break } } if s == 0 { return 0 } } // Find how many trees we can see to the West if pos.X == inp.TLX { return 0 } else { for x := pos.X - 1; x >= inp.TLX; x-- { tst := inp.Get(h.Coordinate{X: x, Y: pos.Y}) if tst < treeHeight { w++ } else if tst >= treeHeight { w++ break } } if w == 0 { return 0 } } return n * e * s * w }