2019 Day 15 Complete
This commit is contained in:
@@ -12,29 +12,32 @@ import (
|
||||
)
|
||||
|
||||
var auto bool
|
||||
|
||||
var maze *Maze
|
||||
|
||||
func main() {
|
||||
progFileName := "input"
|
||||
auto = true
|
||||
|
||||
if len(os.Args) > 1 && os.Args[1] == "-auto" {
|
||||
auto = true
|
||||
if len(os.Args) > 1 && os.Args[1] == "-manual" {
|
||||
auto = false
|
||||
}
|
||||
prog := intcode.ReadIntCodeFile(progFileName)
|
||||
maze = NewMaze()
|
||||
|
||||
play(prog)
|
||||
part1(prog)
|
||||
part2()
|
||||
}
|
||||
|
||||
func play(prog []int) {
|
||||
var all map[string]*MazeCoord
|
||||
|
||||
func part1(prog []int) {
|
||||
p := intcode.NewProgram(prog)
|
||||
go func() {
|
||||
var roadTaken []helpers.Coordinate
|
||||
for {
|
||||
time.Sleep(500)
|
||||
fmt.Println(helpers.CLEAR_SCREEN)
|
||||
maze.Print()
|
||||
//time.Sleep(500)
|
||||
//fmt.Println(helpers.CLEAR_SCREEN)
|
||||
//maze.Print()
|
||||
for !p.NeedsInput() {
|
||||
time.Sleep(1)
|
||||
}
|
||||
@@ -110,40 +113,118 @@ func play(prog []int) {
|
||||
fmt.Println(helpers.CLEAR_SCREEN)
|
||||
maze.Print()
|
||||
fmt.Println("Now find shortest path")
|
||||
done, ret := BFS(maze.bfs[maze.startCoord], maze.bfs[maze.o2Coord])
|
||||
if done {
|
||||
fmt.Println("Found Route")
|
||||
} else {
|
||||
fmt.Println("No Route Found")
|
||||
all = make(map[string]*MazeCoord)
|
||||
for k, v := range maze.maze {
|
||||
if v == MAZE_EMPTY || v == MAZE_O2SYS {
|
||||
c := helpers.CoordinateFromString(k)
|
||||
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) {
|
||||
var queue, explored []*BFSNode
|
||||
queue = append(queue, start)
|
||||
if start == goal {
|
||||
fmt.Println(queue)
|
||||
return true, queue
|
||||
func ProcessNode(m *MazeCoord, steps int) {
|
||||
if m.coord.String() == maze.o2Coord.String() {
|
||||
return
|
||||
}
|
||||
explored = append(explored, start)
|
||||
for len(queue) > 0 {
|
||||
var current *BFSNode
|
||||
if len(queue) > 1 {
|
||||
current, queue = queue[0], queue[1:]
|
||||
if current == goal {
|
||||
fmt.Println(explored)
|
||||
return true, explored
|
||||
} else {
|
||||
children := current.getChildren()
|
||||
if len(children) != 0 {
|
||||
queue = append(queue, children...)
|
||||
} else {
|
||||
return false, explored
|
||||
for _, neighbor := range []*MazeCoord{m.N, m.E, m.S, m.W} {
|
||||
if neighbor == nil {
|
||||
continue
|
||||
}
|
||||
wrk, ok := all[neighbor.coord.String()]
|
||||
if ok {
|
||||
if m.Distance+1 < wrk.Distance {
|
||||
wrk.Distance = m.Distance + 1
|
||||
if !wrk.Visited {
|
||||
ProcessNode(wrk, m.Distance+1)
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user