Skip to content

Instantly share code, notes, and snippets.

@jsoffer
Created February 25, 2011 22:35
Show Gist options
  • Save jsoffer/844640 to your computer and use it in GitHub Desktop.
Save jsoffer/844640 to your computer and use it in GitHub Desktop.
-- head = LSB
decimal_a_bool :: Integer -> [Bool]
decimal_a_bool 1 = [True]
decimal_a_bool n = odd n : decimal_a_bool (div n 2)
bool_a_decimal :: [Bool] -> Integer
-- La cadena vacía no tiene representación
bool_a_decimal [] = error "Sin entrada"
bool_a_decimal s = foldl (\ x y -> if (fst y) then x + 2^(snd y) else x) 0 (zip s [0..])
por_tres :: [Bool] -> [Bool]
por_tres xs = True : ys ++ residuo where
cs = False : zipWith3 gc cs (tail xs) xs
gc b = if b then (||) else (&&)
ys = zipWith3 gy cs (tail xs ++ [False]) xs
gy p q r = (p /= q) /= r
residuo = if last cs then [True] else []
-- En realidad es "suma uno, divide por la mayor potencia de dos que sea factor"
mas_uno :: [Bool] -> [Bool]
-- Casos finales
mas_uno [] = error "mas uno: Sin datos"
mas_uno (False:xs) = error "mas_uno requiere impar"
-- unidad; 1+1=2, 2/2 = 1
mas_uno [True] = [True]
-- Fin del tren de unos
mas_uno (True:False:xs) = True:xs
-- Recorta todos los unos menos el último antes de un cero
mas_uno (True:True:xs) = mas_uno (True:xs)
serie n = mapM_ print $ map mostrar $ (++[[True]]) $ takeWhile (/=[True]) $
iterate paso $ decimal_a_bool n where
paso = (mas_uno) . (por_tres)
mostrar = map (\k -> if k then '1' else '0')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment