package two type neighbour struct { x int y int direction int } func newNeighbour(direction, x, y int) neighbour { switch direction { case NW: return neighbour{x - 1, y + 1, direction} case NE: return neighbour{x + 1, y + 1, direction} case SE: return neighbour{x + 1, y - 1, direction} case SW: return neighbour{x - 1, y - 1, direction} default: return neighbour{} } } func (n neighbour) outOfBounds(lines []string) bool { return n.x < 0 || n.y < 0 || n.y >= len(lines) || n.x >= len(lines[0]) } func (n neighbour) value(lines []string) rune { return rune(lines[n.y][n.x]) } type neighbours struct { NW neighbour NE neighbour SE neighbour SW neighbour } func newNeighbours(x, y int) neighbours { return neighbours{ newNeighbour(NW, x, y), newNeighbour(NE, x, y), newNeighbour(SE, x, y), newNeighbour(SW, x, y), } } func (n neighbours) all() [4]neighbour { return [4]neighbour{n.NW, n.NE, n.SE, n.SW} }