[Question]
  [
Your task is to build a program that identifies the shape of the input. The shapes to be identified can be any of the following:
### Square
To be identified as a square, the source must have lines of all equal length, and the same number of lines as characters per line (newline characters excluded). An optional trailing newline is acceptable.
```
$_='
$_="
$_"'
;say
```
### Rectangle
To be identified as a rectangle, the source must have lines of all equal length, but the number of lines does not match the number of characters per line (newline characters excluded). An optional trailing newline is acceptable. This can be either horizontal or vertical.
```
$_=
"no
t a
squ
are
";#
$_="but it
is still a
consistent
shape!";##
```
### Triangle
To be identified as a triangle, the source must either start with one character, and each subsequent line must have one additional character (including the last), or after the first line, each subsequent line should have one character fewer until the last, which has only one.
```
$
_=
"So
this
"."".
shape;
$_="or
even,
this
way
!!
"
```
### Mess
Anything that doesn't follow a consistent format as per the above, must be identified as a mess.
## Rules
* You may return any four consistent printable values to identify each shape.
* **Your source code must also adhere to one of the above shapes (no, not a mess).**
* A single trailing newline in your source is acceptable.
* You can assume input does not contain any blank lines (including trailing newlines), is not empty, and does not consist only of newlines.
* All shapes must have a height and width of >= 2, otherwise this is defined as a mess.
* [Standard loopholes are forbidden.](https://codegolf.meta.stackexchange.com/q/1061/9365)
* The shortest solution in bytes, in each language, wins.
  
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 35 bytes
```
L€ṀR,Ṛ$ċƲȧ3
L€,;¥LE€S+Ç
ỴµZL«L>1ȧÇ 
```
[Try it online!](https://tio.run/##y0rNyan8/9/nUdOahzsbgnQe7pylcqT72KYTy425QII61oeW@rgCGcHah9u5Hu7ecmhrlM@h1T52hieWH25X@E@@VgA "Jelly – Try It Online")
`0` = Mess  
`1` = Rectangle  
`2` = Square  
`3` = Triangle
[Answer]
# [Brachylog](https://github.com/JCumin/Brachylog), 45 bytes
```
lᵐ{≥₁|≤₁}o{l>1&t>1&}↰₃
lg,?=∧1w|=∧2w|t⟦₁≡?∧3w
```
[Try it online!](https://tio.run/##SypKTM6ozMlPN/r/P@fh1gnVjzqXPmpqrHnUuQRI1eZX59gZqpUAce2jtg2Pmpq5ctJ17G0fdSw3LK8BUUblNSWP5i8Dqn3UudAeKGBc/v9/tJKhko6CkqERhDSGUiZKsQA "Brachylog – Try It Online")
Code is a rectangle (despite the way it renders on my screen). Outputs: 1 for square, 2 for rectangle, 3 for triangle, and nothing for mess
---
### Explanation:
```
lᵐ{≥₁|≤₁}o{l>1&t>1&}↰₃
lg,?=∧1w|=∧2w|t⟦₁≡?∧3w
lᵐ                        Get the length of each string
  {     }                 Verify 
   ≥₁                     The list is non-increasing
     |                    or...
      ≤₁                  The list is non-decreasing
         o                Sort it to be non-decreasing
          {        }      Verify
           l>1            The number of lines is greater than 1
              &           and...
               t>1&       The longest line is longer than 1 character
                    ↰₃    Call the following
lg,?                      Join the number of lines with the line lengths
    =∧1w                  If they are all equal, print 1 (Square)
         |=∧2w            Or if just the line lengths are equal, print 2 (Rectangle)
              |t⟦₁         Or if the range [1, 2, ... <longest line length>]
                  ≡?       Is the list of lengths
                    ∧3w    Print 3 (triangle)
                           Otherwise print nothing (mess)
```
[Answer]
# Java 10, ~~231~~ ~~221~~ ~~219~~ ~~217~~ ~~213~~ ~~211~~ ~~207~~ 203 bytes
```
s->{var a=s.split("\n");int r=a.length,l=a[0].length(),R=0,i=1,L,D;if(r>1){for(L=a[1].length(),D=L-l;
++i<r;R=L-a[i-1].length()!=D?1:R)L=a[i].length();R=R<1?D==0?r==l?1:2:D*D>1|l>1&L>1?0:3:0;}return R;};
```
Function is a rectangle itself.  
`1` = Squares; `2` = Rectangles; `3` = Triangles; `0` = Mess.
-14 bytes thanks to *@OlivierGrégoire*  
-4 bytes thanks to *@ceilingcat*
**Explanation:**
[Try it online.](https://tio.run/##vVXBctowEL3zFbLSaU0CDm5vOIYLhxxIOwO5RZmOMAKUKjKRZDKZlG@nK4Nlk4SaTDplwKzk1dunt8/WHV3R9t301yYRVGt0Rbl8biDEpWFqRhOGvtthPoESf2wUl3OkmxFMruEHX22o4Qn6jiSK0Ua3e88rqhCNdaCXghsfE4mbkV2vYhoIJudm0RIxvenc7kZ@szWKOy0eh61haxDxma96YfN5lip/CHlhJW8QD9siapyd8QsVjWBAb3i7kuDFg37YHTXtOl5OQ@roIuwP4rjTV3EsIOdrd3A66IW/RS/8POyF/U73W7cTrRUzmZJoFK2jTdSA7S2ziYDt7Xa5SvkU3YNIOylubmlzK9D4SRt2H6SZCZZwxwjp4/FDRhXTXZzrhdD5Kfr0M/6Sx/CBGJcxdvORpk/o9PwQrAwSH1scIuFKsP0jGEZ2HW6WtSaCFpD7YR04pBBZXBziG9m7OwcFGLHEUDkXrzQoyGCZFqFBjqJ@yIoQ9HO50ckRqhBJAJSA3YA@ABEJEHYyOqlqY7WfZAZxU8BzDU3mQpQ0klRqDoWky9ELumQeQB3FZFeAyBKayBIU6OVwltoet@sF1xVWjo9h2tTVtWvzglDK5n@ke9eKv9G8gk2lieOyiRXqOMA42FMuqlWNyG0Hx7aD@VYIDsDicNmqFb1sYqqKEmzFZOstIo/0qQg9z7Hb/h3TxlQRmYMXnACQSM@z5Kp0nE0Ud/aV8yIEHft15cATioNj5ZxIm/@R7l0xvde4v7mqlMdD73WYVcKryvBDoUX66BSYAIITBmR0/dJs2q8vt0UDTSwOyGMRwAt27Xu0N64seLoI58J55wgv7DfHAAuAIvCAgDuqVC7rgC5fvKSPeB3XGOHwCZRmCg7xJJ0yeBNpJmbOEoeqvT7B4fmzVv/HhziR/@UU3ym3bqw3fwA)
```
s->{                        // Method with String parameter and integer return-type
  var a=s.split("\n");      //  Input split by new-lines
  int r=a.length,           //  Amount of lines
      l=a[0].length(),      //  Length of the first line
      R=0,                  //  Result-integer, initially 0
      i=1,                  //  Index integer, starting at 1
      L,D;                  //  Temp integers
  if(r>1){                  //  If there are at least two lines:
    for(L=a[1].length(),    //   Set `L` to the length of the second line
        D=L-l;              //   And set `D` to the difference between the first two lines
        ++i<r;              //   Loop over the array
        ;                   //     After every iteration:
         R=L-a[i-1].length()//     If the difference between this and the previous line
          !=D?              //     is not equal to the difference of the first two lines:
           1                //      Set `R` to 1
          :                 //     Else:
           R)               //      Leave `R` the same
      L=a[i].length();      //    Set `L` to the length of the current line
  R=R<1?                    //   If `R` is still 0:
     D==0?                  //    And if `D` is also 0:
      r==l?                 //     And the amount of lines and length of each line is equal:
       1                    //      It's a square, so set `R` to 1
      :                     //     Else:
       2                    //      It's a rectangle, so set `R` to 2
     :D*D>1&                //    Else-if `D` is NOT 1 nor -1,
      l>1&L>1?              //    and neither `l` nor `L` is 1:
       0                    //     Set `R` to 0, since it's a mess
      :                     //    Else (`D` is 1 or -1, and `l` or `L` is 1):
       3                    //     It's a triangle, so set `R` to 3
    :0;}                    //   In all other cases it's a mess, so set `R` to 0
  return R;}                //  Return the result `R`
;                           // No-op to make the method a rectangle
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~32~~ 27 bytes
```
,U⁼€JẸ,E;SÆ²$
ZL«L’aL€Ç$æAƝ
```
[Try it online!](https://tio.run/##y0rNyan8/18n9FHjnkdNa7we7tqh42odfLjt0CYVriifQ6t9HjXMTPQBSh1uVzm8zPHY3P8Pd2853P7/fzZXSgoQpXAVp6QVc6VkAyGEzIZSKVxpWSnZxTlZaQA "Jelly – Try It Online")
Now taking input at a list of lines and switched `>1×` with `’a` and using `SÆ²` after `L€` instead of `FLÆ²Ɗ`. These allowed me to condense into two lines and I saved 5 bytes in total. The following values are the same as before.
`[0.0, 0.0]`=Mess  
`[0.0, 1.5707963267948966]`=Rectangle  
`[0.0, 0.7853981633974483]`=Square  
`[1.5707963267948966, 0.0]`=Triangle
---
`ZL«L` gets the minimum of height and width and `’` subtracts 1 from it. `Ç` calls the second link and at the end if the input is a single line the result of `Ç` gets logical ANDed with the previous number if there is only a single line the output will be `[0.0, 0.0]`.
In the second link: `,U` yields a list of line lengths paired with it's reverse. `J` is `range(number of lines)` and `⁼€` checks whether each of them are equal to the result of `J`. `Ẹ` (Any) yields 1 if the input is a triangle.
`E` checks if all line lengths are equal (rectangle/square).
`SÆ²` with a `$` to group them into a single monad checks whether the total number of characters is a square number.
So at the end of the second link we have `[[a,b],c]` where each number is `0` or `1` indicating whether the input is a triangle, rectangular, and has square number of characters respectively.
However a square number of elements doesn't imply the input is a square since an messy input like
```
a3.
4
```
has a square number of elements but isn't a square. 
This is where `æA` (arctan2) comes in. `0æA0` == `0æA1` == `0`. In other words, if the input has square number of elements but is not a rectangle, then it is not a square. There are certainly more clear ways to do this but what does that matter when we have bytes to think about and we are allowed consistent arbitrary output.
Note I was previously using `æA/` instead of `æAƝ` (and a `,` instead of a `;` in the second link) but the former method distinguishes between triangles that have square number of elements and those that don't but they should obviously be counted as the same thing.
[Answer]
# [Python 2](https://docs.python.org/2/), ~~129~~ ~~114~~ ~~109~~ ~~107~~ 113 bytes
```
l=map(len,input().split('\n'));m=len(
l);r=range(1,m+1);print[[1],0,r,r[::-
1],[m]*m,0,[max(l)]*m,l].index(l)%7/2
```
[Try it online!](https://tio.run/##jU/NTsMwDL73KVoPtARCWbkgLcpTcEyqKbCIRkrcKMmAPv1wxSZxQlys78f@bKelTjM@nc9BRZtYcCg8plNlvC8p@Mq2Brecy6jIYk3gMqts8d2xQcT7gcuUPVath1HsRBZZ7/cPDREdx7tIko72iwW@kjD2Ho9upbfPj7QSdtAAwM1B0RKqsFYgLItdyLiY8Hqqra8GfWlL9SG01uDbjMWX6pD0MtnkOpCbzXXI4EEZhJfZYJ18IdgD9JdO@St6zgbdBz19bfy0i8GuM2j/l2Xw5/S/g74B "Python 2 – Try It Online")
---
Prints
* `0` = `Mess`
* `1` = `Triangle`
* `2` = `Square`
* `3` = `Rectangle`
[Answer]
# Java 10, ~~274~~ ~~323~~ ~~298~~ 229 bytes
First triangle submission.
```
s
->
{  
var 
a=s. 
split 
("\n");
int i,l=
a.length,
c,f=a[0]. 
length(),r=
l<2||f<2&a[1
].length()<2?
0:f==l?7:5;var
b=f==1;for(i=1;
i<l;){c=a[i++]. 
length();r&=c!=f?
4:7;r&=(b&c!=f+1)|
(!b&c!=f-1)?3:7;f=c
;}return r;}        
```
`0` Mess
`1` Rectangle
`3` Square
`4` Triangle
Try it online [here](https://tio.run/##rZRdb9owFIav8a8w2dQmAtJCN1XCuFzvYjdjdzWajHHAXXpCbYcKFX47O07IStFUVRq5sHP88b7HPtbzINey9zD/vV@Vs9woqnLpHP0uDdAX0jLgtc2k0nSylCv9ba7Bm8xoGybDLDX10KaajyfeGlhQA6vSJ4y0dqRFWgdl56XHbl2YOX1E/cPi@ymVduGSSvHUxZ3EnO4d6d2RF0rJWlpKJHcpJW6VG09JHAmI0LbKq5tzItNcw8Ivu0R1My7vr6e4uB6Kk67lJB8NtttsNLiQ930yTZup0WBMrocZ5/n4dviVoROZcQz7LCtsbLAnZpSz5EWhqOl0jmWZveCqzbMx@TK8DUE8uwhxp59sSdyug14/Gd/gdMYVYTurfWmBWrajh2/PCD35Jhvn9WNalD5d4b35HOJo8lRKq4c06pxcVPq2LNHnX/xSALYiCp2IMGJObqIkVKn1L@0fWnkJi/yD8gJEBIXAm5cC3FMpADMLg@zTGU2iWYml9QKMw/dk8jy4qQKcQW3A8UqjHVzfs/1pzYddBdSHm4TDLY0L/yleIza1GzuTUTheYQXotYZu4/UsNwLa7WD6js137dwHLOQZJGbqDCICZudRUQLmB6WrK@qXmq5ssbDy8dLR4hmoK0qL8FLFXP9/hbAcvTsByB4BAT74xAN98BkE/MShRiI0CcOxhkG4qIGQgIZBQeEIQwL6XRUoQ5EyOHUMGiMASYOMSWxgzTR93RkgczPEF8NMFlvchEsqZgkYDC3TudO0kcGEDjI1s0ISr0rM/qUU5pJsjzF1jVIZ5qSQU7ziZXOGY4UaoQ1BBVQMDVvfsq2u1Y7s9n8A).
Edited multiple times to golf it a bit more.
Of course I could save a lot of bytes by turning this into a rectangle as well (~~281~~ ~~267~~ ~~259~~ 200 bytes, see [here](https://tio.run/##rZRdb9owFIavya8w2UQTASnQTZUwKde76E3ZHUaTCQ64MyfUdqgQ8NvZMUlGQVOFNHIRfxz7fY99rOeVr3n7dfb7sMqnSiYkUdwY8swlkK1Xk2CFTnkiyGjBV@LHTICVqRTaBV2UyGJqc4wHI6slzImEVW5D6tX2Xs2rlcrGcovNOpMzskT9cvF4Qriem/CoeOliLsYxOZj203bNNeGxicxKSRv4DPyQHpNpqZhHSsDcLlppzMedSTkKwpaO1aC326XEG/QafNw9hQa9YaefxrEaPva/txLq5KcxTnRpmulAYisHiobbBCVlszmJvGor1Y04qcfp8Fv/0fWDacMNm91wF9SLfrsbDh8wmsYJ3Wthcw1E0/2BeuTiG22MFcsoy220wquxCgJ/9JZzLfrEb17cRXR@8/7XX/EdA/wz3zXMxxE1fOOHrhC1f2m/iMRymKsr5RkwHzKG98wZmLecAWbmJumXG5r40xwLaRlIg09GKuXckgyMRG3A@aNG3bl@ZvtTy6tdGRSHG7nDLaRx/QivEX@FG72RkTtephmItYBW5fXONwzqdWf6ic2zMOYKC34DiWlyAxEG09uoJAxmpdL9PbELQVY6m2u@vDMkewdislwjn5JsJv6/QliO9hODLSEMHAXwiSNmsClI42rE3C@kOFcRBxdVzGFQUoc4hQ/oYdA9gQVDZ2xhgHRBroTa8WUSnXY6sjz08cVQmQYaN@GSI6gY9PqaCmUEqWQwoVKm4JRL4qRE9V82YS7ndOqgVIo5OT4VkKzO8FHhnJoMSm5qemKa21DUau/tD38A)).
The result of the identification is manipulated using bitwise AND, yielding a bitmask as follows:
```
1        1      1
triangle square rectangle
```
Ungolfed version:
```
s -> {
    var lines = s.split("\n"); // split input into individual lines
    int i, // counter for the for loop
    numLines = lines.length, // number of lines
    current, // length of the current line
    previous = lines[0].length(), // length of the previous line
    result = numLines < 2 // result of the identification process; if there are less than two lines
    || previous < 2 & lines[1].length() < 2 // or the first two lines are both shorter than 2
    ? 0 : previous == numLines ? 7 : 5; // it's a mess, otherwise it might be a square if the length of the first line matches the number of lines
    var ascending = previous == 1; // determines whether a triangle is in ascending or descending order
    for(i = 1; i < numLines; ) { // iterate over all lines
         current = lines[i++].length(); // store the current line's length
        result &= current != previous ? 4 : 7; // check if it's not a rectangle or a square
        result &= (ascending & current != previous+1)|(!ascending & current != previous-1) ? 3 : 7; // if the current line is not one longer (ascending) or shorter (descending) than the previous line, it's not a triangle
        previous = current; // move to the next line
    }
    return result; // return the result
}
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 15 bytes
```
Jm0w,ET
ỴẈµLe|Ç
```
[Try it online!](https://tio.run/##1VG9TsMwGNzvKZyPSF2iij3KyFJ1A@bKSU3j4ia0dqkqMQBLmGFhZ2WESgGJIVEfxH0R4zYMfQWWT3ff/Sw3FUqtnRvMTlfR2QXs94f9emo@h@Kurdz2xdZvu4efZtNsWFvtHt/Z9tnWr86FGCWg8xImlxrUJ@pD5/xGxEA4SqhcQNyKIur0FV8jCEAHDVT4GOPQ8yX4QoDiky6ULg2TBlIzbaRS3pKVhZbaiMJ07YH3dubeIeEP9RBr3w@eZmNxNcnl9FrN/g37o5jkHiLNMIZn@@8eAYPoMpTHy9j6PhnGbfUL "Jelly – Try It Online")
Returns `[1]` for triangles, `[2]` for rectangles, `[3]` for squares and `[]` for messes
## How it works
```
ỴẈµLe|Ç - Main link. Takes a string S on the left
Ỵ       - Split S into a list of lines
 Ẉ      - Take the length of each line
  µ     - Use this list of lengths W as the left and right argument:
   L    - Length of W
    e   - This length is in W?
          This returns 1 for triangles and squares and for messes with
          one (or more) lines of a length of the number of lines in the mess
      Ç - Call the helper link on W
     |  - Logical OR
Jm0w,ET - Helper link. Takes a list of lengths W on the left
J       - Replace W with it's indices ([1, 2, ..., len(W)])
 m0     - Reflect; [1, 2, ..., len(W), len(W), ..., 2, 1]
   w    - Index of W as a sublist in this array, or 0
          This returns a non-zero number for triangles
     E  - Are all elements of W equal?
          This returns 1 for squares and rectangles
    ,   - Pair
      T - Return the indices of non-zero elements
          This yields:
            - [1] for triangles
            - [2] for rectangles/squares
            - []  for messes
```
Taking the logical or between these results yields:
* `1 | [1] = [1 | 1] = [1]` for triangles
* `0 | [2] = [0 | 2] = [2]` for rectangles
* `1 | [2] = [1 | 2] = [3]` for squares
* `1 | [] = []` or `0 | [] = []` for messes
[Answer]
## Javascript 125 bytes
```
_=>(g=(l=_.split('\n').map(a=>a.length)).
length)<3?0:(r=l.reduce((a,b)=>a==b?a:0))
?r==g?2:1:l.reduce((a,b)=>++a==b?a:0)?3:0
0 = Mess
1 = Rectangle
2 = Square
3 = Triangle
```
```
fa=_=>(g=(l=_.split('\n').map(a=>a.length)).length)<3?0:(r=l.reduce((a,b)=>a==b?a:0))?r==g?2:1:l.reduce((a,b)=>++a==b?a:0)?3:0
var square = `asd
asd
asd`
var rectangle = `asd
asd
asd
asd
asd
asd`
var triangle = `asd
asdf
asdfg
asdfgh`
var mess = `asd
dasdasd
sd
dasasd`
console.log(fa(square), fa(rectangle), fa(triangle), fa(mess))
```
[Answer]
# [Perl 5](https://www.perl.org/) `-p`, 83 bytes
* Mess: nothing
* Square: 0
* Triangle: 1
* Rectangle: 2
```
($z)=grep++$$_{"@+"-$_*~-$.}==$.,0,/$/,-1
}{$.<2or$_=$$z{$z>0||$.}?$z%2:@F>1&&2x!$z
```
[Try it online!](https://tio.run/##Dcq7DoIwGAbQnbeQfBK1F9omLMYiE5vP0HghxITYpjqYFnx0fz3zCUOcGqIN0taOcQiMAS6XHSsF3O4jIBdrIbniNWoudLFkyIPxEc4CKSO1ap7/64i0Nvuub3VVmfcKieh8Ky7Xrw@vu388SUyhJ3FqpFZS/QA "Perl 5 – Try It Online")
[Answer]
# PHP, ~~195~~ 205 bytes
```
<?$a=$argv[1];$r=substr($a,-2,1)=="\n"?strrev($a):$a;foreach(explode("\n",$r)as$l){$s=strlen($l);$x[$s
]=++$i;$m=$i==$s?T:M;}$z=count($x);echo$i*$z>2?$z==1&&key($x)==$i?S:($z==1&&$i>2?R:($i==$z?$m:M)):M;?>
```
The upside down triangle adds an expensive 56 bytes to this!
Outputs are S,R,T,M
Saved a few bytes thanks to Dom Hastings.
[Try it online!](https://tio.run/##LYxNbsIwEIX3OUWFRsguYRGWcQefgA10RxGaBpdYDbZlG5Sm6tXrTqTO6v1880IfSnnRQAgUr49jc1IQMd3fU44CqF5v6kYiLt7cQnMUzYNT2QKpDx8Ndb0wYxj8xYgZqSFKSjDIb0jI@GCcYKdgPEKqTrhagVVwQ7CIkPRru1M/MGHn7y4LGKUyXe/BPsO03WgusFkuP83XXPGD1YdW/KdgmdiznZcmDbd2JyXP6W1VSun4KqqIqln9@pCtd6msL0@p9zGffTDunOmK3v0B "PHP – Try It Online")
Fixed a few issues now... Test runs produce this.
```
$_="
$_="
$_""
;say
RESULT:S
=============
$_=
"no
t a
squ
are
";#
RESULT:R
=============
$
_=
"So
this
"."".
shape;
RESULT:T
=============
$_="or
even,
this
way
!!
"
RESULT:T
=============
as
smiley
asd
A
RESULT:M
=============
X
RESULT:M
=============
XX
RESULT:M
=============
cccc
a
aa
cccc
RESULT:M
=============
```
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), 81 bytes
```
{.lines>>.chars.&{($_==.[0],3)[2*(2>.max
)+($_ Z- .skip).&{.[0].abs+.Set*2+^2}]}}
```
[Try it online!](https://tio.run/##K0gtyjH7n1upoJamYPu/Wi8nMy@12M5OLzkjsahYT61aQyXe1lYv2iBWx1gz2khLw8hOLzexgktTGyihEKWroFecnVmgCVQIUqOXmFSsrRecWqJlpB1nVBtbW/ufqzixUiENqFhTIS2/iItTKTExMSYPQSjpoIghc4EYKpAE5SJUYOOg6odLQYz5DwA "Perl 6 – Try It Online")
Returns `True` for square, `False` for rectangle, `3` for triangle, `Nil` for mess.
[Answer]
# [Stax](https://github.com/tomtheisen/stax), 39 bytes
```
L{%m~;:-c:u{hJchC; 
|mb1=-C;%a\sI^^P}M0
```
[Run and debug online!](https://staxlang.xyz/#c=L%7B%25m%7E%3B%3A-c%3Au%7BhJchC%3B+%0A%7Cmb1%3D-C%3B%25a%5CsI%5E%5EP%7DM0&i=L%7B%25m%7E%3B%3A-c%3Au%7BhJchC%3B+%0A%7Cmb1%3D-C%3B%25a%5CsI%5E%5EP%7DM0%0A%0A%24_%3D%27%0A%24_%3D%22%0A%24_%22%27%0A%3Bsay%0A%0A%24_%3D%22but+it%0Ais+still+a%0Aconsistent%0Ashape%21%22%3B%23%23%0A%0A%24%0A_%3D%0A%22So%0Athis%0A%22.%22%22.%0Ashape%3B%0A%0A%24_%3D%22or%0Aeven,%0Athis%0Away%0A%21%21%0A%22%0A%0Ashape%3B%0A%24_%3D%22or%0Aeven,%0Athis%0Away%0A%21%21%0A%22%0A%0Ashape%3B%0A%0As%0Ah%0Aa%0Ap%0Ae%0A%3B&a=1&m=1)
Shortest ASCII-only answer so far.
> 
> 0 - Mess   
> 
> 1 - Rectangle   
> 
> 2 - Square   
> 
> 3 - Triangle   
> 
> 
> 
> 
## 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
```
[Answer]
# [Haskell](https://www.haskell.org/), ~~113~~ ~~107~~ ~~103~~ 101 bytes
```
((#)=<<k).map k.lines;k=length;1#x=0;l#x|x==[1..l]
  ||x==[l,l-1..1]=3;l#x=k[1|z<-[l,x!!0],all(==z)x]
```
[Try it online!](https://tio.run/##vZDBaoQwFEX3fsWbpFAFDdpZalbddmDodFFwpKQSo/gmTE0EGfz22sROp/QHuklyzr1v8dIK00vEpeHHJQxpxIuij9hJnKFn2Glp8p6j1Mq2eUYnnuZIp3nivMwYwyoAmFfCGBNnsopvfYP3ZTZfisT5abNJq1gghpxfoqlaFKTAgeykMSRQkHl4lrUVWqH05sGbw8cohhW3Hl@G7pa/raIV9t6AgPdRMRIEJ9Fp5ztt5SBqC3eggEETJAlcI7fTDsLzaA92eNIuXAsRlISSmFBKj/r74e5fcz08/@R/zG2EVP/zf591g0KZJXl93O@/AA "Haskell – Try It Online")
Returns 0, 1, 2 and 3 for mess, rectangle, square and triangle, respectively.
*Edit: -2 bytes thanks to [Lynn](https://codegolf.stackexchange.com/users/3852/lynn)!*
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), ~~35~~ ~~29~~ 27 bytes
Saved 8 bytes thanks to *Magic Octopus Urn*
```
DgV€g©ZU¥ÄP®Y
QP®ËJCXY‚1›P*
```
[Try it online!](https://tio.run/##MzBNTDJM/f/fJT3sUdOa9EMro0IPLT3cEnBoXSRXIJA83O3lHBH5qGGW4aOGXQFa//9Hq6vE2yrlF6nrKKinlqXm6YAYJRmZxSC6PLESRCkqgkgl9VgA "05AB1E – Try It Online")
`0` = Mess  
`4` = Triangle  
`1` = Rectangle  
`3` = Square
[Answer]
# [R](https://www.r-project.org/), 101 bytes
```
"if"(var(z<-nchar(y<-scan(,"",,,"
","")))==0,"if"(length(y)==z,1,2
),"if"(all(abs(diff(z))==1),3,4))
```
> 
> 1=Square  
> 
>  2=Rectangle   
> 
>  3=Triangle   
> 
>  4=Random   
> 
> 
> 
> 
Code cannot deal with 'NEGATIVE ACKNOWLEDGE' (U+0015) or the square in the code above. This byte can be switched to something different if the input requires contains this byte.
[Try it online!](https://tio.run/##vZJBa8MwDIXvuu@eaIPaoJZ12y3NYbBrN@huvQw3cxaDcbbIbUn@vKss/8EghHhIvI@HhpTQtaguZlDTbh2aToZxt@bGBEWIRISAhHeota7rR/rf9jb8xE6Noky0pSfQi268V@bE6tu1rZrmg62mZ3rROj181SuQhtJwBRWbESCL9ewKGHqIhQH@O4MZLGB1n9EeT@dYuAiOC47OewFp@sCOow0RuDO/thSifEgwR/IpkXSOATeIm4WiyhlKP4C92EALxVUeoiwBcxEcXt/fPvZHOEqldAM "R – Try It Online")
[Answer]
# Snails, 29 bytes
```
ada7A
.2,lr
?!(t.
rw~)z
.+~o~
```
Output key:
* **0** - Mess
* **3** - Triangle
* **6** - Rectangle
* **7** - Square
It would be 23 bytes without source layout:
```
zA
.2,dun!(t.rf~)z.+~o~
```
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), 119 bytes
```
(x=StringLength/@#~StringSplit~"\n")/.{{1}->3,s~(t=Table)~{
s=Tr[1^x]}:>0,x[[1]]~t~s:>1,(r=Range@s)|Reverse@r:>2,_->3}&
```
Using `Replace` `/.` and pattern matching on the character count by line. `Replace` will kick out the first RHS of a rule that is matched, so the ordering is to test for the 1 character input, then squares, rectangles, triangles, and a fall-through for messes.
square=0,rectangle=1,triangle=2,mess=3
[Try it online!](https://tio.run/##NY3bUoMwEIbvfQqbdhRmYhF7BxOGB/DCKb1jaSdtw6HSbU2i0kHy6pjIeLGn//9298x1Lc5cNwc@lmz0OpZp2WD1KrDSdZDOzTRn17bRhgASP1j2fTg8JSuqjKfZhu9b4Zv@TrGNzMNtVwxR8ky7PA@LwmijoiSknmRrjpVIlf@zFl9CKpHKKHmhO3tneBjf7A@dl0Hak8WOAblIQIshBdR1owC/@Q1wNgMEQihZAFrK9tnlHwCyBOISqppfReyoiUHH3HNrfHwCcimcGM8n4BHw76ErQOwUK36zFlfHtnw/2WJX1LF0kgvA/YEMxfgL "Wolfram Language (Mathematica) – Try It Online")
[Answer]
# [Red](http://www.red-lang.org), 209 bytes
```
func[s][c: copy[]foreach a split s"^/"[append c length? a]d: unique c
r: 0 if 1 < l: length? c[if 1 = length? d[r: 2 if(do d)= l[r: 1]]n: 0
v: copy[]loop l[append v n: n + 1]if(v = c)or(v = reverse c)[r: 3]]r]
```
[Try it online!](https://tio.run/##XY/BTsMwEETv@xUbF6lUoEDLLaXiH@BomcrYDrEU2cZ2girUbw@bps0hF2u182Z2HI0e3o1GLqCuhrpziifBVYXKhxMXtY9GqgYlptDajIl9PjEuQzBOo8LWuO/cvKEUusLO2Z/OoIJY4TPaGrf4im01Q4pfdod5oTmROyLvtUe9IWFcbIVwFAD9rUPrfSDperRHUh0@EEfGnuLUxsfLEE1vYqIGmzHnRYgohhCty1jj393xwL66jDaDTZiybVuUoLxLNmXjMqRGBlOw/Wp1BphsV98aRjM9bA37JE@zPspwPAD78JAbm4CVjJVT0n5JleWSo2GB3or6CPQX9zjRv/IERQHsPPwD "Red – Try It Online")
`0` Mess
`1` Square
`2` Rectangle
`3` Triangle
[Answer]
# [AWK](https://www.gnu.org/software/gawk/manual/gawk.html), 119 bytes
```
{p=l;l=L[NR]=length($0)
D=d}{d=p-l;x=x?x:NR>2?\
d!=D:0}END{print x==1?\
3:d*d==1?(L[NR]+L[1]==\
NR+1)?2:3:p!=NR}#######
```
[Try it online!](https://tio.run/##JYy7CoMwFED3@xWNddDago8tcpvFbpIhq0oREqo02CBSUyTfnr7OdDjD6de795tBXWqsGy461Gq6LUMUpjFUKN0m0Zx0adEyS7k456wFSbCiqbvwajPzOC07i5h9ekHlQX41@q2Susk6xBa4SLKY5bSghiAXbv/H@/CKwWMG9VTTEZZhhLV/ASEQwBs "AWK – Try It Online")
Output:
`0` = Square  
`1` = Rectangle  
`2` = Triangle  
`3` = Mess
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~115~~ 111 bytes
```
->s{m=s.split(?\n).map &:size;r=*1..s=m.size;s<2?4:(m|[
]).size<2?m[0]<2?4:s==m[0]?1:2:r==m.reverse||r==m ?3:4}
```
[Try it online!](https://tio.run/##HYrBDoIwEAXv/YpCiAGjjSCnytoPQWIwltjEYrOLGhS/vRZuM/MePi@j78Bvj/S1QILc3QypOvWZsK3jK0nmow8I61wIAisWpapQpUztVLMmW1IItt41SyeAmVUuC4mBBeqXRtLTNBtXe1n@vONdnVRhaq@NT84QP5CFW79hw80Qe7cjiyIW/wE "Ruby – Try It Online")
Anonymous lambda. Outputs:
1. Square
2. Rectangle
3. Triangle
4. Mess
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~125~~ 123 bytes
Thanks to [ceilingcat](https://codegolf.stackexchange.com/users/52904/ceilingcat) for -2 bytes.
```
f(L,n)int**L;{int i,l,c,F=strlen(*L),s=-F;for(l=i=0;i<n;l=c)c
=strlen(L[i++]),s+=c-l;s=n>1?s||F<2?~abs(s)+n?0:3:n^F?2:1:0;}
```
[Try it online!](https://tio.run/##bVFNc9owED3bv0JRmqlsiwwYQmYQDjdO3HrEtGOEMJpx1tRr0ukQ8tepJJuBNL5oP/Te076V7OVSnu81yOKwUWSKdaUhf9y9@Le9jS5N67xlCw6BhjoMF@JoItG84JLPE0MrFLBwEXBMenOxLStWJDrpCz0FUSQykP4FtFjqKFoZYJTIXiEwgZfBDN/f59N49pGtkWEQwaw/GU7g53wWTwaTvjid30q9ITmTJWBN5C6rSBgWGhRyYgeBwD/63u0t7rK9wuWKJORIXxUi5YTi70NWKZtVStYZ5IUrjOkmPwnfs3Joou8ZF4Q5m0akL0yYEjAhigLf8/aHGpkbYalXgSOgwW1ZOxY0vb1ZaL1lNIWHDWEPGKSQgnnUINoR0bJPvm9fes00sC9eaoX1oLXy7VeSfrdD24Q2SUqblsDsr/PwPzm@ki0upVA63yRrt2JDu5mUivtOkeFFxKIuQj8aoZ3Gpn5M7WFyjzp7olNqdGOGlpWlqjcF/Fbrj/Fiwt1dI9yp89TqqKrMYV2q3GLN@l3EvIBO1vgLqwv13KJitxt7rB3O93LmPoSTkf3ipoo5GV@r4adq9Kl64mR4rcacDK7Vc3N3Ov8D "C (gcc) – Try It Online")
]