Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 392
Good morning! Here's your coding interview problem for today.

This problem was asked by Google.

You are given a 2D matrix of 1s and 0s where 1 represents land and 0 represents water.

Grid cells are connected horizontally orvertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells).

An island is a group is cells connected horizontally or vertically, but not diagonally. There is guaranteed to be exactly one island in this grid, and the island doesn't have water inside that isn't connected to the water around the island. Each cell has a side length of 1.

Determine the perimeter of this island.

For example, given the following matrix:
```
[[0, 1, 1, 0],
[1, 1, 1, 0],
[0, 1, 1, 0],
[0, 0, 1, 0]]
```

Return `14`.

Pull request:
Day392
Resolves #787.

Patch:
diff --git a/README.md b/README.md
index 7644b94..0d47e64 100644
--- a/README.md
+++ b/README.md
@@ -384,4 +384,5 @@ problems from
 * [Day 386](https://github.com/vaskoz/dailycodingproblem-go/issues/778)
 * [Day 390](https://github.com/vaskoz/dailycodingproblem-go/issues/783)
 * [Day 391](https://github.com/vaskoz/dailycodingproblem-go/issues/785)
+* [Day 392](https://github.com/vaskoz/dailycodingproblem-go/issues/787)
 
diff --git a/day392/problem.go b/day392/problem.go
new file mode 100644
index 0000000..c12fd90
--- /dev/null
+++ b/day392/problem.go
@@ -0,0 +1,37 @@
+package day392
+
+// IslandPerimeter finds the perimeter of exactly one island
+// in the input.
+// Connected land is horizontal or vertical only.
+func IslandPerimeter(grid [][]int) int {
+	perimeter := 0
+
+	for r := range grid {
+		for c := range grid[r] {
+			if grid[r][c] == 0 {
+				continue
+			}
+			// check left
+			if nr, nc := r, c-1; nc < 0 || grid[nr][nc] == 0 {
+				perimeter++
+			}
+
+			// check right
+			if nr, nc := r, c+1; nc >= len(grid[nr]) || grid[nr][nc] == 0 {
+				perimeter++
+			}
+
+			// check up
+			if nr, nc := r-1, c; nr < 0 || grid[nr][nc] == 0 {
+				perimeter++
+			}
+
+			// check down
+			if nr, nc := r+1, c; nr >= len(grid) || grid[nr][nc] == 0 {
+				perimeter++
+			}
+		}
+	}
+
+	return perimeter
+}


Test patch:
diff --git a/day392/problem_test.go b/day392/problem_test.go
new file mode 100644
index 0000000..071ca02
--- /dev/null
+++ b/day392/problem_test.go
@@ -0,0 +1,65 @@
+package day392
+
+import "testing"
+
+// nolint
+var testcases = []struct {
+	grid      [][]int
+	perimeter int
+}{
+	{
+		[][]int{
+			{0, 1, 1, 0},
+			{1, 1, 1, 0},
+			{0, 1, 1, 0},
+			{0, 0, 1, 0},
+		},
+		14,
+	},
+	{
+		[][]int{
+			{0, 1, 1, 0},
+			{0, 1, 1, 0},
+			{0, 1, 1, 0},
+			{0, 1, 1, 0},
+		},
+		12,
+	},
+	{
+		[][]int{
+			{1, 0, 0, 0},
+			{1, 1, 0, 0},
+			{1, 1, 1, 0},
+			{1, 1, 1, 1},
+		},
+		16,
+	},
+	{
+		[][]int{
+			{0, 0, 0, 0, 0, 0},
+			{0, 0, 1, 1, 0, 0},
+			{0, 1, 1, 1, 1, 0},
+			{0, 0, 1, 1, 0, 0},
+			{0, 0, 0, 0, 0, 0},
+		},
+		14,
+	},
+}
+
+func TestIslandPerimeter(t *testing.T) {
+	t.Parallel()
+
+	for _, tc := range testcases {
+		if res := IslandPerimeter(tc.grid); res != tc.perimeter {
+			t.Errorf("Expected %v, got %v", tc.perimeter, res)
+		}
+	}
+}
+
+func BenchmarkIslandPerimeter(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			IslandPerimeter(tc.grid)
+		}
+	}
+}