123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- package main
-
- import (
- "fmt"
- "github.com/csmith/aoc-2019/common"
- "math"
- "strings"
- )
-
- var directions = map[byte]common.Point{
- 'L': {X: -1, Y: 0},
- 'R': {X: +1, Y: 0},
- 'U': {X: 0, Y: -1},
- 'D': {X: 0, Y: +1},
- }
-
- // buildMap constructs a map of points that one or more wires hit, to a slice
- // of ints representing the number of steps each wire takes to reach that point.
- // The number of steps is 0 if the point is the origin or if the wire doesn't
- // reach that point.
- func buildMap(origin common.Point, wires []string) map[common.Point][]int64 {
- points := make(map[common.Point][]int64, 1000000)
-
- for n, wire := range wires {
- var (
- pos = origin
- steps int64 = 0
- moves = strings.Split(wire, ",")
- )
-
- for _, move := range moves {
- dir := directions[move[0]]
- length := common.MustAtoi(move[1:])
-
- for i := 0; i < length; i++ {
- pos = pos.Plus(dir)
- steps++
-
- val, ok := points[pos]
-
- if !ok {
- points[pos] = make([]int64, len(wires))
- val = points[pos]
- }
- val[n] = steps
- }
- }
- }
-
- return points
- }
-
- // combinedSteps computes the total number of steps each wire had to take, given a slice of measurements. If not all
- // wires have measurement, the second return parameter will be false.
- func combinedSteps(steps []int64) (int64, bool) {
- var res int64 = 0
- for _, distance := range steps {
- if distance == 0 {
- return 0, false
- } else {
- res += distance
- }
- }
- return res, true
- }
-
- func traceWires() (int64, int64) {
- wires := common.ReadFileAsStrings("03/input.txt")
- origin := common.Point{X: 0, Y: 0}
- points := buildMap(origin, wires)
-
- var (
- bestDistance int64 = math.MaxInt64
- bestSteps int64 = math.MaxInt64
- )
-
- for pos, v := range points {
- if combinedSteps, hitAll := combinedSteps(v); hitAll {
- if distance := pos.Manhattan(origin); distance < bestDistance {
- bestDistance = distance
- }
-
- if combinedSteps < bestSteps {
- bestSteps = combinedSteps
- }
- }
- }
-
- return bestDistance, bestSteps
- }
-
- func main() {
- part1, part2 := traceWires()
- fmt.Println(part1)
- fmt.Println(part2)
- }
|