Guest User

Untitled

a guest
May 26th, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.82 KB | None | 0 0
  1. import Data.Maybe (fromJust, catMaybes)
  2. import Data.List (subsequences, findIndex, findIndices)
  3.  
  4. import Data.Word(Word8)
  5. import qualified Data.ByteString.Lazy as BL
  6. import Data.Binary.Put
  7.  
  8. data Op = UP | DN deriving (Show, Eq)
  9.  
  10. -- Generalizaciones (limpiar; mala estructura, usar folds)
  11.  
  12. paso :: (Integral a) => (a -> a) -> a -> a
  13. paso hazpar x = if odd x then div (hazpar x) 2 else div x 2
  14.  
  15. serie_infinita :: (Integral a) => (a -> a) -> a -> [Op]
  16. serie_infinita f x = (if odd x then UP else DN) : (serie_infinita f siguiente) where
  17. siguiente = paso f x
  18.  
  19. -- Al no conocer f, no se sabe cual (si existe) es el ciclo límite.
  20. -- Hay que dar como propuesta un elemento del ciclo esperado.
  21. serie :: (Integral a) => (a -> a) -> a -> a -> [Op]
  22. serie f final x
  23. | x == final = []
  24. | otherwise = (if odd x then UP else DN) : (serie f final siguiente) where
  25. siguiente = paso f x
  26.  
  27. -- Funciones de hacer par
  28.  
  29. -- no se puede usar (-1) porque es número negativo, no función
  30. binarios :: (Integral a) => a -> a
  31. binarios = (\ k -> k - 1)
  32.  
  33. collatz :: (Integral a) => a -> a
  34. collatz = (+1).(*3)
  35. --collatz x = (3*x)+1
  36.  
  37. -- Construir el árbol de congruencias
  38.  
  39. -- [3, 5, 4, 1, 0, 2] --> [4, 3, 5, 0, 2, 1]
  40. reordena :: (Integral a) => [a] -> [Int]
  41. reordena xs = map (\k -> fromJust $ findIndex (==k) xs) [0..(fromIntegral $ length xs - 1)]
  42.  
  43. nivel :: (Integral a) => (a -> a) -> a -> [Int]
  44. nivel f n = reordena xs where
  45. xs = 0 : map (serie_a_entero.reverse.(take $ fromIntegral n).(serie_infinita f)) [1..((2^n)-1)]
  46.  
  47. torsiones :: (Integral a) => [a] -> [Int]
  48. torsiones xs = findIndices id $ alternosCon (>) xs
  49. --comp_torsiones xs = findIndices id $ alternosCon (<) xs
  50.  
  51. -- Igualdades
  52.  
  53. -- dos listas son iguales hasta donde están definidas;
  54. -- e.g. [1..10] ==: [1..20] --> True
  55.  
  56. (==:) :: (Eq a) => [a] -> [a] -> Bool
  57. (==:) x y = all id $ zipWith (==) x y
  58. infix 4 ==:
  59.  
  60. -- Igualdad izquierda: nivel y nivel siguiente
  61. igualdad1 :: (Integral a) => (a -> a) -> a -> Bool
  62. igualdad1 f n = nivel f (n+1) ==: map (2*) (nivel f n)
  63.  
  64. -- Igualdad central: el segundo cuarto del lado izquierdo y
  65. -- el primer cuarto del lado derecho
  66. igualdad2 :: (Integral a) => (a -> a) -> a -> Bool
  67. igualdad2 f n = (map (+1) izq) == der where
  68. t = nivel f n
  69. izq = take k $ drop k t
  70. der = take k $ drop j t
  71. k = 2^(n-3)
  72. j = 2^(n-1)
  73.  
  74. -- Igualdad derecha: el número de entradas iguales depende de
  75. -- cuantos niveles de separación hay
  76.  
  77. igualdad3 :: (Integral a) => (a -> a) -> a -> a -> Bool
  78. igualdad3 f n offpow = (conjuga base) == desplazado where
  79. t = nivel f n
  80. offset = 2^offpow
  81. longitud = min (if offset > 1 then 4*offset else 2) (2^(n-offset))
  82. base = idrop (2^(n-offset) - longitud) $ itake (2^(n-offset)) t
  83. desplazado = idrop (2^n - longitud) t
  84. conjuga xs = map (\k -> k + 2^offset - 1) xs
  85.  
  86. -- con 'offset' niveles de separación
  87. -- 'offset' aparentemente debe ser potencia de 2
  88. igualdad3b :: (Integral a) => (a -> a) -> a -> a -> Bool
  89. igualdad3b f n offpow = (conjuga base) ==: desplazado where
  90. offset = 2^offpow
  91. longitud = if offset > 1 then 4*offset else 2
  92. base = take (fromIntegral longitud) $ reverse $ nivel f n
  93. desplazado = take (fromIntegral longitud) $ reverse $ nivel f (n+offset)
  94. conjuga xs = map (\k -> ((k+1)*(2^offset))-1) xs
  95.  
  96. igualdad3c :: (Integral a) => (a -> a) -> a -> a -> Bool
  97. igualdad3c f n offpow = (conjuga base) == desplazado where
  98. offset = 2^offpow
  99. -- min: si el nivel base no alcanza a cubrir
  100. longitud = min (if offset > 1 then 4*offset else 2) (2^n)
  101. base = idrop (2^n - longitud) $ nivel f n
  102. desplazado = idrop (2^(n+offset) - longitud) $ nivel f (n+offset)
  103. conjuga xs = map (\k -> ((k+1)*(2^offset))-1) xs
  104.  
  105. -- Auxiliares
  106.  
  107. -- como binarios, UP es 1, DN es 0, la potencia mínima está a la izquierda (usar reverse si
  108. -- es necesario)
  109. serie_a_entero :: [Op] -> Integer
  110. serie_a_entero xs = sum $ zipWith (\ j k -> if j == UP then k else 0) xs (map (2^) [0..])
  111.  
  112. -- requiere entrada de longitud par y no nula (no verificado)
  113. alternos :: [a] -> ([a],[a])
  114. alternos (x:y:xs) = if null xs then ([x],[y]) else (x:m, y:n) where (m, n) = alternos xs
  115. --alternos [x] = ([x],[])
  116. --alternos [] = ([],[])
  117.  
  118. alternosCon :: (a->a->b) -> [a] -> [b]
  119. alternosCon f xs = zipWith f x y where
  120. (x, y) = alternos xs
  121.  
  122. dropOdd = alternosCon const
  123. dropEven = (alternosCon const).tail
  124.  
  125. separa n xs = a : (if null b then [] else separa n b) where (a,b) = splitAt n xs
  126.  
  127. itake :: (Integral a) => a -> [b] -> [b]
  128. itake n xs = take (fromIntegral n) xs
  129.  
  130. idrop :: (Integral a) => a -> [b] -> [b]
  131. idrop n xs = drop (fromIntegral n) xs
  132.  
  133. -- Escribir a archivo
  134.  
  135. -- el [Bool] debe tener longitud 8 (no verificado)
  136. a_entero :: [Bool] -> Word8
  137. a_entero xs = sum $ zipWith (\j k -> if k then j else 0) (map (2^) [7,6..0]) xs
  138.  
  139. salida :: Put
  140. salida = mapM_ putWord8 $ map a_entero $ separa 8 $ alternosCon (>) $ nivel collatz 16
  141.  
  142. {-
  143. main :: IO ()
  144. main = BL.putStr $ runPut salida
  145. -}
Add Comment
Please, Sign In to add comment