diff --git a/2020/day12.go b/2020/day12.go new file mode 100644 index 0000000..aba0432 --- /dev/null +++ b/2020/day12.go @@ -0,0 +1,148 @@ +package main + +import ( + "fmt" + "log" + "os" + "strconv" + + "git.annabunch.es/annabunches/adventofcode/2020/lib/fileutils" +) + +func distance(x1, y1, x2, y2 int) int { + dy := y2 - y1 + dx := x2 - x1 + if dy < 0 { + dy *= -1 + } + if dx < 0 { + dx *= -1 + } + return dx + dy +} + +func rotate(x, y int, direction byte, degrees int) (int, int) { + turns := degrees / 90 + + newX := x + newY := y + + for i := 0; i < turns; i++ { + hold := newX + newX = newY + newY = hold + + switch direction { + case 'L': + newX *= -1 + case 'R': + newY *= -1 + } + } + + return newX, newY +} + +func step1(values []string) (int, int) { + facing := 90 + x := 0 + y := 0 + + for _, line := range values { + direction := line[0] + value, err := strconv.Atoi(line[1:]) + if err != nil { + log.Panicf(err.Error()) + } + switch direction { + case 'N': + y += value + case 'S': + y -= value + case 'E': + x += value + case 'W': + x -= value + case 'L': + facing -= value + case 'R': + facing += value + case 'F': + // the hard one + switch facing { + case 0: + y += value + case 90: + x += value + case 180: + y -= value + case 270: + x -= value + default: + log.Panicf("Oh no, ships can't face %d degrees!", facing) + } + } + + if facing < 0 { + facing += 360 + } + + if facing >= 360 { + facing %= 360 + } + } + + return x, y +} + +func step2(values []string) (int, int) { + x := 0 + y := 0 + wayX := 10 + wayY := 1 + + for _, line := range values { + direction := line[0] + value, err := strconv.Atoi(line[1:]) + if err != nil { + log.Panicf(err.Error()) + } + switch direction { + case 'N': + wayY += value + case 'S': + wayY -= value + case 'E': + wayX += value + case 'W': + wayX -= value + case 'L': + wayX, wayY = rotate(wayX, wayY, direction, value) + case 'R': + wayX, wayY = rotate(wayX, wayY, direction, value) + case 'F': + for i := 0; i < value; i++ { + x += wayX + y += wayY + } + } + } + + return x, y +} + +func main() { + step := os.Args[1] + values := fileutils.InputParserStrings(os.Args[2]) + + x := 0 + y := 0 + switch step { + case "1": + x, y = step1(values) + case "2": + x, y = step2(values) + } + + fmt.Println(distance(x, y, 0, 0)) +} diff --git a/2020/lib/fileutils/fileutils.go b/2020/lib/fileutils/fileutils.go index a26cde4..506cc15 100644 --- a/2020/lib/fileutils/fileutils.go +++ b/2020/lib/fileutils/fileutils.go @@ -57,7 +57,8 @@ func InputParserStrings(filename string) []string { if err != nil { log.Panicf(err.Error()) } - return strings.Split(string(data), "\n") + output := strings.Split(string(data), "\n") + return output[:len(output)-1] } func InputParserBytes(filename string) [][]byte {