2019 Day 15 Complete
This commit is contained in:
parent
14fcb13c3c
commit
068b018cc0
@ -12,29 +12,32 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var auto bool
|
var auto bool
|
||||||
|
|
||||||
var maze *Maze
|
var maze *Maze
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
progFileName := "input"
|
progFileName := "input"
|
||||||
|
|
||||||
if len(os.Args) > 1 && os.Args[1] == "-auto" {
|
|
||||||
auto = true
|
auto = true
|
||||||
|
|
||||||
|
if len(os.Args) > 1 && os.Args[1] == "-manual" {
|
||||||
|
auto = false
|
||||||
}
|
}
|
||||||
prog := intcode.ReadIntCodeFile(progFileName)
|
prog := intcode.ReadIntCodeFile(progFileName)
|
||||||
maze = NewMaze()
|
maze = NewMaze()
|
||||||
|
|
||||||
play(prog)
|
part1(prog)
|
||||||
|
part2()
|
||||||
}
|
}
|
||||||
|
|
||||||
func play(prog []int) {
|
var all map[string]*MazeCoord
|
||||||
|
|
||||||
|
func part1(prog []int) {
|
||||||
p := intcode.NewProgram(prog)
|
p := intcode.NewProgram(prog)
|
||||||
go func() {
|
go func() {
|
||||||
var roadTaken []helpers.Coordinate
|
var roadTaken []helpers.Coordinate
|
||||||
for {
|
for {
|
||||||
time.Sleep(500)
|
//time.Sleep(500)
|
||||||
fmt.Println(helpers.CLEAR_SCREEN)
|
//fmt.Println(helpers.CLEAR_SCREEN)
|
||||||
maze.Print()
|
//maze.Print()
|
||||||
for !p.NeedsInput() {
|
for !p.NeedsInput() {
|
||||||
time.Sleep(1)
|
time.Sleep(1)
|
||||||
}
|
}
|
||||||
@ -110,40 +113,118 @@ func play(prog []int) {
|
|||||||
fmt.Println(helpers.CLEAR_SCREEN)
|
fmt.Println(helpers.CLEAR_SCREEN)
|
||||||
maze.Print()
|
maze.Print()
|
||||||
fmt.Println("Now find shortest path")
|
fmt.Println("Now find shortest path")
|
||||||
done, ret := BFS(maze.bfs[maze.startCoord], maze.bfs[maze.o2Coord])
|
all = make(map[string]*MazeCoord)
|
||||||
if done {
|
for k, v := range maze.maze {
|
||||||
fmt.Println("Found Route")
|
if v == MAZE_EMPTY || v == MAZE_O2SYS {
|
||||||
} else {
|
c := helpers.CoordinateFromString(k)
|
||||||
fmt.Println("No Route Found")
|
m := &MazeCoord{coord: c}
|
||||||
|
m.Distance = helpers.MAX_INT
|
||||||
|
all[c.String()] = m
|
||||||
}
|
}
|
||||||
fmt.Println("Steps:", len(ret))
|
}
|
||||||
|
for _, v := range all {
|
||||||
|
n, ok := all[v.coord.GetNorthCoord().String()]
|
||||||
|
if ok {
|
||||||
|
v.N = n
|
||||||
|
}
|
||||||
|
e, ok := all[v.coord.GetEastCoord().String()]
|
||||||
|
if ok {
|
||||||
|
v.E = e
|
||||||
|
}
|
||||||
|
s, ok := all[v.coord.GetSouthCoord().String()]
|
||||||
|
if ok {
|
||||||
|
v.S = s
|
||||||
|
}
|
||||||
|
w, ok := all[v.coord.GetWestCoord().String()]
|
||||||
|
if ok {
|
||||||
|
v.W = w
|
||||||
|
}
|
||||||
|
}
|
||||||
|
start := all[maze.startCoord.String()]
|
||||||
|
start.Distance = 0
|
||||||
|
fmt.Println("Processing. . .")
|
||||||
|
ProcessNode(start, 0)
|
||||||
|
fmt.Println("Distance to O2:", all[maze.o2Coord.String()].Distance)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BFS(start, goal *BFSNode) (bool, []*BFSNode) {
|
func ProcessNode(m *MazeCoord, steps int) {
|
||||||
var queue, explored []*BFSNode
|
if m.coord.String() == maze.o2Coord.String() {
|
||||||
queue = append(queue, start)
|
return
|
||||||
if start == goal {
|
|
||||||
fmt.Println(queue)
|
|
||||||
return true, queue
|
|
||||||
}
|
}
|
||||||
explored = append(explored, start)
|
for _, neighbor := range []*MazeCoord{m.N, m.E, m.S, m.W} {
|
||||||
for len(queue) > 0 {
|
if neighbor == nil {
|
||||||
var current *BFSNode
|
continue
|
||||||
if len(queue) > 1 {
|
}
|
||||||
current, queue = queue[0], queue[1:]
|
wrk, ok := all[neighbor.coord.String()]
|
||||||
if current == goal {
|
if ok {
|
||||||
fmt.Println(explored)
|
if m.Distance+1 < wrk.Distance {
|
||||||
return true, explored
|
wrk.Distance = m.Distance + 1
|
||||||
} else {
|
if !wrk.Visited {
|
||||||
children := current.getChildren()
|
ProcessNode(wrk, m.Distance+1)
|
||||||
if len(children) != 0 {
|
|
||||||
queue = append(queue, children...)
|
|
||||||
} else {
|
|
||||||
return false, explored
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
explored = append(explored, current)
|
|
||||||
}
|
}
|
||||||
return false, explored
|
m.Visited = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func part2() {
|
||||||
|
// We're going to reuse the visited flag for oxygen
|
||||||
|
for _, v := range all {
|
||||||
|
v.Visited = false
|
||||||
|
}
|
||||||
|
fmt.Println("Unfilled", countUnfilledSpaces())
|
||||||
|
all[maze.o2Coord.String()].Visited = true
|
||||||
|
var cnt int
|
||||||
|
for countUnfilledSpaces() > 0 {
|
||||||
|
tick()
|
||||||
|
fmt.Println("Unfilled", countUnfilledSpaces())
|
||||||
|
cnt++
|
||||||
|
}
|
||||||
|
fmt.Println("Minutes:", cnt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func countUnfilledSpaces() int {
|
||||||
|
var count int
|
||||||
|
for _, v := range all {
|
||||||
|
if !v.Visited {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
func tick() bool {
|
||||||
|
// Start with the o2 coord
|
||||||
|
var toFill []*MazeCoord
|
||||||
|
for _, v := range all {
|
||||||
|
if v.N != nil && v.N.Visited {
|
||||||
|
toFill = append(toFill, v)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if v.E != nil && v.E.Visited {
|
||||||
|
toFill = append(toFill, v)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if v.S != nil && v.S.Visited {
|
||||||
|
toFill = append(toFill, v)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if v.W != nil && v.W.Visited {
|
||||||
|
toFill = append(toFill, v)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for k := range toFill {
|
||||||
|
all[toFill[k].coord.String()].Visited = true
|
||||||
|
}
|
||||||
|
fmt.Println("Filled", len(toFill), "spaces")
|
||||||
|
return len(toFill) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type MazeCoord struct {
|
||||||
|
coord *helpers.Coordinate
|
||||||
|
N, S, E, W *MazeCoord
|
||||||
|
Distance int
|
||||||
|
Visited bool
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,6 @@ type Maze struct {
|
|||||||
dirHistory []int
|
dirHistory []int
|
||||||
dnt bool
|
dnt bool
|
||||||
|
|
||||||
bfs map[*helpers.Coordinate]*BFSNode
|
|
||||||
|
|
||||||
startCoord *helpers.Coordinate
|
startCoord *helpers.Coordinate
|
||||||
o2Coord *helpers.Coordinate
|
o2Coord *helpers.Coordinate
|
||||||
}
|
}
|
||||||
@ -43,7 +41,6 @@ func NewMaze() *Maze {
|
|||||||
maxY: helpers.MIN_INT,
|
maxY: helpers.MIN_INT,
|
||||||
minY: helpers.MAX_INT,
|
minY: helpers.MAX_INT,
|
||||||
bot: helpers.NewCoordinate(0, 0),
|
bot: helpers.NewCoordinate(0, 0),
|
||||||
bfs: make(map[*helpers.Coordinate]*BFSNode),
|
|
||||||
startCoord: helpers.NewCoordinate(0, 0),
|
startCoord: helpers.NewCoordinate(0, 0),
|
||||||
}
|
}
|
||||||
m.path = append(m.path, helpers.NewCoordinate(0, 0))
|
m.path = append(m.path, helpers.NewCoordinate(0, 0))
|
||||||
@ -51,29 +48,6 @@ func NewMaze() *Maze {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Maze) SetCoord(c *helpers.Coordinate, val int) {
|
func (m *Maze) SetCoord(c *helpers.Coordinate, val int) {
|
||||||
var b *BFSNode
|
|
||||||
var ok bool
|
|
||||||
if b, ok = m.bfs[c]; !ok {
|
|
||||||
b = &BFSNode{Value: val}
|
|
||||||
m.bfs[c] = b
|
|
||||||
}
|
|
||||||
// Create the BFS node for this
|
|
||||||
if n, ok := m.bfs[c.GetNorthCoord()]; ok {
|
|
||||||
n.South = b
|
|
||||||
b.North = n
|
|
||||||
}
|
|
||||||
if e, ok := m.bfs[c.GetEastCoord()]; ok {
|
|
||||||
e.West = b
|
|
||||||
b.East = e
|
|
||||||
}
|
|
||||||
if s, ok := m.bfs[c.GetSouthCoord()]; ok {
|
|
||||||
s.North = b
|
|
||||||
b.South = s
|
|
||||||
}
|
|
||||||
if w, ok := m.bfs[c.GetWestCoord()]; ok {
|
|
||||||
w.East = b
|
|
||||||
b.West = w
|
|
||||||
}
|
|
||||||
if val == 2 {
|
if val == 2 {
|
||||||
m.o2Coord = c
|
m.o2Coord = c
|
||||||
}
|
}
|
||||||
@ -170,26 +144,3 @@ func (m *Maze) Print() {
|
|||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type BFSNode struct {
|
|
||||||
Value int
|
|
||||||
North, East *BFSNode
|
|
||||||
South, West *BFSNode
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BFSNode) getChildren() []*BFSNode {
|
|
||||||
var ret []*BFSNode
|
|
||||||
if b.North != nil {
|
|
||||||
ret = append(ret, b.North)
|
|
||||||
}
|
|
||||||
if b.East != nil {
|
|
||||||
ret = append(ret, b.East)
|
|
||||||
}
|
|
||||||
if b.South != nil {
|
|
||||||
ret = append(ret, b.South)
|
|
||||||
}
|
|
||||||
if b.West != nil {
|
|
||||||
ret = append(ret, b.West)
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
@ -42,7 +42,7 @@ func (c *Coordinate) GetWestCoord() *Coordinate {
|
|||||||
func CoordinateFromString(str string) *Coordinate {
|
func CoordinateFromString(str string) *Coordinate {
|
||||||
c := Coordinate{}
|
c := Coordinate{}
|
||||||
r := strings.NewReader(str)
|
r := strings.NewReader(str)
|
||||||
_, err := fmt.Fscanf(r, "[%d, %d]", c.X, c.Y)
|
_, err := fmt.Fscanf(r, "[%d, %d]", &c.X, &c.Y)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user