Triangular Grids: Simply Connected Polyiamonds

Snails, 95 bytes

F&
lr|=((ul.)2 ,l~a~)d|!((ul.)2 ,l~a~)u}\*}+l\ ,~a~|{\ (lr|=((ul.)2 ,l~a~)d|!((ul.)2 ,l~a~)u}+~

This really suffered from duplication, as I haven't implemented macros or any kind of back-reference. What it does is to check that for each star, there exists a path to the leftmost star on the top line; and for each space, there is a path to an edge of the grid.

F&                         ,, option F: pad lines with spaces to the length of the longest
                           ,, option &: print 1 iff match succeeds from every cell
lr                         ,, direction left or right, or
      | =((ul.)2 ,l~a~) d  ,, direction down, if we are an even number of orthogonal moves from the top left
      | !((ul.)2 ,l~a~) u  ,, or, direction up if we are odd number of moves from the top left
    }  \*                  ,, literal '*'
}+                         ,, 1 or more times
l\ ,~a~                    ,, check that we are on the leftmost * in the top line

|                          ,, the part before this is for starting on '*'; part after for starting on ' '

{ \                        ,, literal ' '
    (   lr                 ,, direction left or right, or
      | =((ul.)2 ,l~a~) d  ,, same drill as before...
      | !((ul.)2 ,l~a~) u 
}+                         ,, 1 or more times
~                          ,, end on an out of bounds cell

CJam, 101 98 bytes

qN/_z,f{' e]}{S2*f+W%z}4*:eeee::f+:~{_(aL{+_{_2,.+1$2,.-@_:+1&!2*(a.+}%2${a1$&},\;@1$-@@}h;\;-}2*!

Try it online.

I finally overcame my fear of implementing a flood fill in CJam. It's about as ugly as I expected, and it can most definitely be golfed.

The general idea is to perform two flood-fills (which are actually implemented as removals from the list of unvisited cells). The first pass will remove all spaces that are reachable from the edge. The second pass will then pick the first * in reading order and remove all the triangles reachable from that. If and only if the resulting list is empty, the polyiamond was simply connected:

  • If the polyiamond had a hole, the first flood fill is unable to reach and remove that hole.
  • If the input consists of several disconnected polyiamonds, the second flood fill is unable to reach and remove all of them.