func hasLoneIsland(grid [][2]int) bool {
	coords := map[[2]int]bool{}
	for _, pos := range grid {
		coords[pos] = true
	}
	delta := [][2]int{
		{-1, 0},
		{1, 0},
		{0, -1},
		{0, 1},
	}
	for _, pos := range grid {
		hasNeighbor := false
		for _, d := range delta {
			pos[0] += d[0]
			pos[1] += d[1]
			if coords[pos] {
				hasNeighbor = true
			}
			pos[0] -= d[0]
			pos[1] -= d[1]
		}
		if !hasNeighbor {
			return true  
		}
	}
	return false
}
this didn't work unfortunately, letters like K do have "lone islands" along
the diagonals
package main
import (
	"flag"
	"fmt"
	"math"
	"strings"
	"time"
	"github.com/alexchao26/advent-of-code-go/cast"
	"github.com/alexchao26/advent-of-code-go/util"
)
func main() {
	var part int
	flag.IntVar(&part, "part", 1, "part 1 or 2")
	flag.Parse()
	fmt.Println("Running part", part)
	if part == 1 {
		part1(util.ReadFile("./input.txt"))
	} else {
		part2(util.ReadFile("./input.txt"))
	}
}
func part1(input string) {
	postions, velocities := parseInputs(input)
	steps := 0
	prints := 0
	hasPrinted := false
	for hasLoneIsland(postions) {
		move(postions, velocities)
		steps++
		fmt.Println("\nsteps run", steps)
		printable := printGrid(postions)
		if printable != "" {
			fmt.Println("Steps: ", steps)
			fmt.Println(printable)
			time.Sleep(time.Millisecond * 500)
			hasPrinted = true
		}
		if printable == "" && hasPrinted {
			return
		}
		fmt.Println(prints)
	}
}
func part2(input string) {
	part1(input)
}
func parseInputs(input string) (positions [][2]int, velocities [][2]int) {
	lines := strings.Split(input, "\n")
	for _, l := range lines {
		posX := strings.TrimSpace(l[10:16])
		posY := strings.TrimSpace(l[18:24])
		velX := strings.TrimSpace(l[36:38])
		velY := strings.TrimSpace(l[40:42])
		positions = append(positions, [2]int{cast.ToInt(posX), cast.ToInt(posY)})
		velocities = append(velocities, [2]int{cast.ToInt(velX), cast.ToInt(velY)})
	}
	return positions, velocities
}