main.go (3276B)
1 package main 2 3 import ( 4 "bufio" 5 "fmt" 6 "log" 7 "os" 8 ) 9 10 type Grid [][]int 11 12 func (g Grid) IsEdge(row, col int) bool { 13 cols, rows := len(g[0]), len(g) 14 return col == 0 || row == 0 || col == cols-1 || row == rows-1 15 } 16 func (g Grid) CalcScore(row, col int) int { 17 cols, rows := len(g[0]), len(g) 18 height := g[row][col] 19 var left, right, top, bottom int 20 left = col 21 for c := col - 1; c >= 0; c-- { 22 if g[row][c] >= height { 23 left = col - c 24 break 25 } 26 } 27 right = cols - col - 1 28 for c := col + 1; c < cols; c++ { 29 if g[row][c] >= height { 30 right = c - col 31 break 32 } 33 } 34 top = row 35 for r := row - 1; r >= 0; r-- { 36 if g[r][col] >= height { 37 top = row - r 38 break 39 } 40 } 41 bottom = rows - row - 1 42 for r := row + 1; r < rows; r++ { 43 if g[r][col] >= height { 44 bottom = r - row 45 break 46 } 47 } 48 49 return left * right * top * bottom 50 } 51 52 type Tree struct { 53 row, col, height int 54 } 55 type Line struct { 56 trees []Tree 57 max int 58 } 59 60 func (l *Line) TryAdd(row, col, height int) { 61 if height > l.max { 62 l.trees = append(l.trees, Tree{row: row, col: col, height: height}) 63 l.max = height 64 } 65 } 66 func (l *Line) Has(row, col int) bool { 67 for _, t := range l.trees { 68 if t.row == row && t.col == col { 69 return true 70 } 71 } 72 return false 73 } 74 75 type Lines []Line 76 77 func (lines *Lines) Add() *Line { 78 *lines = append(*lines, Line{max: -1}) 79 return &(*lines)[len(*lines)-1] 80 } 81 func (lines *Lines) Has(row, col int) bool { 82 for _, l := range *lines { 83 if l.Has(row, col) { 84 return true 85 } 86 } 87 return false 88 } 89 90 func (t Tree) String() string { 91 return fmt.Sprintf("[r:%d,c:%d](h:%d)", t.row, t.col, t.height) 92 } 93 94 func main() { 95 if len(os.Args) > 1 { 96 day08(os.Args[1]) 97 } else if len(os.Args) == 1 { 98 fmt.Printf("usage: %s inputfile.txt\n", os.Args[0]) 99 } else { 100 fmt.Println("No input data") 101 } 102 } 103 104 func day08(input_file string) { 105 fmt.Printf("day 08 input filename: %s\n", input_file) 106 input, err := os.Open(input_file) 107 if err != nil { 108 log.Fatal(err) 109 } 110 defer input.Close() 111 scanner := bufio.NewScanner(input) 112 var grid Grid 113 row := 0 114 for scanner.Scan() { 115 in := scanner.Text() 116 grid = append(grid, make([]int, len(in))) 117 for col := 0; col < len(in); col++ { 118 grid[row][col] = int(in[col]) - 48 // wowee 119 } 120 row++ 121 } 122 if err = scanner.Err(); err != nil { 123 log.Fatal(err) 124 } 125 rows := row 126 cols := len(grid[0]) 127 var lefts, rights, tops, bottoms Lines 128 129 for r := 0; r < rows; r++ { 130 // row left to right 131 left := lefts.Add() 132 for c := 0; c < cols; c++ { 133 left.TryAdd(r, c, grid[r][c]) 134 } 135 // row right to left 136 right := rights.Add() 137 for c := cols - 1; c >= 0; c-- { 138 right.TryAdd(r, c, grid[r][c]) 139 } 140 } 141 142 for c := 0; c < cols; c++ { 143 // column top to bottom 144 top := tops.Add() 145 for r := 0; r < rows; r++ { 146 top.TryAdd(r, c, grid[r][c]) 147 } 148 // column bottom to top 149 bottom := bottoms.Add() 150 for r := rows - 1; r >= 0; r-- { 151 bottom.TryAdd(r, c, grid[r][c]) 152 } 153 } 154 155 sum := 0 156 maxScore := 0 157 for r := 0; r < rows; r++ { 158 for c := 0; c < cols; c++ { 159 if lefts.Has(r, c) || 160 rights.Has(r, c) || 161 tops.Has(r, c) || 162 bottoms.Has(r, c) { 163 sum++ 164 if !grid.IsEdge(r, c) { 165 score := grid.CalcScore(r, c) 166 if score > maxScore { 167 maxScore = score 168 } 169 } 170 } 171 } 172 } 173 fmt.Println("sum:", sum) 174 fmt.Println("score:", maxScore) 175 }