I'm trying to check whether a number is a perfect square.
This is my code:
def is_square(x)
return true if
math.sqrt(x).is_a? Integer
end
Any idea why it doesn't work?
I'm trying to check whether a number is a perfect square.
This is my code:
def is_square(x)
return true if
math.sqrt(x).is_a? Integer
end
Any idea why it doesn't work?
Math, which is constant holding module designed for mathematic operations.Math.sqrt(9) also returns float, so this isn't gonna work either. But you can check the remainder of division by 1. To summarize, I would do something like this:
def is_square?(x)
(Math.sqrt(x) % 1).zero?
end
The result is aways a float:
Math.sqrt(4)
# => 2.0
Math.sqrt(4).class
# => Float
You need to check if the result is a number without decimal points:
def is_square(x)
Math.sqrt(x) % 1 == 0
end
First, you need to capitalise math to Math.
The other problem with this code is the return value of Math.sqrt. Suppose you supply 4 as the value of x. Math.sqrt always returns a Float (a decimal), even if that Float happens to be a round number, so the result would be 2.0. As far as Ruby is concerned, and most programming languages for that matter, 2.0 isn't an Integer. It's still a Float, just one which doesn't have any decimal portion.
The easiest way to check if a Float is an integer is to mod it by 1 (that is, divide it by 1 and get the remainder), which may be done using %, and then check that this remainder is 0.
def is_square(x)
return true if Math.sqrt(x) % 1 == 0
end
This function still isn't perfect though; it returns true for a square and nil for a non-square. It'd make more sense for it to return false for a non-square instead.
This can be done by removing the if, and simply returning the result of the conditional. Also, return in Ruby isn't required for the last statement of a block.
def is_square(x)
Math.sqrt(x) % 1 == 0
end
The result of Math#sqrt will never be an integer type, even for perfect squares. In general, type checks are not very helpful in Ruby.
Instead, there are a couple strategies you can use to determine if a number is integer in Ruby.
x == x.to_int
x.denominator == 1
x % 1 == 0
As an aside, idiomatic Ruby also doesn't use prefixes like is_, but instead adds a suffix question mark to predicate methods:
def perfect_square?(x)
# Implementation
end