diff --git a/go/regions-cut-by-slashes.go b/go/regions-cut-by-slashes.go new file mode 100644 index 0000000..a69fbc7 --- /dev/null +++ b/go/regions-cut-by-slashes.go @@ -0,0 +1,83 @@ +package main + +import aq "github.com/emirpasic/gods/v2/queues/arrayqueue" + +type Position struct { + y, x int +} + +const ( + WALL int = -1 + BLANK int = 0 + SEEN int = 1 +) + +func regionsBySlashes(grid []string) int { + POSITIONS := []Position{ + Position{0, 1}, + Position{0, -1}, + Position{1, 0}, + Position{-1, 0}, + } + + n := len(grid) + + makeGraph := func() [][]int { + graph := make([][]int, 3*n) + for i := range graph { + graph[i] = make([]int, 3*n) + } + + for y0, row := range grid { + for x0, cell := range row { + y, x := 3*y0, 3*x0 + + if cell == '/' { + graph[y][x+2] = WALL + graph[y+1][x+1] = WALL + graph[y+2][x] = WALL + } else if cell == '\\' { + graph[y][x] = WALL + graph[y+1][x+1] = WALL + graph[y+2][x+2] = WALL + } + } + } + + return graph + } + + visit := func(g [][]int, p Position) bool { + return p.y >= 0 && p.y < len(g) && p.x >= 0 && p.x < len(g[p.y]) && g[p.y][p.x] == BLANK + } + + fill := func(g [][]int, y, x int) { + q := aq.New[Position]() + q.Enqueue(Position{y, x}) + + for p, ok := q.Dequeue(); ok; p, ok = q.Dequeue() { + for _, d := range POSITIONS { + next := Position{p.y + d.y, p.x + d.x} + + if visit(g, next) { + q.Enqueue(next) + g[next.y][next.x] = SEEN + } + } + } + } + + graph := makeGraph() + + regions := 0 + for p := 0; p < 9*n*n; p++ { + y, x := p/(3*n), p%(3*n) + + if graph[y][x] == BLANK { + fill(graph, y, x) + regions++ + } + } + + return regions +}