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