Programming Praxis – Four Points Determine A Square

In today’s Programming Praxis exercise, our goal is to determine whether four given points in a 2D plane make up a square. Let’s get started, shall we?

An  import:

import Data.List

The provided solution calculates the squares distances between the first and the three other points and considers the points a square when the smallest two are equal and the largest is the sum of the two smallest, i.e. a2 + b2 = c2. This solution is incorrect, however. If we take the points (0, 0), (1, 0), (0, 1) and (-1, -1), both conditions are satisfied despite the fact that the four points do not form a square. To handle this case correctly, we can use the same basic approach, albeit expanded a bit. Instead of just three distances, we calculate the distances between all six pairs. Of these six, the four smallest ones should be equal, as should the two larger ones. Pythagoras’ theorem can remain the same.

isSquare :: (Num a, Ord a) => (a, a) -> (a, a) -> (a, a) -> (a, a) -> Bool
isSquare p q r s = and [a == b, b == c, c == d, e == f, a + b == e] where
    [a,b,c,d,e,f] = sort [l | (h:t) <- tails [p,q,r,s], l <- map (dist h) t]
    dist (x1,y1) (x2,y2) = (x2-x1)^2 + (y2-y1)^2

Testing reveals that this version handles the old test cases correctly, as well as the example described above.

main :: IO ()
main = do print $ isSquare (0,0) (0,1) (1,1) (1,0)
          print $ isSquare (0,0) (2,1) (3,-1) (1, -2)
          print $ isSquare (0,0) (1,1) (0,1) (1,0)
          print . not $ isSquare (0,0) (0,2) (3,2) (3,0)
          print . not $ isSquare (0,0) (3,4) (8,4) (5,0)
          print . not $ isSquare (0,0) (0,0) (1,1) (0,0)
          print . not $ isSquare (0,0) (0,0) (1,0) (0,1)
          print . not $ isSquare (0,0) (1,0) (0,1) (-1,-1)
About these ads

Tags: , , , , , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

Join 35 other followers

%d bloggers like this: