main.go (2018B)
1 package main 2 3 import ( 4 "bufio" 5 "fmt" 6 "os" 7 "strconv" 8 ) 9 10 const ( 11 N = iota 12 S 13 E 14 W 15 L 16 R 17 F 18 ) 19 20 type navi struct { 21 len int 22 act []int 23 val []int 24 } 25 26 func (this *navi) get(i int) (int, int) { 27 return this.act[i], this.val[i] 28 } 29 30 func readInput(filename string) (res navi) { 31 file, _ := os.Open(filename) 32 defer file.Close() 33 34 actMap := map[byte]int{ 35 'N': N, 'S': S, 'E': E, 'W': W, 36 'L': L, 'R': R, 'F': F, 37 } 38 scanner := bufio.NewScanner(file) 39 for scanner.Scan() { 40 row := scanner.Text() 41 res.act = append(res.act, actMap[row[0]]) 42 val, _ := strconv.Atoi(row[1:]) 43 res.val = append(res.val, val) 44 } 45 res.len = len(res.act) 46 return 47 } 48 49 func main() { 50 input := readInput("./input.txt") 51 // 796 52 fmt.Println(part(input, exec1)) 53 // 39446 54 fmt.Println(part(input, exec2)) 55 } 56 57 func rotate(dir int, act int, val int) int { 58 left := map[int]int{N: W, W: S, S: E, E: N} 59 right := map[int]int{N: E, E: S, S: W, W: N} 60 for i := 0; i < val/90; i++ { 61 if act == L { 62 dir = left[dir] 63 } else if act == R { 64 dir = right[dir] 65 } 66 } 67 return dir 68 } 69 70 func exec1(input navi) (x, y int) { 71 loc := map[int]int{} 72 dir := E 73 for i := 0; i < input.len; i++ { 74 act, val := input.get(i) 75 switch act { 76 case L, R: 77 dir = rotate(dir, act, val) 78 case F: 79 loc[dir] += val 80 default: 81 loc[act] += val 82 } 83 } 84 return loc[E] - loc[W], loc[N] - loc[S] 85 } 86 87 func exec2(input navi) (x, y int) { 88 loc := map[int]int{} 89 wpt := map[int]int{E: 10, N: 1} 90 for i := 0; i < input.len; i++ { 91 act, val := input.get(i) 92 switch act { 93 case L, R: 94 wpt = map[int]int{ 95 rotate(N, act, val): wpt[N], 96 rotate(E, act, val): wpt[E], 97 rotate(S, act, val): wpt[S], 98 rotate(W, act, val): wpt[W], 99 } 100 case F: 101 for _, dir := range []int{N, E, S, W} { 102 loc[dir] += wpt[dir] * val 103 } 104 default: 105 wpt[act] += val 106 } 107 } 108 return loc[E] - loc[W], loc[N] - loc[S] 109 } 110 111 func abs(x int) int { 112 if x < 0 { 113 return -x 114 } 115 return x 116 } 117 118 func part(input navi, exec func(navi) (int, int)) int { 119 x, y := exec(input) 120 return abs(x) + abs(y) 121 }