advent-of-code

Perserverance, or the lack thereof

git clone git://git.shimmy1996.com/advent-of-code.git

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 }