Contando en la arena
El problema de ayer de ¡Acepta el reto! fue Contando en la arena cuyo enunciado es el siguiente:
Es ampliamente conocido que escribimos los números utilizando base 10, en la que expresamos las cantidades utilizando 10 dígitos distintos (0…9). El valor de cada uno de ellos depende de la posición que ocupe dentro del número, pues cada dígito se multiplica por una potencia de 10 distinta según cuál sea esa posición.
La descomposición, por ejemplo, del número 1.234 es: 1.234 = 1×10^3 + 2×10^2 + 3×10^1 + 4×10^0
Otra base muy conocida es la base 2 al ser la utilizada por los dispositivos electrónicos. En ella sólo hay dos dígitos distintos (0 y 1), que se ven multiplicados por potencias de 2.
Mucho antes de que llegaran la base 2, la base 10 e incluso los números romanos, los primeros seres humanos contaban haciendo surcos en la arena, muescas en un trozo de madera o colocando palos en línea. Estaban, sin saberlo, usando base 1. En ella sólo hay un símbolo y cada dígito es multiplicado por una potencia de 1. Dado que 1^n = 1 el resultado es que todos los dígitos tienen el mismo peso.
Definir la función
1 |
transformaAbase1 :: FilePath -> FilePath -> IO () |
tal que al evaluar (transformaAbase1 f1 f2) lee el contenido del fichero f1 (que estará compuesto por distintos números mayores que 0, cada uno en una línea) y escribe en el fichero f2 una línea con la representación en base 1 de cada uno de los números de f1 excepto el 0 final. Por ejemplo, si el contenido de «Entrada.txt» es
1 2 3 4 |
1 4 6 0 |
al evaluar (transformaAbase1 «Entrada.txt» «Salida.txt») el contenido de «Salida.txt» debe de ser
1 2 3 |
1 1111 111111 |
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
transformaAbase1 :: FilePath -> FilePath -> IO () transformaAbase1 f1 f2 = do cs <- readFile f1 writeFile f2 (transformaAbase1Aux cs) -- (transformaAbase1Aux cs) es la cadena obtenida transformando a base 1 -- cada uno de los números de cs. Por ejemplo, -- λ> transformaAbase1Aux "1\n4\n6\n0\n" -- "1\n1111\n111111\n" transformaAbase1Aux :: String -> String transformaAbase1Aux cs = unlines (map (show . enBase1) (numeros cs)) -- (numeros cs) es la lista de los números de cs, excepto el último. Por -- ejemplo, -- numeros "1\n4\n6\n0\n" == [1,4,6] numeros :: String -> [Integer] numeros cs = init (map read (lines cs)) -- (enBsase1 x) es la representación de x en base 1. Por ejemplo, -- enBase1 4 == 1111 enBase1 :: Integer -> Integer enBase1 x = (10^x - 1) `div` 9 |
5 Comentarios