--------------------------------------- -- Dyadic numerals (after Smullyan) -- Fritz, Nov 08 (rev. unfoldl 2019) --------------------------------------- module Dyadic where import Char -------------------- -- "raw" definition of Smullyan's dyadics -- call "dyad n" to get the dyadic version; -- "did" should be the identity on Nats via dyadics dy 0 = "" dy n = if odd n then d (n-1) ++ "1" else d (n-2) ++ "2" where d = dy . (`div` 2) dyad n = "|" ++ dy n ++"|" did = unbase 2 . dy -------------------- -- standard Horner conversions using foldl & unfoldl sumProd b a c = b * a + c unfoldl p f s = g s [] where g s a = if p s then a else g t (h:a) where (t,h) = f s unbase b = foldl (sumProd b) 0 . map digitToInt base b = map intToDigit . unfoldl (==0) (`divMod` b) -------------------- -- for dyadics, we shift "mod" to "mad" -- (see Teen Titans villain :) ) -- now "dase" is like "base" mad n k = if m == 0 then k else m where m = n `mod` k divMad n k = ((n-m) `div` k, m) where m = n `mad` k dase b = map intToDigit . unfoldl (==0) (`divMad` b) -------------------- -- testing threes = ["", "1", "2", "3", "11", "12", "13", "21", "22", "23", "31"] dump b j k = mapM_ (putStrLn . fmt) [j..k] where fmt n = "\t" ++ base b n ++ "\t\t" ++ dase b n