From f5ec48772e2bc4977fe04bedcf917ee2e4ae0a2e Mon Sep 17 00:00:00 2001 From: David Ashby Date: Sat, 12 Dec 2020 12:22:14 -0500 Subject: [PATCH] add day 12 --- .gitignore | 3 +- 12/main.go | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 12/main.go diff --git a/.gitignore b/.gitignore index 770eab4..8178bd2 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -input \ No newline at end of file +input +testinput \ No newline at end of file diff --git a/12/main.go b/12/main.go new file mode 100644 index 0000000..43cf118 --- /dev/null +++ b/12/main.go @@ -0,0 +1,198 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "time" +) + +func main() { + start := time.Now() + partOne() + duration := time.Since(start) + partTwo() + duration2 := time.Since(start) + fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration) +} + +type ship struct { + horizontal int + vertical int + direction rune // E W N S +} + +// both horizontal/vertical are relative to ship +type waypoint struct { + horizontal int + vertical int +} + +func parseLine(s string) (rune, int) { + i, _ := strconv.Atoi(s[1:]) + return []rune(s)[0], i +} + +func movePartOne(s ship, action rune, vector int) ship { + switch action { + case 'R', 'L': + s.direction = rotateShip(s.direction, vector, action) + case 'N': + s.vertical = s.vertical + vector + case 'S': + s.vertical = s.vertical - vector + case 'E': + s.horizontal = s.horizontal + vector + case 'W': + s.horizontal = s.horizontal - vector + case 'F': + s = movePartOne(s, s.direction, vector) + } + return s +} + +func movePartTwo(s ship, w waypoint, action rune, vector int) (ship, waypoint) { + switch action { + case 'R', 'L': + w = rotateWaypoint(w, action, vector) + case 'N': + w.vertical = w.vertical + vector + case 'S': + w.vertical = w.vertical - vector + case 'E': + w.horizontal = w.horizontal + vector + case 'W': + w.horizontal = w.horizontal - vector + case 'F': + s.horizontal = s.horizontal + (w.horizontal * vector) + s.vertical = s.vertical + (w.vertical * vector) + } + return s, w +} + +// for example E, 90, L => N; E, 180, R => W; E, 90, R => S +func rotateShip(current rune, degrees int, rl rune) rune { + // easy + if degrees == 180 { + switch current { + case 'N': + return 'S' + case 'S': + return 'N' + case 'E': + return 'W' + case 'W': + return 'E' + } + } + // translate L to R + if rl == 'L' { + if degrees == 90 { + degrees = 270 + } else { + degrees = 90 + } + } + // the R set + if degrees == 90 { + switch current { + case 'N': + return 'E' + case 'S': + return 'W' + case 'E': + return 'S' + case 'W': + return 'N' + } + } else if degrees == 270 { + switch current { + case 'N': + return 'W' + case 'S': + return 'E' + case 'E': + return 'N' + case 'W': + return 'S' + } + } + + return current // we're made a terrible mistake somewhere +} + +func rotateWaypoint(w waypoint, action rune, vector int) waypoint { + if vector == 180 { + w.horizontal = -w.horizontal + w.vertical = -w.vertical + } else if action == 'R' { + if vector == 90 { + w.horizontal, w.vertical = w.vertical, -w.horizontal + } + if vector == 270 { + w.horizontal, w.vertical = -w.vertical, w.horizontal + } + } else if action == 'L' { + if vector == 90 { + w.horizontal, w.vertical = -w.vertical, w.horizontal + } + if vector == 270 { + w.horizontal, w.vertical = w.vertical, -w.horizontal + } + } + return w +} + +func manhattan(i, j int) int { + return abs(i) + abs(j) +} + +func abs(x int) int { + if x < 0 { + return -x + } + return x +} + +func partOne() { + f, _ := os.Open("input") + reader := bufio.NewReader(f) + scanner := bufio.NewScanner(reader) + + s := ship{ + horizontal: 0, + vertical: 0, + direction: 'E', + } + + for scanner.Scan() { + dir, vec := parseLine(scanner.Text()) + s = movePartOne(s, dir, vec) + } + + fmt.Println(manhattan(s.horizontal, s.vertical)) +} + +func partTwo() { + f, _ := os.Open("input") + reader := bufio.NewReader(f) + scanner := bufio.NewScanner(reader) + + s := ship{ + horizontal: 0, + vertical: 0, + // no longer care about ship direction + } + w := waypoint{ + horizontal: 10, + vertical: 1, + } + + for scanner.Scan() { + dir, vec := parseLine(scanner.Text()) + s, w = movePartTwo(s, w, dir, vec) + } + + fmt.Println(manhattan(s.horizontal, s.vertical)) +}