All the single eights

R, 117 63 59 bytes

function(m)sum(colSums(as.matrix(dist(which(m==8,T)))<2)<2)

Try it online!

dist computes distances (default is Euclidean) among rows of a matrix. which with second argument TRUE returns the coordinates where the predicate is true.

Coordinates are neighbours if the distance between them is not more than the square root of 2, but the inner <2 is good enough because the possible distance jumps from sqrt(2) ro 2.


APL (Dyalog Classic), 29 28 25 bytes

≢∘⍸16=2⊥¨3,⌿3,/8=(⍉0,⌽)⍣4

Try it online!


Jelly, 18 15 bytes

8=µ+Ż+ḊZµ⁺ỊṖḋµS

Try it online!

How it works

8=µ+Ż+ḊZµ⁺ỊṖḋµS    Main link (monad). Input: digit matrix
8=              1) Convert elements by `x == 8`
  µ             2) New chain:
   +Ż+Ḋ              x + [0,*x] + x[1:] (missing elements are considered 0)
                     Effectively, vertical convolution with [1,1,1]
       Z             Transpose
        µ⁺      3) Start new chain, apply 2) again
          ỊṖ       Convert elements by `|x| <= 1` and remove last row
            ḋ      Row-wise dot product with result of 1)
             µS 4) Sum

Previous solution, 18 bytes

æc7B¤ZḊṖ
8=µÇÇỊḋµS

Try it online!

Wanted to share another approach, though this is 1 byte longer than Jonathan Allan's solution.

How it works

æc7B¤ZḊṖ    Auxiliary link (monad). Input: integer matrix
æc7B¤       Convolution with [1,1,1] on each row
     ZḊṖ    Zip (transpose), remove first and last elements

8=µÇÇỊḋµS    Main link (monad). Input: digit matrix
8=           Convert 8 to 1, anything else to 0 (*A)
  怀        Apply aux.link twice (effective convolution with [[1,1,1]]*3)
     Ịḋ      Convert to |x|<=1, then row-wise dot product with A
       µS    Sum the result