Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell function to test if Int is perfect square using infinite list

Tags:

haskell

Purely for pleasure, and practice, I am trying to write a simple Haskell function to determine if an integer is a perfect square. Now I know that there are other solutions out there but I am wondering if there is a way to do it with an infinite list. I've started with this, but for clear reasons, it is not working (it never stops!)

    isSquare :: Integer -> Bool
    isSquare n = sum[ 1 | x <- [1..], x*x == n] /= 0

Also, if I might add, can someone point out how to search an infinite list for the first instance of something and then STOP! ?

like image 575
CodyBugstein Avatar asked Apr 26 '13 04:04

CodyBugstein


People also ask

How do you check if a number is a perfect square Haskell?

There's a very simple way to test for a perfect square - quite literally, you check if the square root of the number has anything other than zero in the fractional part of it.

How do you check if an integer is a perfect square?

All perfect squares end in 1, 4, 5, 6, 9 or 00 (i.e. Even number of zeros). Therefore, a number that ends in 2, 3, 7 or 8 is not a perfect square.

How do you quickly tell if a number is a perfect square?

To check the perfectness of your square, you can simply calculate the square root of a given number. If the square root is an integer, your number is the perfect square. Let's calculate the squares of the following numbers: 49 and 53 . √49 = 7 - 7 is an integer → number 49 is a perfect square.

How do you know if a number is a perfect square without Squarert?

Suppose we have a number n, we have to check whether n is a perfect square number or not. A perfect square number k can be represented as k = a * a for some integer a. We have to solve this without using built-in square root function. So, if the input is like n = 121, then the output will be True because 121 = 11*11.


1 Answers

About the infinite search function:

There is already a function that searches a list for a value - elem.

If you assume the infinite list is sorted, we could write a version of elem that works on such a list. This can easily be accomplished by firstly rejecting any elements less than the search value. The first value not rejected then must be either equal to or greater than the search element. If equal - return true, else return false

infiniteElem1 :: (Ord a) => a -> [a] -> Bool
infiniteElem1 x list = (== x) $ head $ dropWhile (< x) list

Example usage:

> infiniteElem1 10 [1..]
True
> infiniteElem1 10 [1,3..]
False

There is one problem though with infiniteElem1 though: If used on a finite list, it may throw an exception if the element isn't found:

> infiniteElem1 100 [1,2,3]
*** Exception: Prelude.head: empty list

This is a reason the function head is best avoided. A better solution is this:

infiniteElem :: (Ord a) => a -> [a] -> Bool
infiniteElem x list = case dropWhile (< x) list of
  [] -> False
  (v:_) -> v == x

Now it works with a finite sorted list as well:

> infiniteElem 100 [1,2,3]
False

With this your problem becomes trivial:

let isSquare n = n `infiniteElem` [ x * x | x <- [1..]]
like image 105
David Miani Avatar answered Nov 08 '22 11:11

David Miani