-- | -- TerntUp -- offers terntUp/terntDown functions for printing/parsing between Integers and balanced ternary string representations module TerntUp where -- | Determine the appropriate balanced ternary digit and carry value for a decimal digit tUp :: Integer -> (Char, Integer) tUp 0 = ('0', 0) tUp 1 = ('1', 0) tUp 2 = ('T', 1) -- | Print an Integer to a balanced ternary string representation terntUp :: Integer -> String terntUp 0 = "0" terntUp n = terntUp' n "" where terntUp' :: Integer -> String -> String terntUp' 0 digits = digits terntUp' n digits = terntUp' (quo + carry) (t:digits) where (quo, rem) = n `divMod` 3 (t, carry) = tUp rem -- | Determine the appropriate decimal digit value for a balanced ternary digit (in several styles) tDown :: Char -> Integer tDown '0' = 0 tDown '1' = 1 tDown '+' = 1 tDown 'T' = -1 tDown 't' = -1 tDown '-' = -1 tDown d = error ("Parse error for digit " ++ [d]) -- | Parse a balanced ternary string representation to an Integer terntDown :: String -> Integer terntDown digits = terntDown' (reverse digits) 0 0 where terntDown' :: String -> Integer -> Integer -> Integer terntDown' "" subtotal _ = subtotal terntDown' (d:ds) subtotal exp = terntDown' ds (subtotal + tDown d * 3 ^ exp) (exp + 1)