code.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "os"
  7. )
  8. func readInput(file *os.File) [][]byte {
  9. scanner := bufio.NewScanner(file)
  10. var trees [][]byte
  11. for scanner.Scan() {
  12. line := scanner.Text()
  13. if line == "" {
  14. continue
  15. }
  16. trees = append(trees, []byte(line))
  17. }
  18. return trees
  19. }
  20. func visibleFromLeft(x int, y int, trees [][]byte) bool {
  21. visible := true
  22. for i := 0; i < x; i++ {
  23. if trees[y][i] >= trees[y][x] {
  24. visible = false
  25. break
  26. }
  27. }
  28. return visible
  29. }
  30. func visibleFromRight(x int, y int, trees [][]byte, limit int) bool {
  31. visible := true
  32. for i := x + 1; i < limit; i++ {
  33. if trees[y][i] >= trees[y][x] {
  34. visible = false
  35. break
  36. }
  37. }
  38. return visible
  39. }
  40. func visibleFromTop(x int, y int, trees [][]byte) bool {
  41. visible := true
  42. for i := 0; i < y; i++ {
  43. if trees[i][x] >= trees[y][x] {
  44. visible = false
  45. break
  46. }
  47. }
  48. return visible
  49. }
  50. func visibleFromBottom(x int, y int, trees [][]byte, limit int) bool {
  51. visible := true
  52. for i := x + 1; i < limit; i++ {
  53. if trees[i][x] >= trees[y][x] {
  54. visible = false
  55. break
  56. }
  57. }
  58. return visible
  59. }
  60. func isVisible(x int, y int, trees [][]byte, width int, height int) bool {
  61. if visibleFromLeft(x, y, trees) {
  62. return true
  63. }
  64. if visibleFromRight(x, y, trees, width) {
  65. return true
  66. }
  67. if visibleFromTop(x, y, trees) {
  68. return true
  69. }
  70. if visibleFromBottom(x, y, trees, height) {
  71. return true
  72. }
  73. return false
  74. }
  75. func part1(trees [][]byte) int {
  76. width := len(trees[0])
  77. height := len(trees)
  78. visible := 2*height + (width-2)*2
  79. for y := 1; y < height-1; y++ {
  80. for x := 1; x < width-1; x++ {
  81. if isVisible(x, y, trees, width, height) {
  82. visible++
  83. }
  84. }
  85. }
  86. return visible
  87. }
  88. func main() {
  89. if len(os.Args) < 2 {
  90. log.Fatal("You need to specify a file!")
  91. }
  92. filePath := os.Args[1]
  93. file, err := os.Open(filePath)
  94. if err != nil {
  95. log.Fatalf("Failed to open %s!\n", filePath)
  96. }
  97. trees := readInput(file)
  98. fmt.Println("Part1:", part1(trees))
  99. }