Sheba's Amoebas

The description states that no two amoebas will overlap. It also states that a black pixel will always have two of its eight neighbours as black pixels. Using this information, we can count the amoebas by "tracing" their outlines using a variation on the Flood fill algorithm, which amounts to a depth-first or breadth-first search with extra steps.

We iterate over each pixel in the input, calling our flood fill on any black pixel that hasn't been searched from. Each amoeba will require one flood fill, so we just count our calls to the algorithm and print the amount.

The C++ shows a recursive flood fill. The Python shows an iterative flood fill.

amoebas.cpp
amoebas.py

_53
#include <iostream>
_53
#include <string>
_53
#include <vector>
_53
#include <functional>
_53
_53
using namespace std;
_53
_53
int main() {
_53
int m,n;
_53
cin >> m >> n;
_53
vector<string> grid (m);
_53
for (auto& row : grid) cin >> row;
_53
vector<vector<bool>> seen(m, vector<bool>(n, false));
_53
_53
vector<pair<int,int>> dirs;
_53
_53
for (int dr : {-1,0,1})
_53
for (int dc : {-1,0,1})
_53
if (dr || dc) dirs.emplace_back(dr,dc);
_53
_53
auto in_bounds = [&](int r, int c) {
_53
return (r >= 0 && r < m && c >= 0 && c < n);
_53
};
_53
_53
int count = 0;
_53
_53
function<int(int,int)> flood_fill = [&] (int r, int c) {
_53
for (auto [dr, dc] : dirs) {
_53
int nr = r+dr, nc = c+dc;
_53
if (!in_bounds(nr,nc)) continue;
_53
if (grid[nr][nc] != '#') continue;
_53
if (!seen[nr][nc]) {
_53
seen[nr][nc] = true;
_53
flood_fill(nr,nc);
_53
}
_53
}
_53
return 1;
_53
};
_53
_53
for (int r = 0; r < m; ++r) {
_53
for (int c = 0; c < n; ++c) {
_53
if (grid[r][c] != '#')
_53
continue;
_53
_53
if (!seen[r][c]) {
_53
seen[r][c] = true;
_53
count += flood_fill(r,c);
_53
}
_53
}
_53
}
_53
_53
cout << count << '\n';
_53
}

If you found this solution helpful, consider leaving a star!