"2Fø0δ.ø}2Fø€ü3}"DU.VOO_©˜ƶIgäΔX.V®*€€à}D˜ÙsX.V€€àI+_˜«0Kg
Input as a bit-matrix.
Try it online or verify all test cases.
Explanation:
Step 1: Add a border of 0s around the input, and convert it to overlapping 3x3 blocks:
"..." # Push the string explained below
DU # Store a copy in variable `X`
.V # Pop and evaluate it as 05AB1E code
2Fø0δ.ø} # Add a border of 0s around the (implicit) input-matrix:
2F } # Loop 2 times:
ø # Zip/transpose; swapping rows/columns
# (which will use the implicit input-matrix in the first iteration)
δ # Map over each row:
0 .ø # Add a leading/trailing 0
2Fø€ü3} # Convert it into overlapping 3x3 blocks:
2F } # Loop 2 times again:
ø # Zip/transpose; swapping rows/columns
€ # Map over each inner list:
ü3 # Convert it to a list of overlapping triplets
Try just this first step online.
Step 2: Sum each overlapping 3x3 block, and check whether it's 0:
OO # Sum all overlapping 3x3 blocks
_ # Check for each sum whether it's 0 (1 if 0; 0 if ≥1)
Try just the first two steps online.
Step 3: Flood-fill, and check how many islands of 1s there are:
© # Store the current matrix in variable `®` (without popping)
˜ # Flatten it
ƶ # Multiply each value by its 1-based index
Ig # Push the amount of rows in the input-matrix
Ì # Increase it by 2 to account for the two borders of 0s
ä # Convert the list back to a matrix of that many rows
Δ # Loop until the result no longer changes to flood-fill:
X.V # Pop and evaluate string `X` as 05AB1E code (repeat step 1)
®* # Multiply each 3x3 block by the value in matrix `®`
# (so the 0s remain 0s)
€€ # Nested map over each 3x3 block:
à # Pop and leave its flattened maximum
} # Close the changes-loop
D # Duplicate this matrix (to use in a later step)
˜ # Pop and flatten it to a list
Ù # Uniquify the remaining digits, to get all islands (and 0)
Try just the first three steps online.
Step 4: Identify all single cell edge cases, that haven't been flood-filled yet:
s # Swap so the duplicated matrix of islands is at the top again
X.V # Pop and evaluate string `X` as 05AB1E code (repeat step 1 yet again)
€€ # Nested map over each 3x3 block:
à # Pop and leave its flattened maximum
Y+ # Add the values of the input-matrix
_ # Check which cells are (still) 0s
Try just the first four steps online.
Step 5: Combine the results of steps 3 and 4, and output the result:
˜ # Flatten the matrix of 1s/0s of the previous step to a list
« # Merge the two lists together (the unique islands,
# as well as the 0-cells that haven't been flood-filled)
0K # Remove all 0s
g # Pop and push the combined length
# (which is output implicitly as result)