Menu Close

Vértices de un cuadrado

Definir la función

   esCuadrado :: (Num a, Ord a) => (a,a) -> (a,a) -> (a,a) -> (a,a) -> Bool

tal que (esCuadrado p q r s) se verifica si los puntos p, q, r y s son los vértices de un cuadrado. Por ejemplo,

   esCuadrado (0,0) (0,1) (1,1) (1,0)    == True
   esCuadrado (0,0) (2,1) (3,-1) (1, -2) == True
   esCuadrado (0,0) (1,1) (0,1) (1,0)    == True
   esCuadrado (1,1) (1,1) (1,1) (1,1)    == True
   esCuadrado (0,0) (0,2) (3,2) (3,0)    == False
   esCuadrado (0,0) (3,4) (8,4) (5,0)    == False
   esCuadrado (0,0) (0,0) (1,1) (0,0)    == False
   esCuadrado (0,0) (0,0) (1,0) (0,1)    == False
   esCuadrado (0,0) (1,0) (0,1) (-1,-1)  == False

Soluciones

import Data.List (sort, tails)
 
esCuadrado :: (Num a, Ord a) => (a,a) -> (a,a) -> (a,a) -> (a,a) -> Bool
esCuadrado p q r s = and [a == b, b == c, c == d, e == f, a + b == e]
  where [a,b,c,d,e,f] = sort (distancias p q r s)
 
-- (distancias p q r s) es la lista de los cuadrados de las longitudes
-- de los lados y de las diagonales del cuadrilátero cuyos vértices son
-- los puntos p, q, r y s. Por ejemplo,
--    distancias (0,0) (0,1) (1,1) (1,0)  ==  [1,2,1,1,2,1]
--    distancias (0,0) (3,4) (8,4) (5,0)  ==  [25,80,25,25,20,25]
--    distancias (0,0) (0,2) (3,2) (3,0)  ==  [4,13,9,9,13,4]
--    distancias (0,0) (0,0) (1,1) (0,0)  ==  [0,2,0,2,0,2]
--    distancias (0,0) (0,0) (1,0) (0,1)  ==  [0,1,1,1,1,2]
distancias :: Num a => (a,a) -> (a,a) -> (a,a) -> (a,a) -> [a]
distancias p q r s =
  [l | (h:t) <- tails [p,q,r,s], l <- map (dist h) t]
 
-- (dist p q) es el cuadrado de la distancia del punto p al q. Por
-- ejemplo,
--    dist (6,4) (3,8)  ==  25
dist :: Num a => (a,a) -> (a,a) -> a
dist (x1,y1) (x2,y2) = (x2-x1)^2 + (y2-y1)^2

