func Draw(mapCoordsToType map[string]int) [][]int {
	var lowX, highX, lowY, highY int
	for key := range mapCoordsToType {
		coords := strings.Split(key, ",")
		x, _ := strconv.Atoi(coords[0])
		y, _ := strconv.Atoi(coords[1])
		switch {
		case x < lowX:
			lowX = x
		case x > highX:
			highX = x
		}
		switch {
		case y < lowY:
			lowY = y
		case y > highY:
			highY = y
		}
	}
	edgeLength := 2 * mathy.MaxInt(-lowY, -lowX, highY, highX)
	grid := make([][]int, edgeLength)
	for i := 0; i < edgeLength; i++ {
		grid[i] = make([]int, edgeLength)
	}
	for key, val := range mapCoordsToType {
		coords := strings.Split(key, ",")
		x, _ := strconv.Atoi(coords[0])
		y, _ := strconv.Atoi(coords[1])
		x += edgeLength / 2
		y += edgeLength / 2
		if val != -1 {
			grid[x][y] = val
		}
	}
	grid = trim(grid)
	grid = algos.RotateIntGrid(grid)
	grid = trim(grid)
	return grid
}
Draw was copied from day11. It converts a map of points mapped from a (0,0) origin to a 2D grid
The origin loses its reference...
package main
import (
	"fmt"
	"log"
	"strconv"
	"strings"
	"github.com/alexchao26/advent-of-code-go/algos"
	"github.com/alexchao26/advent-of-code-go/mathy"
	"github.com/alexchao26/advent-of-code-go/util"
)
func main() {
	inputFile := util.ReadFile("../input.txt")
	splitStrings := strings.Split(inputFile, ",")
	inputNumbers := make([]int, len(splitStrings))
	for i, v := range splitStrings {
		inputNumbers[i], _ = strconv.Atoi(v)
	}
	robot := MakeRobot(inputNumbers)
	robot.RecursiveMove()
	grid := Draw(robot.floorDetails)
	for y, row := range grid {
		for x, tileType := range row {
			if tileType == 5 {
				grid[y][x] = 1
			}
		}
	}
	var minutes int
	for !isFullOfOxygen(grid) {
		spreadOxygen(grid)
		minutes++
	}
	fmt.Println("Minutes elapsed", minutes)
}
func isFullOfOxygen(grid [][]int) bool {
	for _, row := range grid {
		for _, tile := range row {
			if tile == 1 {
				return false
			}
		}
	}
	return true
}
var dRow []int = []int{0, 0, -1, 1}
var dCol []int = []int{-1, 1, 0, 0}
func spreadOxygen(grid [][]int) {
	for i := 0; i < len(grid); i++ {
		for j := 0; j < len(grid[0]); j++ {
			if grid[i][j] == 1 {
				for d := 0; d < 4; d++ {
					neighborRow := i + dRow[d]
					neighborCol := j + dCol[d]
					inBounds := neighborRow >= 0 && neighborRow < len(grid) && neighborCol >= 0 && neighborCol < len(grid[0])
					if inBounds && grid[neighborRow][neighborCol] == 2 {
						grid[i][j] = -1
						break
					}
				}
			}
		}
	}
	for i := 0; i < len(grid); i++ {
		for j := 0; j < len(grid); j++ {
			if grid[i][j] == -1 {
				grid[i][j] = 2
			}
		}
	}
}
type Robot struct {
	fromTop, fromLeft int
	floorDetails      map[string]int  
	computer          *Intcode
}
func MakeRobot(intcodeInput []int) *Robot {
	return &Robot{
		0,
		0,
		map[string]int{"0,0": 5},  
		MakeComputer(intcodeInput),
	}
}
var backtrack map[int]int = map[int]int{
	1: 2,  
	2: 1,
	3: 4,  
	4: 3,
}
var dx map[int]int = map[int]int{
	1: 0,
	2: 0,
	3: -1,
	4: 1,
}
var dy map[int]int = map[int]int{
	1: 1,
	2: -1,
	3: 0,
	4: 0,
}
func (robot *Robot) RecursiveMove() {
	for i := 1; i <= 4; i++ {
		nextCoords := fmt.Sprintf("%v,%v", robot.fromTop+dy[i], robot.fromLeft+dx[i])
		if robot.floorDetails[nextCoords] == 0 {
			robot.computer.Step(i)
			computerOutput := robot.computer.Outputs[len(robot.computer.Outputs)-1]
			switch computerOutput {
			case 0:  
				robot.floorDetails[nextCoords] = -1
			case 1, 2:  
				robot.floorDetails[nextCoords] = computerOutput
				robot.fromLeft += dx[i]
				robot.fromTop += dy[i]
				robot.RecursiveMove()
				robot.fromLeft -= dx[i]
				robot.fromTop -= dy[i]
				robot.computer.Step(backtrack[i])
			}
		}
	}
}
type Intcode struct {
	PuzzleInput      []int  
	InstructionIndex int    
	RelativeBase     int    
	Outputs          []int  
	IsRunning        bool   
}
func MakeComputer(PuzzleInput []int) *Intcode {
	puzzleInputCopy := make([]int, len(PuzzleInput))
	copy(puzzleInputCopy, PuzzleInput)
	comp := Intcode{
		puzzleInputCopy,
		0,
		0,
		make([]int, 0),
		true,
	}
	return &comp
}
func (comp *Intcode) Step(input int) {
	opcode, paramIndexes := comp.GetOpCodeAndParamIndexes()
	param1, param2, param3 := paramIndexes[0], paramIndexes[1], paramIndexes[2]
	switch opcode {
	case 1, 2, 7, 8:
		comp.ResizeMemory(param1, param2, param3)
	case 5, 6:
		comp.ResizeMemory(param1, param2)
	case 3, 4, 9:
		comp.ResizeMemory(param1)
	}
	switch opcode {
	case 99:  
		fmt.Println("Terminating...")
		comp.IsRunning = false
	case 1:  
		comp.PuzzleInput[param3] = comp.PuzzleInput[param1] + comp.PuzzleInput[param2]
		comp.InstructionIndex += 4
		comp.Step(input)
	case 2:  
		comp.PuzzleInput[param3] = comp.PuzzleInput[param1] * comp.PuzzleInput[param2]
		comp.InstructionIndex += 4
		comp.Step(input)
	case 3:  
		if input == -1 {
			return
		}
		comp.PuzzleInput[param1] = input
		comp.InstructionIndex += 2
		comp.Step(-1)
	case 4:  
		comp.Outputs = append(comp.Outputs, comp.PuzzleInput[param1])
		comp.InstructionIndex += 2
		comp.Step(input)
	case 5:
		if comp.PuzzleInput[param1] != 0 {
			comp.InstructionIndex = comp.PuzzleInput[param2]
		} else {
			comp.InstructionIndex += 3
		}
		comp.Step(input)
	case 6:
		if comp.PuzzleInput[param1] == 0 {
			comp.InstructionIndex = comp.PuzzleInput[param2]
		} else {
			comp.InstructionIndex += 3
		}
		comp.Step(input)
	case 7:
		if comp.PuzzleInput[param1] < comp.PuzzleInput[param2] {
			comp.PuzzleInput[param3] = 1
		} else {
			comp.PuzzleInput[param3] = 0
		}
		comp.InstructionIndex += 4
		comp.Step(input)
	case 8:
		if comp.PuzzleInput[param1] == comp.PuzzleInput[param2] {
			comp.PuzzleInput[param3] = 1
		} else {
			comp.PuzzleInput[param3] = 0
		}
		comp.InstructionIndex += 4
		comp.Step(input)
	case 9:
		comp.RelativeBase += comp.PuzzleInput[param1]
		comp.InstructionIndex += 2
		comp.Step(input)
	default:
		log.Fatalf("Error: unknown opcode %v at index %v", opcode, comp.PuzzleInput[comp.InstructionIndex])
	}
}
func (comp *Intcode) GetOpCodeAndParamIndexes() (int, [3]int) {
	instruction := comp.PuzzleInput[comp.InstructionIndex]
	opcode := instruction % 100
	instruction /= 100
	var paramIndexes [3]int
	for i := 1; i <= 3 && comp.InstructionIndex+i < len(comp.PuzzleInput); i++ {
		mode := instruction % 10
		instruction /= 10
		switch mode {
		case 0:  
			paramIndexes[i-1] = comp.PuzzleInput[comp.InstructionIndex+i]
		case 1:  
			paramIndexes[i-1] = comp.InstructionIndex + i
		case 2:  
			paramIndexes[i-1] = comp.PuzzleInput[comp.InstructionIndex+i] + comp.RelativeBase
		}
	}
	return opcode, paramIndexes
}
func (comp *Intcode) ResizeMemory(sizes ...int) {
	maxArg := sizes[0]
	for _, v := range sizes {
		if v > maxArg {
			maxArg = v
		}
	}
	if maxArg >= len(comp.PuzzleInput) {
		resizedPuzzleInput := make([]int, maxArg+1)
		copy(resizedPuzzleInput, comp.PuzzleInput)
		comp.PuzzleInput = resizedPuzzleInput
	}
}