From 975bc3346d86d2e620ae3deb50255d995af1df1c Mon Sep 17 00:00:00 2001 From: alexchao26 Date: Sat, 12 Dec 2020 01:14:53 -0500 Subject: [PATCH] 2020-day12: 243 on part 1, then confused the heck out of myself for part 2 w/ x/y vs row/col vs x,y coordinates and rotating around the origin.. --- 2020/day12/main.go | 108 +++++++++++++++++++++++++++++++++++----- 2020/day12/main_test.go | 20 ++++++-- 2 files changed, 111 insertions(+), 17 deletions(-) diff --git a/2020/day12/main.go b/2020/day12/main.go index eac4896..c396f7e 100644 --- a/2020/day12/main.go +++ b/2020/day12/main.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + "github.com/alexchao26/advent-of-code-go/mathutil" "github.com/alexchao26/advent-of-code-go/util" ) @@ -16,35 +17,118 @@ func main() { if part == 1 { ans := part1(util.ReadFile("./input.txt")) - util.CopyToClipboard(fmt.Sprintf("%v", ans)) fmt.Println("Output:", ans) } else { ans := part2(util.ReadFile("./input.txt")) - util.CopyToClipboard(fmt.Sprintf("%v", ans)) fmt.Println("Output:", ans) } } -func part1(input string) int { - parsed := parseInput(input) - _ = parsed +// globals for part 1 +var directions = []string{"N", "E", "S", "W"} +var directionsToDiff = map[string][2]int{ + // !! X and Y like a coordinate system! Not typical 2D matrices in algos + "N": [2]int{0, 1}, + "E": [2]int{1, 0}, + "S": [2]int{0, -1}, + "W": [2]int{-1, 0}, +} - return 0 +func part1(input string) int { + instructions := parseInput(input) + + // X and Y like a coordinate system + var shipX, shipY int + dirIndex := 1 // index in directions slice + for _, inst := range instructions { + switch inst.action { + case "N": + shipY += inst.value + case "S": + shipY -= inst.value + case "E": + shipX += inst.value + case "W": + shipX -= inst.value + case "L": + // rotate ship left, this is equivalent + // -1 + 4 to keeping dirIndex positive for the modding + dirIndex += (-1 + 4) * inst.value / 90 + dirIndex %= 4 + case "R": + dirIndex += inst.value / 90 + dirIndex %= 4 + case "F": + d := directionsToDiff[directions[dirIndex]] + shipX += d[0] * inst.value + shipY += d[1] * inst.value + default: + panic("unexpected action") + } + } + + return mathutil.ManhattanDistance(0, 0, shipX, shipY) } func part2(input string) int { - parsed := parseInput(input) - _ = parsed + instructions := parseInput(input) - return 0 + // X and Y like a coordinate system + waypointX := 10 + waypointY := 1 + var shipX, shipY int + + for _, inst := range instructions { + switch inst.action { + case "N": + waypointY += inst.value + case "S": + waypointY -= inst.value + case "E": + waypointX += inst.value + case "W": + waypointX -= inst.value + case "L": + // rotate waypoint left around ship (origin) + turns := inst.value / 90 + for turns > 0 { + // this simple bit is all it needs to rotate around the origin + // I had a 20 line if/else block... + waypointX, waypointY = -waypointY, waypointX + turns-- + } + case "R": + turns := inst.value / 90 + for turns > 0 { + waypointX, waypointY = waypointY, -waypointX + turns-- + } + case "F": + shipX += inst.value * waypointX + shipY += inst.value * waypointY + default: + panic("unexpected action") + } + } + + return mathutil.ManhattanDistance(0, 0, shipX, shipY) } -func parseInput(input string) []int { - var ans []int +type instruction struct { + action string + value int +} + +func parseInput(input string) []instruction { + var ans []instruction lines := strings.Split(input, "\n") for _, l := range lines { - ans = append(ans, mathutil.StrToInt(l)) + inst := instruction{ + action: l[:1], + value: mathutil.StrToInt(l[1:]), + } + ans = append(ans, inst) } return ans diff --git a/2020/day12/main_test.go b/2020/day12/main_test.go index ee82d4e..ed3fe01 100644 --- a/2020/day12/main_test.go +++ b/2020/day12/main_test.go @@ -1,14 +1,24 @@ package main -import "testing" +import ( + "testing" + + "github.com/alexchao26/advent-of-code-go/util" +) + +var exampleInput = `F10 +N3 +F7 +R90 +F11` var tests1 = []struct { name string want int input string - // add extra args if needed }{ - // {"actual", ACTUAL_ANSWER, util.ReadFile("input.txt")}, + {"example", 25, exampleInput}, + {"actual", 820, util.ReadFile("input.txt")}, } func TestPart1(t *testing.T) { @@ -25,9 +35,9 @@ var tests2 = []struct { name string want int input string - // add extra args if needed }{ - // {"actual", ACTUAL_ANSWER, util.ReadFile("input.txt")}, + {"example", 286, exampleInput}, + {"actual", 66614, util.ReadFile("input.txt")}, } func TestPart2(t *testing.T) {