Para una clase de Lisp, nos dieron una tarea simple de cifrado de transposición de fila, que también traté de resolver en Haskell. Básicamente, uno solo divide una cadena en filas de longitud n
, y luego transpone el resultado. La concatenación de la lista resultante de listas de caracteres es la cadena cifrada. La decodificación es un poco más difícil, ya que pueden faltar elementos en la última fila de entrada (columnas incompletas en el resultado), que deben tenerse en cuenta.Cifrado de transposición de fila simple
Esta es mi solución en Haskell:
import Data.List
import Data.Ratio
import Data.List.Split
encode :: String -> Int -> String
encode s n = concat . transpose $ chunk n s
decode :: String -> Int -> String
decode s n = take len $ encode s' rows
where s' = foldr (insertAt " ") s idxs
rows = ceiling (len % n)
idxs = take (n-filled) [n*rows-1,(n-1)*rows-1..]
filled = len - n * (rows - 1)
len = length s
insertAt :: [a] -> Int -> [a] -> [a]
insertAt xs i ys = pre ++ xs ++ post
where (pre,post) = splitAt i ys
Se hace el trabajo, pero no estoy seguro, si esto sería considerado idiomática Haskell, ya que mi jugando con los índices no se siente demasiado declarativa. ¿Se podría mejorar esto, y si es así, cómo?
Por cierto: ¿hay algo así como insertAt
en Haskell 98? Es decir. una función que inserta un elemento o lista en un índice dado en una lista.
Nota: Esto NO es parte de la tarea, que se cumplió hoy de todos modos.
Una pequeña observación: puede escribir 'idxs = [n * rows-1, (n-1) * rows-1 .. (filled + 1) * rows-1]'. – HaskellElephant
@HaskellElephant: Se ve mejor, gracias! – danlei