Clojure, 227 198 bytes
(fn[t w h](let[c #(for[y(range %3 %4)x(range % %2)][x y])e #(= 8(get-in t(reverse %)0))m(fn[[o p]](count(filter e(c(dec o)(+ o 2)(dec p)(+ p 2)))))](count(filter #(= 1(m %))(filter e(c 0 w 0 h))))))
Ouch. Definitely not the shortest here by any means. 54 bytes of parenthesis is killer. I'm still relatively happy with it though.
-29 bytes by creating a helper function that generates a range since I was doing that twice, changing the reduce
to a (count (filter
setup, and getting rid of the threading macro after golfing.
(defn count-single-eights [td-array width height]
; Define three helpers. One generates a list of coords for a given range of dimensions, another checks if an eight is
; at the given coord, and the other counts how many neighbors around a coord are an eight
(letfn [(coords [x-min x-max y-min y-max]
(for [y (range y-min y-max)
x (range x-min x-max)]
[x y]))
(eight? [[x y]] (= 8 (get-in td-array [y x] 0)))
(n-eights-around [[cx cy]]
(count (filter eight?
(coords (dec cx) (+ cx 2), (dec cy) (+ cy 2)))))]
; Gen a list of each coord of the matrix
(->> (coords 0 width, 0 height)
; Remove any coords that don't contain an eight
(filter eight?)
; Then count how many "neighborhoods" only contain 1 eight
(filter #(= 1 (n-eights-around %)))
(count))))
(mapv #(count-single-eights % (count (% 0)) (count %))
test-cases)
=> [3 0 0 2 2 1 3 1 4 3]
Where test-cases
is an array holding all the "Python test cases"