Is it L-convex?

Matlab, 182 bytes

Idea: Repeat for every 1 in the polyomino matrix:

  • Create new matrix with only the given 1 but the rest zero.
  • for every 1 in this new matrix (repeat until nothing changes anymore)
    • add 1 as neighbours in x direction if there are 1 as neighbours in the polynomio
  • for every 1 in this new matrix (repeat until nothing changes anymore)
    • add 1 as neighbours in x direction if there are 1 as neighbours in the polynomio

Now 1 in the new matrix should cover all 1 in the polynomio-matrix that are reachable from the given starting point by first going in x-direction and then in y-direction. Now we can repeat the same process but with first going into y-direction and then in x-direction. Now every 1 of the polyomino matrix should be reached at once or both times. If not, then we have found a position in the polynomio matrix that cannot be reached from every other position by an L-path.

Golfed:

function r=f(a);[i,j,b]=find(a);N=nnz(i);r=1;for k=1:N;K=1:3;for l=1:2;c=b;b=a*0;b(i(k),j(k))=1;for z=1:2*N; b=conv2(b+0,K,'s')&a;if z==N;K=K';end;end;end;r=r*all(b(:)|c(:)>=a(:));end

With comments:

function r=codegolf_L_convex(a);
%a=[0,1;1,1];
[i,j,b]=find(a);%b just needs to be initialized, does not really mattter
N=nnz(i);%number of ones in the matrix
r=1;%return value
for k=1:N;%go throu all '1' in the matrix
    %expand that pixel in x dir:
    K=1:3;%convolution kernel (just three positive values needed)
    for l=1:2;%first horizontal->vertical then vertical->horizontal
        c=b;%backup for considering both runs
        b=a*0;
        b(i(k),j(k))=1; %set the seed
        for z=1:2*N;     
            b=conv2(b+0,K,'s')&a; %expand the seed horizontally (or vertically for the second half) but only within the polyomino
            if z==N;
                K=K'; %change horizontal/vertical 
            end;
        end;
    end;
    r=r*all(b(:)|c(:)>=a(:));%check whether we can really reach every point
end

Test cases script:

disp('all false -------------');
a=[0,1;1,0];
f(a)
a=[1,1,1;1,0,1;1,1,1];
f(a)
a=[1,1,0,1;1,1,1,1;1,1,1,0];
f(a)
a=[1,1,0,0;1,0,0,0;0,0,1,1];
f(a)
a=[0,1,1,0,0;1,1,1,1,0;0,1,1,1,0;0,0,1,1,0];
f(a)
a=[0,1,1,0,0,0;0,1,1,1,1,0;0,0,1,1,1,1];
f(a)
 disp('all true +++++++++++++');
a=[1];
f(a)
a=[0,1;1,1];
f(a)
a=[0,1,0;1,1,1;0,1,0];
f(a)
a=[0,0,1;0,1,1;1,1,1];
f(a)
a=[1,1,1,0,0;1,1,1,1,0;0,1,1,0,0;0,1,0,0,0];
f(a)
a=[0,1,1,0,0,0;0,1,1,0,0,0;1,1,1,1,0,0;1,1,1,1,1,1;0,0,1,0,0,0];
f(a)

Snails, 45 24

&
!{\1t\1!{o\1,nf\1,!.!~

Right after posting my initial solution, I realized there was a much better way. The original program traveled around the square formed by the paths between two 1s, testing for the presence of a 0 in each pair of sides. It also had to have a special case for straight line paths. The new version starts by teleporting from one 1 to the other, and testing for the absence of a straight or L-shaped path of 1s back to the start.


Mathematica, 129 127 bytes

3>GraphDiameter@Graph[#,#<->#2&@@@Select[#~Tuples~2,!FreeQ[#-#2&@@#,0]&]]&@Position[#,1]&&{#,Thread@#}~FreeQ~{___,1,0..,1,___}&

Explanation:

First, if there is a 0 between two 1s on the same row or column, the array is not L-convex, because we can't connect the two 1s.

After excluding this case, every two 1s on the same row or column can be connected by a straight path. We can generate a graph, whose vertices are the positions of 1s in the array, and edges are pairs of 1s on the same row or column. Then the array is L-convex if and only if the diameter of the graph is less than 3.