From 629f47bcf966505227a72c1357a267d1133cdeb7 Mon Sep 17 00:00:00 2001 From: Brian Buller Date: Wed, 18 Dec 2019 07:25:25 -0600 Subject: [PATCH] Moving right along --- 2019/day15/main.go | 45 ++++++++++-- 2019/day15/maze.go | 68 +++++++++++++++-- 2019/day17/input | 1 + 2019/day17/main.go | 22 ++++++ 2019/day17/part1.go | 69 +++++++++++++++++ 2019/day17/part2.go | 94 ++++++++++++++++++++++++ 2019/day17/walk.go | 175 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 462 insertions(+), 12 deletions(-) create mode 100644 2019/day17/input create mode 100644 2019/day17/main.go create mode 100644 2019/day17/part1.go create mode 100644 2019/day17/part2.go create mode 100644 2019/day17/walk.go diff --git a/2019/day15/main.go b/2019/day15/main.go index 61be563..44cb4fa 100644 --- a/2019/day15/main.go +++ b/2019/day15/main.go @@ -104,11 +104,44 @@ func play(prog []int) { } } }() - ret := p.Run() - if ret == intcode.RET_DONE { - maze.Print() - } else if ret == intcode.RET_ERR { - fmt.Println("ERROR") - fmt.Println(p.Error()) + p.Run() + //We force quit the program when the maze is built. + // Now we find the quickest path through the maze. + 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") } + fmt.Println("Steps:", len(ret)) +} + +func BFS(start, goal *BFSNode) (bool, []*BFSNode) { + var queue, explored []*BFSNode + queue = append(queue, start) + if start == goal { + return true, queue + } + explored = append(explored, start) + for len(queue) > 0 { + var current *BFSNode + if len(queue) > 1 { + current, queue = queue[0], queue[1:] + if current == goal { + return true, explored + } else { + children := current.getChildren() + if len(children) != 0 { + queue = append(queue, children...) + } else { + return false, explored + } + } + } + explored = append(explored, current) + } + return false, explored } diff --git a/2019/day15/maze.go b/2019/day15/maze.go index 94a117b..403c6b5 100644 --- a/2019/day15/maze.go +++ b/2019/day15/maze.go @@ -28,22 +28,55 @@ type Maze struct { path []*helpers.Coordinate dirHistory []int dnt bool + + bfs map[*helpers.Coordinate]*BFSNode + + startCoord *helpers.Coordinate + o2Coord *helpers.Coordinate } func NewMaze() *Maze { m := &Maze{ - maze: make(map[string]int), - maxX: helpers.MIN_INT, - minX: helpers.MAX_INT, - maxY: helpers.MIN_INT, - minY: helpers.MAX_INT, - bot: helpers.NewCoordinate(0, 0), + maze: make(map[string]int), + maxX: helpers.MIN_INT, + minX: helpers.MAX_INT, + maxY: helpers.MIN_INT, + minY: helpers.MAX_INT, + bot: helpers.NewCoordinate(0, 0), + bfs: make(map[*helpers.Coordinate]*BFSNode), + startCoord: helpers.NewCoordinate(0, 0), } m.path = append(m.path, helpers.NewCoordinate(0, 0)) return m } 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 { + m.o2Coord = c + } m.maze[c.String()] = val if m.maxX < c.X { m.maxX = c.X @@ -137,3 +170,26 @@ func (m *Maze) Print() { 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 +} diff --git a/2019/day17/input b/2019/day17/input new file mode 100644 index 0000000..9b291d5 --- /dev/null +++ b/2019/day17/input @@ -0,0 +1 @@ +1,330,331,332,109,2608,1102,1182,1,16,1101,1399,0,24,102,1,0,570,1006,570,36,102,1,571,0,1001,570,-1,570,1001,24,1,24,1105,1,18,1008,571,0,571,1001,16,1,16,1008,16,1399,570,1006,570,14,21102,1,58,0,1105,1,786,1006,332,62,99,21102,333,1,1,21101,0,73,0,1106,0,579,1101,0,0,572,1101,0,0,573,3,574,101,1,573,573,1007,574,65,570,1005,570,151,107,67,574,570,1005,570,151,1001,574,-64,574,1002,574,-1,574,1001,572,1,572,1007,572,11,570,1006,570,165,101,1182,572,127,102,1,574,0,3,574,101,1,573,573,1008,574,10,570,1005,570,189,1008,574,44,570,1006,570,158,1106,0,81,21102,340,1,1,1105,1,177,21101,0,477,1,1106,0,177,21102,514,1,1,21101,0,176,0,1106,0,579,99,21101,184,0,0,1106,0,579,4,574,104,10,99,1007,573,22,570,1006,570,165,1001,572,0,1182,21101,375,0,1,21101,211,0,0,1106,0,579,21101,1182,11,1,21102,222,1,0,1105,1,979,21102,388,1,1,21101,0,233,0,1105,1,579,21101,1182,22,1,21101,0,244,0,1105,1,979,21101,401,0,1,21101,0,255,0,1105,1,579,21101,1182,33,1,21101,266,0,0,1105,1,979,21101,0,414,1,21101,0,277,0,1105,1,579,3,575,1008,575,89,570,1008,575,121,575,1,575,570,575,3,574,1008,574,10,570,1006,570,291,104,10,21101,1182,0,1,21102,313,1,0,1105,1,622,1005,575,327,1101,1,0,575,21102,327,1,0,1106,0,786,4,438,99,0,1,1,6,77,97,105,110,58,10,33,10,69,120,112,101,99,116,101,100,32,102,117,110,99,116,105,111,110,32,110,97,109,101,32,98,117,116,32,103,111,116,58,32,0,12,70,117,110,99,116,105,111,110,32,65,58,10,12,70,117,110,99,116,105,111,110,32,66,58,10,12,70,117,110,99,116,105,111,110,32,67,58,10,23,67,111,110,116,105,110,117,111,117,115,32,118,105,100,101,111,32,102,101,101,100,63,10,0,37,10,69,120,112,101,99,116,101,100,32,82,44,32,76,44,32,111,114,32,100,105,115,116,97,110,99,101,32,98,117,116,32,103,111,116,58,32,36,10,69,120,112,101,99,116,101,100,32,99,111,109,109,97,32,111,114,32,110,101,119,108,105,110,101,32,98,117,116,32,103,111,116,58,32,43,10,68,101,102,105,110,105,116,105,111,110,115,32,109,97,121,32,98,101,32,97,116,32,109,111,115,116,32,50,48,32,99,104,97,114,97,99,116,101,114,115,33,10,94,62,118,60,0,1,0,-1,-1,0,1,0,0,0,0,0,0,1,4,0,0,109,4,2101,0,-3,587,20101,0,0,-1,22101,1,-3,-3,21101,0,0,-2,2208,-2,-1,570,1005,570,617,2201,-3,-2,609,4,0,21201,-2,1,-2,1105,1,597,109,-4,2106,0,0,109,5,2101,0,-4,629,21002,0,1,-2,22101,1,-4,-4,21102,0,1,-3,2208,-3,-2,570,1005,570,781,2201,-4,-3,653,20101,0,0,-1,1208,-1,-4,570,1005,570,709,1208,-1,-5,570,1005,570,734,1207,-1,0,570,1005,570,759,1206,-1,774,1001,578,562,684,1,0,576,576,1001,578,566,692,1,0,577,577,21101,702,0,0,1105,1,786,21201,-1,-1,-1,1106,0,676,1001,578,1,578,1008,578,4,570,1006,570,724,1001,578,-4,578,21102,1,731,0,1105,1,786,1105,1,774,1001,578,-1,578,1008,578,-1,570,1006,570,749,1001,578,4,578,21101,756,0,0,1106,0,786,1105,1,774,21202,-1,-11,1,22101,1182,1,1,21101,0,774,0,1105,1,622,21201,-3,1,-3,1106,0,640,109,-5,2105,1,0,109,7,1005,575,802,21002,576,1,-6,21002,577,1,-5,1106,0,814,21101,0,0,-1,21102,1,0,-5,21101,0,0,-6,20208,-6,576,-2,208,-5,577,570,22002,570,-2,-2,21202,-5,39,-3,22201,-6,-3,-3,22101,1399,-3,-3,1202,-3,1,843,1005,0,863,21202,-2,42,-4,22101,46,-4,-4,1206,-2,924,21102,1,1,-1,1105,1,924,1205,-2,873,21102,35,1,-4,1105,1,924,1202,-3,1,878,1008,0,1,570,1006,570,916,1001,374,1,374,2101,0,-3,895,1101,2,0,0,2102,1,-3,902,1001,438,0,438,2202,-6,-5,570,1,570,374,570,1,570,438,438,1001,578,558,922,20101,0,0,-4,1006,575,959,204,-4,22101,1,-6,-6,1208,-6,39,570,1006,570,814,104,10,22101,1,-5,-5,1208,-5,31,570,1006,570,810,104,10,1206,-1,974,99,1206,-1,974,1101,0,1,575,21102,973,1,0,1105,1,786,99,109,-7,2105,1,0,109,6,21102,0,1,-4,21101,0,0,-3,203,-2,22101,1,-3,-3,21208,-2,82,-1,1205,-1,1030,21208,-2,76,-1,1205,-1,1037,21207,-2,48,-1,1205,-1,1124,22107,57,-2,-1,1205,-1,1124,21201,-2,-48,-2,1105,1,1041,21102,1,-4,-2,1105,1,1041,21102,-5,1,-2,21201,-4,1,-4,21207,-4,11,-1,1206,-1,1138,2201,-5,-4,1059,2101,0,-2,0,203,-2,22101,1,-3,-3,21207,-2,48,-1,1205,-1,1107,22107,57,-2,-1,1205,-1,1107,21201,-2,-48,-2,2201,-5,-4,1090,20102,10,0,-1,22201,-2,-1,-2,2201,-5,-4,1103,2101,0,-2,0,1106,0,1060,21208,-2,10,-1,1205,-1,1162,21208,-2,44,-1,1206,-1,1131,1106,0,989,21102,1,439,1,1105,1,1150,21102,1,477,1,1106,0,1150,21101,514,0,1,21102,1149,1,0,1105,1,579,99,21101,0,1157,0,1105,1,579,204,-2,104,10,99,21207,-3,22,-1,1206,-1,1138,2101,0,-5,1176,2101,0,-4,0,109,-6,2106,0,0,0,5,34,1,38,1,38,1,38,11,3,11,24,1,3,1,34,1,3,1,34,1,3,1,30,5,3,1,30,1,7,1,30,1,7,1,1,11,3,9,6,1,7,1,1,1,9,1,3,1,7,1,6,5,3,5,7,1,3,1,7,1,10,1,5,1,1,1,7,1,3,1,7,1,4,5,1,1,5,1,1,1,7,5,7,1,4,1,3,1,1,1,5,1,1,1,19,1,4,1,3,1,1,1,3,5,19,1,4,1,3,1,1,1,3,1,1,1,21,1,4,1,3,11,19,1,4,1,5,1,3,1,1,1,1,1,19,12,1,5,1,1,15,6,3,1,7,1,1,1,3,1,15,1,4,1,3,1,7,1,1,1,3,1,15,1,4,1,3,1,7,1,1,1,3,1,15,1,4,5,7,11,11,1,18,1,3,1,3,1,11,1,18,11,9,1,22,1,3,1,1,1,9,1,22,5,1,1,9,1,28,1,9,1,28,11,4 diff --git a/2019/day17/main.go b/2019/day17/main.go new file mode 100644 index 0000000..45fc833 --- /dev/null +++ b/2019/day17/main.go @@ -0,0 +1,22 @@ +package main + +import ( + intcode "git.bullercodeworks.com/brian/adventofcode/2019/intcode-processor" + helpers "git.bullercodeworks.com/brian/adventofcode/helpers" +) + +var layout [][]byte + +func main() { + pt := helpers.GetArgNumber(1) + prog := intcode.ReadIntCodeFile("input") + + if pt == "1" { + part1(prog) + } else if pt == "walk" { + part1(prog) + walk() + } else { + part2(prog) + } +} diff --git a/2019/day17/part1.go b/2019/day17/part1.go new file mode 100644 index 0000000..1fc22e5 --- /dev/null +++ b/2019/day17/part1.go @@ -0,0 +1,69 @@ +package main + +import ( + "fmt" + intcode "git.bullercodeworks.com/brian/adventofcode/2019/intcode-processor" + "time" +) + +func part1(prog []int) { + p := intcode.NewProgram(prog) + + go func() { + var line []byte + for { + for !p.NeedsOutput() { + time.Sleep(1) + } + out := byte(p.Output()) + fmt.Print(string(out)) + if out == '\n' { + layout = append(layout, line) + line = []byte{} + } else { + line = append(line, out) + } + } + }() + fmt.Println("Running") + p.Run() + fmt.Println("Done") + + var total int + for y := range layout { + for x := range layout[y] { + if IsIntersection(x, y) { + total = total + (x * y) + fmt.Print("O") + } else { + fmt.Print(string(layout[y][x])) + } + } + fmt.Println() + } + + fmt.Println("# Part 1: ", total) +} +func IsIntersection(x, y int) bool { + if y == 0 || y == len(layout)-2 { + return false + } else if x == 0 || x == len(layout[y])-2 { + return false + } + if layout[y][x] != '#' { + return false + } + if layout[y-1][x] != '#' { + return false + } + if layout[y+1][x] != '#' { + return false + } + if layout[y][x-1] != '#' { + return false + } + if layout[y][x+1] != '#' { + return false + } + return true +} diff --git a/2019/day17/part2.go b/2019/day17/part2.go new file mode 100644 index 0000000..4bc3dbf --- /dev/null +++ b/2019/day17/part2.go @@ -0,0 +1,94 @@ +package main + +import ( + "fmt" + "time" + + intcode "git.bullercodeworks.com/brian/adventofcode/2019/intcode-processor" +) + +func part2(prog []int) { + p := intcode.NewProgram(prog) + p.SetProgramValueAt(0, 2) + + /* + A: L,4,L,4,L,10,R,4,R,4 + B: L,4,L,4,R,8,R,10, + A: L,4,L,4,L,10,R,4,R,4 + L,10,R,10, + A: L,4,L,4,L,10,R,4,R,4, + L,10,R,10,R,4, + L,4,L,4,R,8,R,10,R,4, + L,10,R,10,R,4, + L,10,R,10,R,4, + B: L,4,L,4,R,8,R,10 + */ + var input []string + input = append(input, "A,B,A,C"+string(byte(10))) + input = append(input, "L,4,L,4,L,10,R,4,R,4"+string(byte(10))) + input = append(input, "L,4,L,4,R,8,R,10"+string(byte(10))) + input = append(input, "L,10"+string(byte(10))) + + go func() { + printAllOutput(p) + for k := range input { + writeString(p, input[k]) + printAllOutput(p) + } + for !p.NeedsInput() { + time.Sleep(1) + } + p.Input(int('y')) + for !p.NeedsInput() { + time.Sleep(1) + } + p.Input(10) + + printAllOutput(p) + }() + + fmt.Println("Running") + p.Run() + fmt.Println("Done") +} + +func readString(p *intcode.Program) string { + var ret string + for { + if !p.NeedsOutput() { + time.Sleep(1) + } + out := p.Output() + if byte(out) == '\n' { + return ret + } + ret = ret + string(out) + } +} + +func writeString(p *intcode.Program, str string) { + fmt.Println("Printing", str) + for k := range str { + if p.NeedsInput() { + fmt.Print(string(str[k])) + p.Input(int(str[k])) + printAllOutput(p) + } + if p.NeedsOutput() { + return + } + time.Sleep(1) + } +} + +func printAllOutput(p *intcode.Program) { + for { + if p.NeedsInput() { + return + } + if p.NeedsOutput() { + fmt.Print(string(p.Output())) + } + time.Sleep(1) + } +} diff --git a/2019/day17/walk.go b/2019/day17/walk.go new file mode 100644 index 0000000..19f259c --- /dev/null +++ b/2019/day17/walk.go @@ -0,0 +1,175 @@ +package main + +import ( + "fmt" + "time" + + helpers "git.bullercodeworks.com/brian/adventofcode/helpers" +) + +const ( + DIR_N = '^' + DIR_E = '>' + DIR_S = 'v' + DIR_W = '<' +) + +func walk() { + bot := NewBot(layout) + for { + x, y := bot.GetNextSpot() + if bot.CanMove() && !bot.LastCoordWas(x, y) { + bot.Move() + } else { + bot.TurnLeft() + if bot.turns == 4 { + break + } + } + fmt.Print(helpers.CLEAR_SCREEN) + fmt.Println(bot.pathCoords) + bot.PrintLayout() + time.Sleep(time.Second / 10) + } + fmt.Println(bot.path) +} + +type Bot struct { + X, Y int + Dir byte + layout [][]byte + path string + pathCoords []*helpers.Coordinate + turns int + moves int +} + +func NewBot(layout [][]byte) *Bot { + b := &Bot{layout: layout} + // Find the bot + for y := range b.layout { + for x := range b.layout[y] { + if isBot(b.layout[y][x]) { + b.X = x + b.Y = y + b.Dir = b.layout[y][x] + b.layout[y][x] = '#' + } + } + } + return b +} + +func (b *Bot) Visited(x, y int) bool { + for _, v := range b.pathCoords { + if v.X == x && v.Y == y { + return true + } + } + return false +} + +func (b *Bot) LastCoordWas(x, y int) bool { + if len(b.pathCoords) == 0 { + return false + } + c := b.pathCoords[len(b.pathCoords)-1] + return c.X == x && c.Y == y +} + +func (b *Bot) Move() bool { + if !b.CanMove() { + return false + } + b.pathCoords = append(b.pathCoords, helpers.NewCoordinate(b.X, b.Y)) + b.X, b.Y = b.GetNextSpot() + if b.turns == 1 { // Left Turn + b.path = b.path + ",L" + } else if b.turns == 3 { // Right Turn + b.path = b.path + ",R" + } + b.moves++ + b.turns = 0 + return true +} + +func (b *Bot) GetNextSpot() (int, int) { + testX, testY := b.X, b.Y + switch b.Dir { + case DIR_N: + testY-- + case DIR_E: + testX++ + case DIR_S: + testY++ + case DIR_W: + testX-- + } + return testX, testY +} + +func (b *Bot) CanMove() bool { + x, y := b.GetNextSpot() + if y < 0 || y >= len(b.layout) { + return false + } + if x < 0 || x >= len(b.layout[y]) { + return false + } + return b.layout[y][x] == '#' +} + +func (b *Bot) TurnLeft() { + switch b.Dir { + case DIR_N: + b.Dir = DIR_W + case DIR_E: + b.Dir = DIR_N + case DIR_S: + b.Dir = DIR_E + case DIR_W: + b.Dir = DIR_S + } + b.turns++ + if b.moves > 0 { + b.path = b.path + "," + helpers.Itoa(b.moves) + b.moves = 0 + } +} + +func (b *Bot) TurnRight() { + switch b.Dir { + case DIR_N: + b.Dir = DIR_E + case DIR_E: + b.Dir = DIR_S + case DIR_S: + b.Dir = DIR_W + case DIR_W: + b.Dir = DIR_N + } + b.turns++ + if b.moves > 0 { + b.path = b.path + "," + helpers.Itoa(b.moves) + b.moves = 0 + } +} + +func isBot(b byte) bool { + return b == DIR_N || b == DIR_E || b == DIR_S || b == DIR_W +} + +func (b *Bot) PrintLayout() { + for y := range b.layout { + for x := range b.layout[y] { + if x == b.X && y == b.Y { + fmt.Print(string(b.Dir)) + } else if b.Visited(x, y) { + fmt.Print("█") + } else { + fmt.Print(string(b.layout[y][x])) + } + } + fmt.Println() + } +}