Camel
Peter
Peter Campbell Smith

Ugly and square

Weekly challenge 123 — 26 July 2021

Week 123: 26 Jul 2021

Task 2

Task — Square points

You are given coordinates of four points: (x1, y1), (x2, y2), (x3, y3) and (x4, y4).

Write a script to find out if the given four points form a square.

Examples


Input: x1 = 10, y1 = 20
       x2 = 20, y2 = 20
       x3 = 20, y3 = 10
       x4 = 10, y4 = 10
Output: 1 as the given coordinates form a square.

Input: x1 = 12, y1 = 24
       x2 = 16, y2 = 10
       x3 = 20, y3 = 12
       x4 = 18, y4 = 16
Output: 0 as the given coordinates don't form a square.

Analysis

The points form a square if:

  • all four sides are equal length, and
  • both diagonals are sqrt(2) times the length of the sides.

It is not necessary that the sides of the square parallel the x and y axes - see my fourth example.

Try it 

Try running the script with any input:



example: (1, 2), (2, 2), (2, 1), (1, 1)

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2021-07-26
use utf8;     # Week 123 - task 2 - Square points
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

square_points(0, 0, 0, 2, 2, 2, 2, 0); # true
square_points(0, 0, 0, 2, 2, 2, 2, 3); # false
square_points(-2, 0, 0, 2, 2, 0, 0, -2); # true
square_points(-1, -1, 1, -1, 3, 1, 1, 1); # false
square_points(87, 34, 9, -44, 3, 61, 0, 77); # false

sub square_points {
    
    my (@p, $out, $side);
    
    # initialise
    @p = @_;
    
    # get length of side
    $side = dist($p[0], $p[1], $p[2], $p[3]);

    # other 3 sides the same and diagonals = sqrt(2) * side
    $out = (abs(dist($p[2], $p[3], $p[4], $p[5]) - $side) < 1e-5
        && abs(dist($p[4], $p[5], $p[6], $p[7]) - $side) < 1e-5
        && abs(dist($p[6], $p[7], $p[0], $p[1]) - $side) < 1e-5
        && abs(dist($p[0], $p[1], $p[4], $p[5]) - ($side * sqrt(2)) < 1e-5)
        && abs(dist($p[2], $p[3], $p[6], $p[7]) - ($side * sqrt(2)) < 1e-5))
        ? 1 : 0;
    
    say qq[\nInput:  ] . 
        sprintf('(%d, %d), (%d, %d), (%d, %d), (%d, %d)', @p);
    say qq[Output: $out];
}

# distance between 2 points
sub dist {
    my @p = @_;
    return sqrt(($p[0] - $p[2]) ** 2 + ($p[1] - $p[3]) ** 2);
}

last updated 2026-03-05 — 16 lines of code

Output



Input:  (0, 0), (0, 2), (2, 2), (2, 0)
Output: 1

Input:  (0, 0), (0, 2), (2, 2), (2, 3)
Output: 0

Input:  (-2, 0), (0, 2), (2, 0), (0, -2)
Output: 1

Input:  (-1, -1), (1, -1), (3, 1), (1, 1)
Output: 0

Input:  (87, 34), (9, -44), (3, 61), (0, 77)
Output: 0

Input:  (0, 0), (1, 0), (0, 0), (1, 0)
Output: 0

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain