Explanation
The solution makes use of the following fact: If something is explicitly printed in the execution of the program, no implicit output is generated. Otherwise, the top of stack at the end of the execution is implicitly output.
L{%m~;:-c:u{hJchC;|mb1=-C;%a\sI^^P}M0
L Collect all lines in an array
{%m Convert each line to its length
~; Make a copy of the length array, put it on the input stack for later use
:- Difference between consecutive elements.
If the original array has only one line, this will be an empty array
c:u Are all elements in the array the same?
Empty array returns false
{ }M0 If last test result is true, execute block
If the block is not executed, or is cancelled in the middle, implicitly output 0
hJ The first element of the difference array squared (*)
chC Cancel if it is not 0 or 1
;|m1= Shortest line length (**) is 1
- Test whether this is the same as (*)
Includes two cases:
a. (*) is 1, and (**) is 1, in which case it is a triangle
b. (*) is 0, and (**) is not 1, in which case it is a square or a rectangle
C Cancel if last test fails
;% Number of lines
a\ [Nr. of lines, (*)]
I Get the 0-based index of (**) in the array
0-> Square, 1->Triangle -1(not found) -> Rectangle
^^P Add 2 and print
Explanation
The solution makes use of the following fact: If something is explicitly printed in the execution of the program, no implicit output is generated. Otherwise, the top of stack at the end of the execution is implicitly output.
L{%m~;:-c:u{hJchC;|mb1=-C;%a\sI^^P}M0
L Collect all lines in an array
{%m Convert each line to its length
~; Make a copy of the length array, put it on the input stack for later use
:- Difference between consecutive elements.
If the original array has only one line, this will be an empty array
c:u Are all elements in the array the same?
Empty array returns false
{ }M0 If last test result is true, execute block
If the block is not executed, or is cancelled in the middle, implicitly output 0
hJ The first element of the difference array squared (*)
chC Cancel if it is not 0 or 1
;|m1= Shortest line length (**) is 1
- Test whether this is the same as (*)
Includes two cases:
a. (*) is 1, and (**) is 1, in which case it is a triangle
b. (*) is 0, and (**) is not 1, in which case it is a square or a rectangle
C Cancel if last test fails
;% Number of lines
a\ [Nr. of lines, (*)]
I Get the 0-based index of (**) in the array
0-> Square, 1->Triangle -1(not found) -> Rectangle
^^P Add 2 and print
#Stax, 39 bytes
L{%m~;:-c:u{hJchC;
|mb1=-C;%a\sI^^P}M0
Shortest ASCII-only answer so far.
0 - Mess
1 - Rectangle
2 - Square
3 - Triangle