# The challenge:

Given four coordinates, each in x y form, your job is to find out whether or not the given coordinates form a rectangle, and output a truthy/falsey.

## Rules:

• For the sake of simplicity, squares, lines (two identical pairs of coordinates) or dots (all four of the coordinates are the same) are all counted as rectangles

• Coordinates for rectangles can be given in any order, for example this:

A----B
|    |
D----C


and this:

A---B
|   |
|   |
|   |
C---D


are both rectangles.

• Rectangles can be rotated, so they won't always be parallel to x and y axis.

• You may take input in any form you like as long as the order for each coordinate is not mixed: [x,x,x,x,y,y,y,y] is not acceptable, where as [x,y,x,y,x,y,x,y] or [(x,y),(x,y),(x,y),(x,y)] is fine.

• Complex numbers are a valid form of input

• This is codegolf, so lowest byte count wins.

## Test cases:

[0,2, 3,2, 3,0, 0,0]      Truthy
[3,5, 2,0, 0,2, 5,3]      Truthy
[6,3, 3,5, 0,2, 3,0]      Falsy
[1,4, 5,2, 4,0, 0,2]      Truthy
[0,0, 0,0, 3,2, 4,0]      Falsy
[1,1, 1,1, 1,1, 1,1]      Truthy
[1,4, 100,1, 100,1, 1,4]  Truthy

• Is [6,3,3,5,0,2,2,0] really a rectangle?
– xnor
Apr 5 '20 at 9:45
• @Arnauld Good point, spacing it better does make the rectnagles clearer. It looks like the second test case actually has the issue that the points are in the wrong order, making a self-crossing shape.
– xnor
Apr 5 '20 at 11:49
• @SurculoseSputum I'm understanding it the other way, that the "Coordinates should not be treated like this figure:" means we should always interpret input points as being in cyclic order, so that the second test case wouldn't be a rectangle. I've VTC'ed as unclear.
– xnor
Apr 5 '20 at 12:34
• @Noodle9 fully approve of your edit, thank you!
– Dion
Apr 5 '20 at 17:13
• @MitchellSpector, yep
– Dion
Apr 5 '20 at 17:34

# Python 3, 88 $$\\cdots\$$ 54 43 bytes

lambda l:len({abs(sum(l)/4-z)for z in l})<2


Try it online!

How

Calculates the distances from the quadrilateral's centre of mass to all of its vertices and tests if they're equal.

Input The four vertices as a sequence of complex numbers in any order.
Output True/False

• Oh, I see, that's clever. That should work then in the "in any order" interpretation of the challenge.
– xnor
Apr 5 '20 at 16:46
• A nice solution! Apr 5 '20 at 16:50
• Here's an argument that convinced me only a rectangle passes your test. Consider the circle on which four points lie. Its center must be the points' center of mass. One way to "average" the four points is to take the midpoint between two points and then midpoint between the other two points, and take the midpoint between those midpoints. To get the center of the circle at the end, the two midpoints must be opposite each inside the circle. (cont'd)
– xnor
Apr 5 '20 at 17:06
• (continuing) Draw the segment between the two midpoints. We can obtain the pair of points on the circle producing a midpoint by drawing the perpendicular to that segment and intersecting it with the circle. In fact, this the only such of pair of points on the circle. Doing so for both midpoints, we find that central segment is now perpendicular to two equal-length segments whose endpoints are the four corners, so they form a rectangle. (This was all probably confusing without a drawing...)
– xnor
Apr 5 '20 at 17:08
• Diagram
– xnor
Apr 5 '20 at 23:11

# Jelly, 6 bytes

A port of Noodle9's Python answer with a slight adjustment for golfing purposes.

×4_SAE


A monadic Link accepting a list of four complex numbers which yields 1 if they form a rectangle or 0 if not.

Try it online! Or see the test-suite.

### How?

Checks that all four coordinates are equidistant from the centre of mass of the uniform density quadrilateral.

×4_SAE - Link: list of complex numbers, C
4     - literal four
×      - (C) multiply (4) (vectorises across C)
S   - sum (of C)
_    - (C×4) subtract (sum(C)) (vectorises across C×4)
A  - absolute value (vectorises)
E - all equal?


Note this still works given an equilateral triangle with a repeated coordinate (it would skew the centre of mass toward the repeated coordinate).

The equivalent change to Noodle9's program would be:

lambda l:len({abs(z*4-sum(l))for z in l})<2


# 05AB1E, 11 bytes

Port of Noodle9's Python answer. 05AB1E doesn't have complex numbers, so it ends up a bit long.

εIøO4/-}nOË


Try it online!

# Python 3, 115108 107 bytes

This solution finds if any permutation of A,B,C,D results in a rectangle. Output is correct for all test cases except test case 3 which is not a rectangle due to corners not equal to 90 degrees.

lambda a,b,c,d:g(a,b,c,d)+g(a,c,b,d)+g(a,b,d,c)
g=lambda a,b,c,d:b+d-a-c==((b-a)*(d-a).conjugate()).real==0


Try it online!

Input: 4 complex numbers representing the 4 coordinates.
Output: a positive integer if input is a rectangle, or 0 if input is not.

105 bytes if output can be 0 for rectangle, and non-zero for non-rectangle.

lambda a,b,c,d:g(a,b,c,d)*g(a,c,b,d)*g(a,b,d,c)
g=lambda a,b,c,d:b+d-a-c or((b-a)*(d-a).conjugate()).real


# APL2: 33 bytes

Yet another port of Noddle9's answer, this time in APL2.

Prerequisites:

1. This is code is ⎕IO-dependant since it uses Partition with axis. This example in ⎕IO=0
2. The list of coordinates is stored in variable C.

D≡⌽D←↑+/(M-+/¨.25×M←⊂[1]⍉4 2⍴C)*2

The result is either 1 for true or 0 for false.

### An example

If C is the vector 3,5,2,0,0,2,5,3 or rather 3 5 2 0 0 2 5 3, then the first thing that happens is that 4 2⍴C turns it into a 4x2 matrix:

3 5
2 0
0 2
5 3


Then ⍉ transposes that matrix and ⊂[1] turns it into a vector of 2 vectors (x & y). This is stored as M: ((3 2 0 5)(5 0 2 3)).

Next M is multiplied with 0.25 and summed element-wise: (this is what +/¨ does)

(2.5 2.5).

Now we subtract this from M and square the differences: (M- ...)*2 (yes, * is "power"). We now have: (0.25 0.25 6.25 6.25)(6.25 6.25 0.25 0.25).

This is summed by the +/ outside the brackets and we get ((6.5 6.5 6.5 6.5)). Sadly we have a 4-element vector inside another structure so we have to "spend" a character to remove the outer shell: ↑.

The inner vector is assigned to variable D. Finally we use ≡ to compare D to its reverse ⌽D thereby checking if all items are equal.

# APL (Dyalog Unicode), 25 bytes

{1=≢∪|⍵-+/⍵÷4}


Try it online!

input: complex numbers.

distances from centre of gravity must match.

# Husk, 13 bytes

Λ=mO½´×oΣzo□-


Try it online!

I'm not sure if this is correct.

It takes Euclidean distance between all pairs and checks if the resulting array is symmetric.

# Vyxal, 12 bytes

ƛ?ÞTvṁ-²∑√;≈


Try it Online!

ƛ         ;  # Map to...
?           # Input
ÞT         # Transposed
vṁ       # Take the average of each (center)
-      # Get the x and y distances to the center
²∑√   # Pythagoras to get abs. dist. to center
≈ # Are all equal?


# Ruby, 44 bytes

Input is an array of 4 complex numbers, again.

->l{l.map{|z|(l.sum/4.0-z).abs}.uniq.size<2}


Try it online!

# Bash + GNU utilities, 77 bytes

cat>t;join -j3 t t|xargs -I% dc -e%sDsClD-d*sqlC-d*lq+p|sort|uniq -c|grep 2\


(There's a space at the end, after the backslash.)

Try it online!

Or try the entire test suite online.

The input is in the form:

x1 y1
x2 y2
x3 y3
x4 y4


(with a newline after each point).

The output is the exit code: 0 for falsey, 1 for truthy.

Here's how it works (there are no complex numbers available in bash):

1. The join computes all the pairs of points. There are 4 points, so there are 16 pairs of points. (This includes each pair in both orders, and it even includes pairs where the two points are the same.)

2. The xargs command uses dc to compute the square of the distance between each pair of points. We now have a list of all the squares of the distances between pairs of the points.

3. Now, sort|uniq -c computes how many times each value appears in the list of squared distances.

4. The original four points form a rectangle iff no value appears exactly twice in the list.

# Wolfram Language (Mathematica), 32 bytes

Equal@@Norm/@(r=#;Mean@r-#&/@r)&


This is a port of Noodle9's Python answer. I start by determining the centroid of the four points, which is their average position in space, by taking the mean of the four vectors corresponding to each. [N.B.: If the points had mass, and their masses were identical, this would give their center of mass.]. I then subtract each point from the centroid, and determine the lengths (norms) of the four resulting vectors. I then test to see if all four norms are the same.

Try it online!

Alternately, the following is also 32 bytes. Though this one is non-competing, since the challenge was posted ~May 2020, and this uses new syntax (|-> as a shorthand for \[Function] ) that wasn't introduced until v. 12.2 of Mathematica, which was released in Dec. 2020:

Equal@@Norm/@(r|->Mean@r-#&/@r)&


Interestingly, the above doesn't work in tio.run , because it's using version 12.0.1 for Linux x86 (64-bit) (October 16, 2019).