I want to convert an integer to a perfect square by multiplying it by some number. That number is the product of all the prime factors of the number which not appear an even number of times. Example 12 = 2 x 2 x 3; 2 appears twice (even number of times) but 3 just once (odd number of times), so the number I need to multiply 12 by to get a perfect square is 3. And in fact 12 x 3 = 36 = 6 * 6.
I converted my code to Haskell and would like to know what suggestions you have.
import Data.List (group)
toPerfectSquare :: Int -> Int
toPerfectSquare n = product . map (\(x:_) -> x) . filter (not . even . length) . group $ primefactors n
primefactors :: Int -> [Int]
primefactors n = prmfctrs' n 2 [3,5..]
where
prmfctrs' m d ds | m < 2 = [1]
| m < d^2 = [m]
| r == 0 = d : prmfctrs' q d ds
| otherwise = prmfctrs' m (head ds) (tail ds)
where (q, r) = quotRem m d
Sorry about the naming, I'm bad at giving names.
One particular doubt I have is in the use of $
in toPerfectSquare
, that I first used .
but it didn't work and I needed to use parenthesis. Why? And is it usual to have that many compositions in one line?