2019/day3/main.go
2019-12-04 17:20:16 +01:00

157 lines
3.4 KiB
Go

package main
import (
"bufio"
"log"
"math"
"os"
"strconv"
"strings"
)
type Point struct {
X int
Y int
}
func main() {
file, err := os.Open("input.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
if !scanner.Scan() {
log.Fatalln("Problem while read line.")
return
}
route1 := scanner.Text()
if !scanner.Scan() {
log.Fatalln("Problem while read second line.")
return
}
route2 := scanner.Text()
distance := GetShortestDistance(route1, route2)
routeDistance := GetShortestRoute(route1, route2)
log.Println("Part1: Distance: " + strconv.Itoa(distance))
log.Println("Part2: Route: " + strconv.Itoa(routeDistance))
}
func GetShortestDistance(route1 string, route2 string) int {
points1 := GetAllPointsFromRoute(ParseRoute(route1))
points2 := GetAllPointsFromRoute(ParseRoute(route2))
crossed := FindAllCrossedPoints(points1, points2)
distance := GetShortestDistanceFromPoints(crossed)
return distance
}
func GetShortestRoute(route1 string, route2 string) int {
points1 := GetAllPointsFromRoute(ParseRoute(route1))
points2 := GetAllPointsFromRoute(ParseRoute(route2))
crossed := FindAllCrossedPoints(points1, points2)
shortestDis := math.MaxInt32
for _, point := range crossed {
distance1 := GetRouteDistanceToPoint(points1, point)
distance2 := GetRouteDistanceToPoint(points2, point)
fullDistance := distance1 + distance2
if fullDistance < shortestDis {
shortestDis = fullDistance
}
}
return shortestDis
}
func ParseRoute(route string) []string {
return strings.Split(route, ",")
}
func GetAllPointsFromRoute(cmds []string) []Point {
var (
currentX int
currentY int
points []Point
)
for _, cmd := range cmds {
runes := []rune(cmd)
direction := string(runes[0])
lengthStr := string(runes[1:len(runes)])
length, _ := strconv.Atoi(lengthStr)
if direction == "R" {
for i := 1; i <= length; i++ {
currentX++
points = append(points, Point{X: currentX, Y: currentY})
}
} else if direction == "L" {
for i := 1; i <= length; i++ {
currentX--
points = append(points, Point{X: currentX, Y: currentY})
}
} else if direction == "U" {
for i := 1; i <= length; i++ {
currentY++
points = append(points, Point{X: currentX, Y: currentY})
}
} else if direction == "D" {
for i := 1; i <= length; i++ {
currentY--
points = append(points, Point{X: currentX, Y: currentY})
}
} else {
log.Fatal("ERROR Cmd: " + direction)
}
}
return points
}
func FindAllCrossedPoints(a []Point, b []Point) []Point {
crossedPoints := make([]Point, 0)
for _, pointA := range a {
for _, pointB := range b {
if pointA.X == pointB.X && pointA.Y == pointB.Y {
crossedPoints = append(crossedPoints, pointA)
}
}
}
return crossedPoints
}
func GetShortestDistanceFromPoints(points []Point) int {
shortestDis := math.MaxInt32
for _, point := range points {
distance := GetDistanceFromPoint(point)
if distance < shortestDis {
shortestDis = distance
}
}
return shortestDis
}
func GetRouteDistanceToPoint(route []Point, point Point) int {
sum := 0
for _, routePoint := range route {
sum++
if routePoint.X == point.X && routePoint.Y == point.Y {
break
}
}
return sum
}
func GetDistanceFromPoint(point Point) int {
return GetPositiveNumber(point.X) + GetPositiveNumber(point.Y)
}
func GetPositiveNumber(num int) int {
if num < 0 {
return -1 * num
}
return num
}