jchi2241
jchi2241

Reputation: 2226

Determining if 4 given integer points creates a square

I'm currently a programmer noob, and I've been working through problems on CodeEval for practice. Right now, I'm working on CodeEval's "Find a Square" problem. https://www.codeeval.com/open_challenges/101/

The method I'm utilizing is the one described by Joel Brown: https://softwareengineering.stackexchange.com/questions/176938/how-to-check-if-4-points-form-a-square

I'm passing 9 out of the 10 test cases given. The thing is though CodeEval doesn't seem to give you their test inputs, so I'm working blind on figuring out what case I'm missing. I'm assuming a case that's suppose to test as "true" is leaking through to the else statement, meaning I'm missing one of the possible point assignment positions for the given points.

   def is_square? a, b, c, d
      #distances between all points
      ab = Math.sqrt((a[0] - b[0])**2 + (a[1] - b[1])**2)
      ac = Math.sqrt((a[0] - c[0])**2 + (a[1] - c[1])**2)
      ad = Math.sqrt((a[0] - d[0])**2 + (a[1] - d[1])**2)

      cd = Math.sqrt((c[0] - d[0])**2 + (c[1] - d[1])**2)
      bc = Math.sqrt((b[0] - c[0])**2 + (b[1] - c[1])**2)
      bd = Math.sqrt((b[0] - d[0])**2 + (b[1] - d[1])**2)

      ba = ab, ca = ac, da = ad, dc = cd, cb = bc, db = bd

      #possible point positions
      if ab == ac
        return false if bc != Math.sqrt(ab**2 + ac**2) #check if right triangle
        return false if bd != cd #check if other sides equal each other
        return false if bc != ad #check diagonals
        return false if ab != bd #check if all sides are equal
      elsif ab == ad
        return false if bd != Math.sqrt(ab**2 + ad**2) #check if right triangle
        return false if bc != dc #check if other sides equal each other
        return false if ac != bd #check diagonals
        return false if ab != bc #check if all sides are equal
      elsif ac == ad
        return false if cd != Math.sqrt(ac**2 + ad**2) #check if right triangle
        return false if cb != db #check if other sides equal each other
        return false if ab != cd #check diagonals
        return false if ac != cb #check if all sides are equal
      else 
        return false
      end

      return true
    end

    File.open(ARGV[0]).each_line do |line|
      a, b, c, d = line.strip.split(" ")

      a = a.scan(/\d+/).map(&:to_i)
      b = b.scan(/\d+/).map(&:to_i)
      c = c.scan(/\d+/).map(&:to_i)
      d = d.scan(/\d+/).map(&:to_i)

      puts is_square?(a, b, c, d)
    end                         

Upvotes: 1

Views: 180

Answers (1)

Nick Veys
Nick Veys

Reputation: 23939

It looks like you can do puts statements in the CodeEval system, so add some debugging prints to your code, that will let you extract the test input and let you debug it locally.

Also, you're comparing floating point values using == and !=. This will often lead to issues. Two edges may be calculated to be, for example, 4.000001 and 4.0. These will not be equal, but in fact they probably are, and are just falling victim to the representation being imprecise.

Usually, comparisons of floating point values use an acceptable difference between the numbers to consider them equal. Here is a question regarding that with Ruby code.

Good luck!

Upvotes: 1

Related Questions