adventofcode/2022/day08/main.go

170 lines
3.1 KiB
Go

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
}