tres suma promedio numeros numero multiplos mayor listas ejercicios ejemplos divisores ciclos haskell

suma - Divide un número en sus dígitos con Haskell



promedio en haskell (14)

¿Has oído hablar de div y mod ?

Probablemente quiera revertir la lista de números si quiere tratar primero el dígito más significativo. Convertir el número en una cadena es una forma alterada de hacer las cosas.

135 `div` 10 = 13 135 `mod` 10 = 5

Generalizar en una función:

digs :: Integral x => x -> [x] digs 0 = [] digs x = digs (x `div` 10) ++ [x `mod` 10]

O a la inversa

digs :: Integral x => x -> [x] digs 0 = [] digs x = x `mod` 10 : digs (x `div` 10)

Esto trata a 0 como sin dígitos. Una función de envoltura simple puede ocuparse de ese caso especial si así lo desea.

Tenga en cuenta que esta solución no funciona para números negativos (la entrada x debe ser integral, es decir, un número entero).

Dado un número arbitrario, ¿cómo puedo procesar cada dígito del número individualmente?

Editar He añadido un ejemplo básico del tipo de cosas que Foo podría hacer.

Por ejemplo, en C # podría hacer algo como esto:

static void Main(string[] args) { int number = 1234567890; string numberAsString = number.ToString(); foreach(char x in numberAsString) { string y = x.ToString(); int z = int.Parse(y); Foo(z); } } void Foo(int n) { Console.WriteLine(n*n); }


A través de la lista de comprensión:

import Data.Char digits :: Integer -> [Integer] digits n = [toInteger (digitToInt x) | x <- show n]

salida:

> digits 1234567890 [1,2,3,4,5,6,7,8,9,0]


Aquí hay una mejora en una respuesta anterior. Esto evita el 0 adicional al comienzo (Ejemplos: [0,1,0] para 10, [0,1] para 1). Use la coincidencia de patrones para manejar casos donde x <10 de forma diferente:

toDigits :: Integer -> [Integer] -- 12 -> [1,2], 0 -> [0], 10 -> [1,0] toDigits x | x < 10 = [x] | otherwise = toDigits (div x 10) ++ [mod x 10]

Hubiera dicho esto en respuesta a esa respuesta, pero no tengo los puntos de reputación necesarios :(


El libro de texto se desarrolla

import qualified Data.List as L digits = reverse . L.unfoldr (/x -> if x == 0 then Nothing else Just (mod x 10, div x 10))


La respuesta aceptada es correcta, excepto que arrojará una lista vacía cuando la entrada sea 0, sin embargo, creo que la salida debería ser [0] cuando la entrada es cero.

Y no creo que tenga que ver con el caso cuando la entrada es negativa. Debajo está mi implementación, que resuelve los dos problemas anteriores.

toDigits :: Integer -> [Integer] toDigits n | n >=0 && n < 10 = [n] | n >= 10 = toDigits (n`div`10) ++ [n`mod`10] | otherwise = error "make sure your input is greater than 0"


La respuesta aceptada es excelente, pero falla en los casos de números negativos, ya que mod (-1) 10 evalúa como 9. Si desea que maneje correctamente los números negativos ... lo que puede no ser el caso, el siguiente código lo permitirá.

digs :: Int -> [Int] digs 0 = [] digs x | x < 0 = digs ((-1) * x) | x > 0 = digs (div x 10) ++ [mod x 10]


Para devolver una lista de [Entero]

import Data.Char toDigits :: Integer -> [Integer] toDigits n = map (/x -> toInteger (digitToInt x)) (show n)


Puedes usar

digits = map (`mod` 10) . reverse . takeWhile (> 0) . iterate (`div` 10)

o por orden inverso

rev_digits = map (`mod` 10) . takeWhile (> 0) . iterate (`div` 10)

La parte de iteración genera una lista infinita que divide el argumento en cada paso por 10, por lo que 12345 se convierte en [12345,1234,123,12,1,0,0 ..]. La parte takeWhile solo toma la interesante parte no nula de la lista. Luego invertimos (si queremos) y tomamos el último dígito de cada número de la lista.

Utilicé el estilo sin puntos aquí, así que puedes imaginar un argumento invisible n en ambos lados de la "ecuación". Sin embargo, si quieres escribirlo de esa manera, debes sustituir el nivel superior . por $ :

digits n = map(`mod` 10) $ reverse $ takeWhile (> 0) $ iterate (`div`10) n


También podría simplemente reutilizar digits de Hackage.


Traté de seguir usando la recursividad de cola

toDigits :: Integer -> [Integer] toDigits x = reverse $ toDigitsRev x toDigitsRev :: Integer -> [Integer] toDigitsRev x | x <= 0 = [] | otherwise = x `rem` 10 : toDigitsRev (x `quot` 10)


Usando la misma técnica utilizada en su publicación, puede hacer:

digits :: Integer -> [Int] digits n = map (/x -> read [x] :: Int) (show n)

Véalo en acción:

Prelude> digits 123 [1,2,3]

¿Eso ayuda?


Applicative . Pointfree . Origami . Ordenado.

Disfrutar:

import Data.List import Data.Tuple import Data.Bool import Control.Applicative digits = unfoldr $ liftA2 (bool Nothing) (Just . swap . (`divMod` 10)) (> 0)


digits :: Integer -> [Int] digits = map (read . (:[])) . show

o puede devolverlo a [] :

digits :: Integer -> [Int] digits = map (read . return) . show

o, con Data.Char.digitToInt:

digits :: Integer -> [Int] digits = map digitToInt . show

lo mismo que Daniel es realmente, pero no tiene sentido y usa Int, porque un dígito no debería exceder maxBound :: Int .


digits = reverse . unfoldr go where go = uncurry (*>) . (&&&) (guard . (>0)) (Just . swap . (`quotRem` 10))