package main import ( "fmt" "math" h "git.bullercodeworks.com/brian/adventofcode/helpers" ) func main() { inp := h.StdinToCoordMap() start, _ := inp.FindFirst('S') end, _ := inp.FindFirst('E') score, seats := bfs(inp, start, end) fmt.Println("# Part 1") fmt.Println("Minimum Score:", score) fmt.Println("# Part 2") fmt.Println("Best Seats:", seats) } func bfs(inp h.CoordByteMap, s, e h.Coordinate) (int, int) { start := CD{c: s, d: E} minScore := math.MaxInt queue := []State{ { pos: start, path: []h.Coordinate{}, }, } visited := make(map[CD]int) sizeToC := make(map[int][]h.Coordinate) for len(queue) > 0 { currState := queue[0] queue = queue[1:] if currState.score > minScore { continue } if currState.pos.c.Equals(e) { if currState.score <= minScore { minScore = currState.score sizeToC[minScore] = append(sizeToC[minScore], currState.path...) } continue } for _, n := range currState.pos.GetNeighbors() { if inp.Get(n.c) == '#' { continue } score := currState.score + 1 if currState.pos.d != n.d { score += 1000 } if prev, ok := visited[n]; ok { if prev < score { continue } } visited[n] = score np := make([]h.Coordinate, len(currState.path)) copy(np, currState.path) queue = append(queue, State{ pos: n, path: append(np, n.c), score: score, }) } } seatMap := make(map[h.Coordinate]bool) for _, p := range sizeToC[minScore] { seatMap[p] = true } /* for y := inp.TLY; y <= inp.BRY; y++ { for x := inp.TLX; x <= inp.BRX; x++ { c := h.Coordinate{X: x, Y: y} if _, ok := seatMap[c]; ok { fmt.Print("O") } else { fmt.Print(string(inp.Get(c))) } } fmt.Println() } */ return minScore, len(seatMap) + 1 } var ( N = h.Coordinate{X: 0, Y: -1} E = h.Coordinate{X: 1, Y: 0} S = h.Coordinate{X: 0, Y: 1} W = h.Coordinate{X: -1, Y: 0} Dirs = []h.Coordinate{N, E, S, W} ) type CD struct { c, d h.Coordinate } func (cd CD) GetNeighbors() []CD { var ret []CD opp := h.Coordinate{X: -cd.d.X, Y: -cd.d.Y} for _, dir := range Dirs { if !dir.Equals(opp) { ret = append(ret, CD{ c: cd.c.Add(dir), d: dir, }) } } return ret } type State struct { pos CD path []h.Coordinate score int }