Mathematica, 180 bytes
(f=Flatten@#;p=Partition)[If[Tr[1^VertexComponent[r~Graph~Cases[##&@@p[#,2,1]&/@Join[g=p[r,5],g],{a_,b_}/;(A=f[[a]])==f[[b]]&&A!=" ":>a<->b],#]]<3,f[[#]],"x"]&/@(r=Range@25),5]&
Explanation:
(f=Flatten@#;p=Partition)[
If[
Tr[1^VertexComponent[
r~Graph~Cases[
##&@@p[#,2,1]&/@Join[g=p[r,5],g],
{a_,b_}/;(A=f[[a]])==f[[b]]&&A!=" ":>a<->b
],
#
]]<3,
f[[#]],
"x"
]&/@(r=Range@25),
5
]&
Pure function which accepts a 5x5
array.
is the 3-byte private-use character U+F3C7
representing the postfix transpose operator \[Transpose]
.
(f=Flatten@#;p=Partition)
: Flattens the input list and stores it in f
. Sets p = Partition
and returns it.
g=p[r,5]
: The array {{1,2,3,4,5}, ..., {21,22,23,24,25}}
(this is because r
gets set to Range@25
).
Join[g=p[r,5],g]
: the list of rows and columns of g
.
p[#,2,1]&
: Pure function which partitions the list #
into sublists of length 2
with overlap 1
; i.e., the list of adjacent pairs in #
.
##&@@p[#,2,1]&
: Same as above except it returns a Sequence
.
##&@@p[#,2,1]&/@Join[g=p[r,5],g]
: Maps the previous function of the rows and columns of g
to obtain a list of all of the adjacent entries in g
. My gut says there is a shorter way to do this.
r~Graph~Cases[...]
: Graph whose vertices are the integers 1, ..., 25
and whose edges are the edges between adjacent entries in g
which have the same corresponding entries in the input array (other than " "
)
{a_,b_}/;(A=f[[a]])==f[[b]]&&A!=" "
: Pattern which matches {a,b}
such that f[[a]] == f[[b]]
(same value in the input array) and which are not equal to " "
. Set A = f[[a]]
to save 1
byte.
...:>a<->b
: Replace every match with an undirected edge from a to b.
VertexComponent
: Returns the connected component of the second argument (a vertex) in the first argument (a graph).
Tr[1^VertexComponent[...]]
: The size of the connected component. Saves 1
byte from Length@VertexComponent[...]
.
If[Tr[...]<3,f[[#]],"x"]&
: Pure function which takes an entry #
in g
. If the size of its connected component is less than 3
, replace it with the corresponding entry in the input. Otherwise, replace it with "x"
.
(f=Flatten@#;p=Partition)[...,5]
: And finally reshape the result to be a 5x5
array.