4 soluciones de “Vértices de un cuadrado

  1. alerodrod5
    import Data.List(sort,group)
    resta ::(Num a, Ord a) =>  (a,a) -> (a,a) -> (a,a)
    resta (x,y) (a,b) = (x-a,y-b)
     
    esCuadrado :: (Num a, Ord a) => (a,a) -> (a,a) -> (a,a) -> (a,a) -> Bool
    esCuadrado p q r s =length xs == 1 || (length xs == 2 && length (head xs) ==4 && head (last xs) == 2*head(head xs))
      where moduloCuadrado (a,b) = a^2+b^2
            xs =  group(sort(map moduloCuadrado [resta p q,resta p r,resta p s,resta q r,resta q s,resta r s]))
  2. agumaragu1
    import Data.List (sort, group)
     
    esCuadrado :: (Num a, Ord a) => (a,a) -> (a,a) -> (a,a) -> (a,a) -> Bool
    esCuadrado a b c d = aux distancias
      where distancia2 (p,q) (r,s) = (p-r)^2 + (q-s)^2
            distancias = group $ sort $  distancia2 <$> [a,b,c,d] <*> [a,b,c,d]
            aux [a,b,c] = length a == 4 && head b * 2 == head c
            aux xs = all (==0) $ concat xs
  3. carbremor
    import Data.List
    import Test.Hspec 
     
    -- Escribrimos una función distancia que nos permite calcular
    -- la distancia cartesiana entre dos puntos del plano: http://bit.ly/2cLggEq
    -- Pues, a partir de cada punto ya podríamos calcular la distancia
    -- a los otros tres puntos.
     
    distancia (x1, y1) (x2, y2) = sqrt $ (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)
     
    -- λ> distancia (2,5) (3,1)
    -- 4.123105625617661
    -- (0.01 secs, 93,816 bytes)
     
    -- Para la función esCuadrado, sabemos que un conjunto de puntos forma un
    -- cuadrado si se cumplen las siguientes condiciones:
     
    -- 1. Todas las distancias son iguales
    -- 2. Las dos distancias más cortas son iguales
    -- 3. La mayor distancia (diagonal) es sqrt(2*a^2), donde a es la distancia más corta
     
    esCuadrado (x1, y1) (x2, y2) (x3, y3) (x4, y4) =
      let m1 = distancia (x1,y1)
          m2 = distancia (x2,y2)
          m3 = distancia (x3,y3)
          m4 = distancia (x4,y4)
          d1 = sort $ map m1 [(x2,y2),(x3,y3),(x4,y4)]
          d2 = sort $ map m2 [(x1,y1),(x3,y3),(x4,y4)]
          d3 = sort $ map m3 [(x1,y1),(x2,y2),(x4,y4)]
          d4 = sort $ map m4 [(x1,y1),(x2,y2),(x3,y3)] 
      in d1 == d2 && d2 == d3 && d3 == d4 && d1!!0 == d1!!1 && sqrt((d1!!0)^2+(d1!!1)^2) == d1!!2 
     
    -- ---------------------------------------------------------------------
    -- § Verificación                                                     --
    -- ---------------------------------------------------------------------
     
    verificaVértices :: IO ()
    verificaVértices = hspec $ do
      describe "esCuadrado" $ do
        it "e1" $ do 
         esCuadrado (0,0) (0,1) (1,1) (1,0)   `shouldBe`
           True
        it "e2" $ do
         esCuadrado (0,0) (2,1) (3,-1) (1, -2) `shouldBe`
            True
        it "e3" $ do
          esCuadrado (0,0) (1,1) (0,1) (1,0) `shouldBe`
           True
        it "e4" $ do
         esCuadrado (1,1) (1,1) (1,1) (1,1) `shouldBe`
            True
        it "e5" $ do
         esCuadrado (0,0) (0,2) (3,2) (3,0) `shouldBe`
             False
        it "e6" $ do
         esCuadrado (0,0) (3,4) (8,4) (5,0)  `shouldBe`
             False
        it "e7" $ do
         esCuadrado (0,0) (0,0) (1,1) (0,0) `shouldBe`
             False
        it "e8" $ do
         esCuadrado (0,0) (0,0) (1,0) (0,1)  `shouldBe`
             False
        it "e9" $ do
         esCuadrado (0,0) (1,0) (0,1) (-1,-1) `shouldBe`
             False
     
     
    -- λ> verificaVértices
     
    -- esCuadrado
      -- e1
      -- e2
      -- e3
      -- e4
      -- e5
      -- e6
      -- e7
      -- e8
      -- e9
     
    -- Finished in 0.0262 seconds
    -- 9 examples, 0 failures
    -- (0.03 secs, 320,360 bytes)
  4. jaibengue
    import Data.List
     
    esCuadrado :: (Num a, Ord a) => (a,a) -> (a,a) -> (a,a) -> (a,a) -> Bool
    esCuadrado p1 p2 p3 p4 = (aux.sort) [p1,p2,p3,p4]
      where aux [a,b,c,d] =
              u == v
              && u == v'
              && u == w'
              && 2*u == w
              where vector (x,y) (x',y') = (x'-x, y'-y)
                    qlong (x,y) = x^2+y^2
                    u = qlong(vector a b)
                    v = qlong(vector a c)
                    w = qlong(vector a d)
                    v'= qlong(vector b d)
                    w'= qlong(vector c d)

Escribe tu solución

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.