add day 12
This commit is contained in:
parent
55fa312abf
commit
f5ec48772e
3
.gitignore
vendored
3
.gitignore
vendored
@ -1 +1,2 @@
|
||||
input
|
||||
input
|
||||
testinput
|
198
12/main.go
Normal file
198
12/main.go
Normal file
@ -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))
|
||||
}
|
Loading…
Reference in New Issue
Block a user