Last active
March 2, 2018 06:24
-
-
Save DataKinds/00db630cba142d481f474fcba8b86c4a to your computer and use it in GitHub Desktop.
Interface to the C-L Prime Construction of the Naturals
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module CLN where | |
import Data.List | |
data CLNElem = Dot | Parens [CLNElem] | |
instance (Show CLNElem) where | |
show Dot = "." | |
show (Parens clnes) = "(" ++ (concatMap show clnes) ++ ")" | |
newtype CLN = CLN [CLNElem] | |
instance (Show CLN) where | |
show (CLN clnes) = "CLN " ++ (concatMap show clnes) | |
isPrime :: Integer -> Bool | |
isPrime n = not $ any (== 0) [n `mod` x | x <- [2 .. (floor $ sqrt floatN)]] | |
where | |
floatN = fromIntegral n :: Double | |
primes :: [Integer] | |
primes = filter isPrime [1..] | |
whichPrime :: Integer -> Integer | |
whichPrime n = (fromIntegral . length) $ takeWhile (< n) primes | |
nthPrime :: Integer -> Integer | |
nthPrime n = primes !! (fromIntegral n) | |
firstDivisors :: Integer -> [Integer] | |
firstDivisors n = [fD1, fD2] | |
where | |
fD1 = head $ filter (\fD -> n `mod` fD == 0) [2..] | |
fD2 = n `div` fD1 | |
iterateDivisors :: [Integer] -> [Integer] | |
iterateDivisors ns = concatMap divideIf ns | |
where | |
divideIf x = if (isPrime x) then [x] else (firstDivisors x) | |
primeDivisors :: Integer -> [Integer] | |
primeDivisors n = fix $ iterate iterateDivisors (firstDivisors n) | |
where | |
fix (x:xs) = if (x == (head xs)) then x else (fix xs) | |
toCLN :: Integer -> CLN | |
toCLN 1 = CLN [Dot] | |
toCLN n = CLN (toCLN' n) | |
where | |
toCLN' :: Integer -> [CLNElem] | |
toCLN' 1 = [Dot] | |
toCLN' n = case (isPrime n) of | |
True -> [Parens (toCLN' (whichPrime n))] | |
False -> concatMap toCLN' $ primeDivisors n | |
fromCLN :: CLN -> Integer | |
fromCLN (CLN ns) = foldl (*) 1 $ map fromCLN' ns | |
where | |
fromCLN' :: CLNElem -> Integer | |
fromCLN' Dot = 1 | |
fromCLN' (Parens xs) = nthPrime $ foldl (*) 1 $ map fromCLN' xs | |
instance (Monoid CLN) where | |
mempty = CLN [Dot] | |
mappend (CLN as) (CLN bs) = tNumId $ CLN $ mappend as bs | |
where | |
tNumId = toCLN . fromCLN |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example interaction: