<p>Given the coordinates of four points in 2D space <code>p1</code>, <code>p2</code>, <code>p3</code> and <code>p4</code>, return <code>true</code> <em>if the four points construct a square</em>.</p>

<p>The coordinate of a point <code>p<sub>i</sub></code> is represented as <code>[x<sub>i</sub>, y<sub>i</sub>]</code>. The input is <strong>not</strong> given in any order.</p>

<p>A <strong>valid square</strong> has four equal sides with positive length and four equal angles (90-degree angles).</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,1]
<strong>Output:</strong> true
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,12]
<strong>Output:</strong> false
</pre>

<p><strong class="example">Example 3:</strong></p>

<pre>
<strong>Input:</strong> p1 = [1,0], p2 = [-1,0], p3 = [0,1], p4 = [0,-1]
<strong>Output:</strong> true
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>p1.length == p2.length == p3.length == p4.length == 2</code></li>
	<li><code>-10<sup>4</sup> &lt;= x<sub>i</sub>, y<sub>i</sub> &lt;= 10<sup>4</sup></code></li>
</ul>

class Solution {
public:
    bool validSquare(vector<int>& p1, vector<int>& p2, vector<int>& p3, vector<int>& p4) {
        double d1 = m_dist(p1, p2);
        double d2 = m_dist(p1, p3);
        double d3 = m_dist(p1, p4);
        double side, diagonal;

        if (d1 == d2) {
            side = d1;
            diagonal = d3;
        }
        else if (d1 == d3) {
            side = d1;
            diagonal = d2;
        }
        else if (d2 == d3) {
            side = d2;
            diagonal = d1;
        }
        else
            return false;

        return diagonal > side
            && m_check(p2, p3, p4, p1, side, diagonal)
            && m_check(p3, p4, p1, p2, side, diagonal)
            && m_check(p4, p1, p2, p3, side, diagonal);
    }

private:
    static double m_dist(vector<int>& p1, vector<int>& p2) {
        return pow(p1[0] - p2[0], 2) + pow(p1[1] - p2[1], 2);
    }

    static bool m_check(vector<int>& p1, vector<int>& p2, vector<int>& p3, vector<int>& p4, double side, double diagonal) {
        double d1 = m_dist(p1, p2);
        double d2 = m_dist(p1, p3);
        double d3 = m_dist(p1, p4);

        if (d1 == diagonal)
            return d2 == side && d3 == side;
        if (d2 == diagonal)
            return d1 == side && d3 == side;
        if (d3 == diagonal)
            return d1 == side && d2 == side;
        return false;
    }
};
28900