diff --git a/2021/day23/input b/2021/day23/input new file mode 100644 index 0000000..51ab079 --- /dev/null +++ b/2021/day23/input @@ -0,0 +1,5 @@ +############# +#...........# +###A#C#B#C### + #D#A#D#B# + ######### diff --git a/2021/day23/main.go b/2021/day23/main.go new file mode 100644 index 0000000..f0ea0f3 --- /dev/null +++ b/2021/day23/main.go @@ -0,0 +1,77 @@ +package main + +import ( + "fmt" + + h "git.bullercodeworks.com/brian/adventofcode/helpers" +) + +var costs map[byte]int +var homes map[byte][]h.Coordinate +var burrow h.CoordByteMap + +func main() { + costs = map[byte]int{'A': 1, 'B': 10, 'C': 100, 'D': 1000} + homes = map[byte][]h.Coordinate{ + 'A': []h.Coordinate{h.Coordinate{X: 3, Y: 3}, h.Coordinate{X: 3, Y: 2}}, + 'B': []h.Coordinate{h.Coordinate{X: 5, Y: 3}, h.Coordinate{X: 5, Y: 2}}, + 'C': []h.Coordinate{h.Coordinate{X: 7, Y: 3}, h.Coordinate{X: 7, Y: 2}}, + 'D': []h.Coordinate{h.Coordinate{X: 9, Y: 3}, h.Coordinate{X: 9, Y: 2}}, + } + inp := h.StdinToStringSlice() + burrow = h.StringSliceToCoordByteMap(inp) + fmt.Println(burrow) + pods := findAllPods() + for k, v := range pods { + fmt.Println(k, string(v)) + } +} + +func findAllPods() map[h.Coordinate]byte { + return burrow.FindAllNot(' ', '#', '.') +} + +func getHome(b byte) h.Coordinate { + // Returns the home spot for this pod... + if burrow.Get(homes[b][0]) == b { + return homes[b][1] + } + return homes[b][0] +} +func isPod(b byte) bool { + return b == 'A' || b == 'B' || b == 'C' || b == 'd' +} + +// pathClear checks: +// 1: is the given coordinate a pod? +// 2: is the path to the pod's home clear? +func pathClear(c h.Coordinate) bool { + v := burrow.Get(c) + if !isPod(v) { + return false + } + return canMoveFromTo(c, getHome(v)) +} + +func canMoveFromTo(from, to h.Coordinate) bool { + if from.Equals(to) { // Not actually moving... + return true + } + if burrow.Get(to) != '.' { + return false + } + if from.X == to.X { + // Just moving up or down + if from.Y > to.Y { + return canMoveFromTo(h.Coordinate{X: from.X, Y: from.Y - 1}, to) + } + return canMoveFromTo(h.Coordinate{X: from.X, Y: from.Y + 1}, to) + } else if from.Y == to.Y { + // Just moving left or right + if from.X > to.X { + return canMoveFromTo(h.Coordinate{X: from.X - 1, Y: from.Y}, to) + } + return canMoveFromTo(h.Coordinate{X: from.X + 1, Y: from.Y}, to) + } + +} diff --git a/2021/day23/testinput b/2021/day23/testinput new file mode 100644 index 0000000..69c4fc2 --- /dev/null +++ b/2021/day23/testinput @@ -0,0 +1,5 @@ +############# +#...........# +###B#C#B#D### + #A#D#C#A# + ######### diff --git a/2021/day23/work b/2021/day23/work new file mode 100644 index 0000000..6654265 --- /dev/null +++ b/2021/day23/work @@ -0,0 +1,22 @@ +{'A': 1, 'B': 10, 'C': 100, 'D': 1000} + +############# +#...........# +###A#B#C#.### + #A#B#C#D# + ######### + +A: 7, 2, 3, 7 +B: 5, 7, 3, 3 +C: 11 +D Min: 15 + +// 16277 is too low? +// 16330 is incorrect +// 16442 is too high +// 16512 is too high + +A: 2, 6, 2 +B: 4, 4, 7, 7 +C: 4, 3, 4 (C Min: 9) +D Min: 15 diff --git a/helpers/coordinateByteMap.go b/helpers/coordinateByteMap.go index 59d73ce..4d620ea 100644 --- a/helpers/coordinateByteMap.go +++ b/helpers/coordinateByteMap.go @@ -1,6 +1,9 @@ package aoc -import "fmt" +import ( + "errors" + "fmt" +) type CoordByteMap struct { Field map[Coordinate]byte @@ -32,6 +35,56 @@ func StringSliceToCoordByteMap(input []string) CoordByteMap { return ret } +// FindFirst searches left to right, top to bottom for the first +// instance of b. +func (m *CoordByteMap) FindFirst(b byte) (Coordinate, error) { + for y := m.TLY; y <= m.BRY; y++ { + for x := m.TLX; x <= m.BRX; x++ { + c := Coordinate{X: x, Y: y} + if m.Get(c) == b { + return c, nil + } + } + } + return Coordinate{}, errors.New("Not Found") +} + +func (m *CoordByteMap) FindAll(b ...byte) []Coordinate { + var ret []Coordinate + for y := m.TLY; y <= m.BRY; y++ { + for x := m.TLX; x <= m.BRX; x++ { + c := Coordinate{X: x, Y: y} + for i := range b { + if m.Get(c) == b[i] { + ret = append(ret, c) + } + } + } + } + return ret +} + +func (m *CoordByteMap) FindAllNot(b ...byte) map[Coordinate]byte { + ret := make(map[Coordinate]byte) + for y := m.TLY; y <= m.BRY; y++ { + for x := m.TLX; x <= m.BRX; x++ { + c := Coordinate{X: x, Y: y} + v := m.Get(c) + var is bool + for i := range b { + if v == b[i] { + is = true + break + } + } + if !is { + ret[c] = v + } + } + } + return ret +} + func (m *CoordByteMap) Count(b byte) int { var ret int for y := m.TLY; y <= m.BRY; y++ {