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 }