<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Exchange Server">
<!-- converted from text --><style><!-- .EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; } --></style>
</head>
<body>
<div class="PlainText">Muito obrigado pelo retorno, e principalmente aos pontos levantados... hoje de noite vou fazer alterações com base na suas dicas!<br>
<br>
--- Mensagem Original ---<br>
<br>
De: "Álvaro Pereira" <alvaro.bruno@gmail.com><br>
Enviado: 6 de janeiro de 2015 04:10<br>
Para: haskell-br@haskell.org<br>
Assunto: Re: [haskell-br] HackerRank<br>
<br>
</div>
<div>
<div dir="ltr">Pro Jean, que tava pedindo umas dicas... tô aprendendo haskell ainda, mas deixa eu tentar ajudar no que consigo no código haeuhea, vamo lá:<br>
<br>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<pre>import Data.Char
import Control.Monad

intDigits :: Integer -> [Int]
intDigits n = map (\x -> read [x] :: Int) (show n)<br></pre>
</blockquote>
<div>Aqui o " :: Int " é desnecessário, porque como você declarou o tipo da função (que retorna [Int]), a linguagem já se vira sozinha.<br>
</div>
<div>Além disso, o haskell tem o currying pronto, então "map (\x -> read [x])" já é uma função (que "tá faltando" receber o último argumento), então dá pra você compor ela com o show. Podendo escrever só assim:<br>
<br>
</div>
<div>intDigits = map (\x -> read [x]) . show<br>
<br>
</div>
<div>(daí nem precisa do n)<br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<pre>charDigits :: [Int] -> [Char]
charDigits = map (\x -> intToDigit x)

digits :: Integer -> [Char]
digits = charDigits . intDigits</pre>
</blockquote>
<div>[Char] e String são as mesmas coisas, você tá convertendo um int pra uma lista com os digitos e passando eles pra char, mas não tinha necessidade (isso é a mesma coisa que dar show já).<br>
</div>
<div>Tipo, se você fizer:<br>
<br>
</div>
<div>digits = show<br>
<br>
</div>
<div>O código continua fazendo a mesma coisa :P<br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<pre>
divide :: Integer -> Char -> Bool
divide _ '0' = False
divide n c = isMultiple
    where digit = toInteger $ digitToInt c
          nModDigit = n `mod` digit
          isMultiple = nModDigit == 0 <br></pre>
</blockquote>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<pre>
findDigit :: Integer -> Int
findDigit n = foldl (\a b -> a + (if div b then 1 else 0)) 0 list
    where div = divide n
          list = digits n

getStrings :: Integer -> [IO String]
getStrings n
    | n <= 0 = []
    | otherwise = getLine : getStrings (n - 1)</pre>
</blockquote>
<div>Aqui acho q era mais negócio c usar pattern matching do que as guards (que nem fez embaixo), mas só pq fica menor/mais bonitim msm<br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<pre>
getIntegers :: [String] -> [Integer]
getIntegers [] = []
getIntegers (x:xs) = readInteger x : getIntegers xs</pre>
</blockquote>
<div> </div>
<div>Aqui c podia fazer algo como: getIntegers = map read<br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<pre>
readInteger :: String -> Integer
readInteger = read</pre>
</blockquote>
<div>Aqui, c só deu outro nome pro "read".<br>
Se a intenção foi forçar o tipo, é mei bobera, no sentido que se na outra função que c vai usar ela (a getIntegers por exemplo) já tem o tipo declarado,<br>
</div>
<div>a linguagem já vai converter pro tipo certo com o read. <br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<pre>
main = do
    qtd <- getLine
    valStr <- sequence $ getStrings (readInteger qtd)
    let valores = getIntegers valStr
        digitsFound = map (findDigit) valores
    mapM (print) digitsFound</pre>
</blockquote>
<div><br>
</div>
<div>E no geral c tá usando Integer, sendo que no problema não estouraria o Int, daí não tem pq usar. (Integer é mais pesadinho).<br>
</div>
<div>Dá uma olhada depois em coisas como forever, getContents e interact, que ajuda em muitos casos na I/O.<br>
<br>
</div>
<div>Vô botar meu código aqui pro mesmo problema, talvez c tira algumas ideias tb:<br>
<br>
main = do<br>
  _ <- getLine<br>
  interact $ unlines . map (show . solve) . lines<br>
<br>
solve ::  String -> Int<br>
solve line =<br>
  let n = read line<br>
  in countDiv n $ digits n<br>
<br>
digits :: Int -> [Int]<br>
digits = map (\x -> read [x]) . show<br>
<br>
divides :: Int -> Int -> Bool<br>
divides _ 0 = False<br>
divides n d = (n `mod` d == 0)<br>
<br>
countDiv :: Int -> [Int] -> Int<br>
countDiv n nums = <br>
  let divisors = filter (divides n) nums<br>
  in length divisors<br>
<br>
</div>
<div>(Se alguém tiver algumas dicas pra dar em cima dele, é bem vindo tb :D)<br>
</div>
</div>
</div>
</body>
</html>