3
\$\begingroup\$

Link to the challenge

Given an input of \$T\$ rectangles, each of various dimensions \$l \times b\$, what is the minimum number of identical perfect squares that would cover each rectangle with no overlap or excess?

Constraints

\$1 \le T \le 1000\$
\$1 \le l\$, \$b \le 1000\$

Sample Input

2
2 2
6 9

Sample Output

1
6

import System.IO (readLn, getLine)
import Control.Monad (replicateM)

main :: IO ()
main = getNumLoaves >>= getLoafDimensions >>= mapM_ (print . minNumberOfSlices)

getNumLoaves :: IO Int
getNumLoaves = readLn

parseInt :: String -> Int
parseInt = read

tuplefy :: [a] -> (a, a)
tuplefy xs = case xs of [a, b] -> (a, b)
                        _      -> error "each line of input must consist of 2 integer values."

getLoafDimensions :: Int -> IO [(Int, Int)]
getLoafDimensions =
  let rawText         = flip replicateM getLine
      parseDimensions = map $ tuplefy . map parseInt . words
  in fmap parseDimensions . rawText

squares :: [Int]
squares = map (^2) [1..1000]

squareRoot :: Int-> Int
squareRoot squaredNum = floor . sqrt $ fromIntegral squaredNum

minNumberOfSlices :: (Int, Int) -> Int
minNumberOfSlices (l, b) =
  let area                        = l * b
      isPerfectSliceDimension num = area `rem` num + b `rem` squareRoot num + l `rem` squareRoot num == 0
      largestSquare               = last $ filter isPerfectSliceDimension $ take (min l b) squares
  in if l == b
     then 1
     else area `div` largestSquare
\$\endgroup\$
1
\$\begingroup\$
getNumLoaves :: IO Int
getNumLoaves = readLn

parseInt :: String -> Int
parseInt = read 

Theses functions are useless. It's useful when you're writing the code and it's not done yet, but Haskell can actually deduce the types based on what the other functions parameters type, like getLoafDimensions need an int, so readLn must return an int, otherwise it wouldn't compile

Your tuplefy function can be simplified by removing the case of, which is basically the same as this form of pattern matching

tuplefy :: [a] -> (a, a)
tuplefy [a, b] = (a, b)
tuplefy _      = error "each line of input must consist of 2 integer values."

By the way, the error message is wrong, because that function can accept a list of any type

Both readLn and getLine are defined in the prelude, so you don't need to import them, so you don't need to import System.IO

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.