Drill

ProblemsGo › patterns

How many separate areas on the map

hardpatternsGridsRecursionGo

A coverage map marks every square metre as served or not. Planning wants the number of separate served areas, so a served square touching another one edge to edge belongs to the same area.

countRegions(coverage: list<list<int>>) → int

Go needs a compiler and Drill does not host one yet, so this page is the reference rather than an exercise: the problem, worked examples, and the solution in full. To type it out, the same problem runs in Python.

Solve it in Python →

Where you start

func countRegions(coverage [][]int) int {
	
}

Worked examples

CallResult
countRegions([][]int{[]int{1, 1, 0}, []int{0, 1, 0}, []int{0, 0, 1}})2
countRegions([][]int{[]int{1, 0, 1}, []int{0, 0, 0}, []int{1, 0, 1}})4
countRegions([][]int{[]int{0, 0}, []int{0, 0}})0
countRegions([][]int{[]int{1, 1}, []int{1, 1}})1

Hint

Walk every cell. The first time you meet an unvisited served cell, that is a new area — then flood outwards from it, marking everything it reaches, so you never count it twice.

Reference solution in Go
func countRegions(coverage [][]int) int {
	if len(coverage) == 0 {
	    return 0
	}
	rows, cols := len(coverage), len(coverage[0])
	seen := make([][]bool, rows)
	for i := range seen {
	    seen[i] = make([]bool, cols)
	}
	var flood func(r, c int)
	flood = func(r, c int) {
	    if r < 0 || r >= rows || c < 0 || c >= cols {
	        return
	    }
	    if seen[r][c] || coverage[r][c] != 1 {
	        return
	    }
	    seen[r][c] = true
	    flood(r+1, c)
	    flood(r-1, c)
	    flood(r, c+1)
	    flood(r, c-1)
	}
	areas := 0
	for r := 0; r < rows; r++ {
	    for c := 0; c < cols; c++ {
	        if coverage[r][c] == 1 && !seen[r][c] {
	            areas++
	            flood(r, c)
	        }
	    }
	}
	return areas
}

The same problem in another language

More patterns problems in Go