|
@@ -1,39 +1,47 @@
|
|
|
module Main where
|
|
|
-import Numeric (showHex)
|
|
|
+import Numeric (showIntAtBase)
|
|
|
import Data.List (isInfixOf, genericIndex)
|
|
|
import Data.List.Split(splitOn)
|
|
|
import Text.Read (readMaybe)
|
|
|
import System.IO (hFlush, stdout)
|
|
|
+import System.Environment (getArgs)
|
|
|
+import System.Exit (exitWith, ExitCode(ExitSuccess))
|
|
|
|
|
|
-hexPi :: Integer -> Char
|
|
|
+
|
|
|
+
|
|
|
+hexPi :: Integer -> Integer
|
|
|
hexPi n =
|
|
|
let
|
|
|
summation = (4 * sumPi n 1) - (2 * sumPi n 4) - (sumPi n 5) - (sumPi n 6)
|
|
|
- skimmedSum = summation - (fromIntegral (floor summation :: Integer))
|
|
|
+ skimmedSum = summation - (fromIntegral (floor summation :: Integer))
|
|
|
in
|
|
|
- showHex (floor (16 * skimmedSum) :: Integer) "" !! 0
|
|
|
+ floor (16 * skimmedSum) :: Integer
|
|
|
+
|
|
|
|
|
|
+
|
|
|
+
|
|
|
sumPi :: Integer -> Integer -> Double
|
|
|
sumPi n x =
|
|
|
let
|
|
|
summation1 = [(fromIntegral ((16^(n-k) `mod` ((8*k)+x)))) / (fromIntegral ((8*k)+x)) | k <- [0..n]]
|
|
|
-
|
|
|
summation2 = [16^^(n-k) / (fromIntegral ((8*k)+x)) | k <- [(n+1)..5000]]
|
|
|
in
|
|
|
sum $ summation1 ++ summation2
|
|
|
|
|
|
-rangePi :: Maybe Integer -> Maybe Integer -> IO ()
|
|
|
-rangePi num1 num2 = do
|
|
|
- case (num1, num2) of
|
|
|
- (Just one, Just two) ->
|
|
|
- if one >= two then
|
|
|
- putStrLn "Please give a proper range."
|
|
|
- else
|
|
|
- putStrLn $ foldr (:) [] (drop (fromIntegral one) . take (fromIntegral two) $ hexDigits)
|
|
|
- (_,_) -> putStrLn "Error: Please give an Integer (ex: 3) or a range (ex: 3..5)."
|
|
|
-
|
|
|
-prompt :: IO ()
|
|
|
-prompt = do
|
|
|
+
|
|
|
+
|
|
|
+rangePi :: (Integer -> String) -> Maybe Integer -> Maybe Integer -> String
|
|
|
+rangePi printFun (Just low) (Just high) =
|
|
|
+ if low >= high then
|
|
|
+ "Error: Please give a proper range."
|
|
|
+ else
|
|
|
+ foldr (++) [] (map printFun (drop (fromIntegral low) . take (fromIntegral high) $ hexDigits))
|
|
|
+
|
|
|
+rangePi _ _ _ = printErr
|
|
|
+
|
|
|
+
|
|
|
+prompt :: (Integer -> String) -> IO ()
|
|
|
+prompt printFun = do
|
|
|
putStr ":: "
|
|
|
hFlush stdout
|
|
|
response <- getLine
|
|
@@ -41,19 +49,50 @@ prompt = do
|
|
|
if (isInfixOf ".." response) then
|
|
|
let
|
|
|
range = splitOn ".." response
|
|
|
+ low = readMaybe $ range !! 0 :: Maybe Integer
|
|
|
+ high = readMaybe $ range !! 1 :: Maybe Integer
|
|
|
in
|
|
|
- rangePi (readMaybe $ range !! 0 :: Maybe Integer) (readMaybe $ range !! 1 :: Maybe Integer)
|
|
|
+ putStrLn $ rangePi printFun low high
|
|
|
else do
|
|
|
case (readMaybe response :: Maybe Integer) of
|
|
|
- Nothing -> putStrLn "Error: Please give an Integer (ex: 3) or a range (ex: 3..5)."
|
|
|
- Just x -> putStrLn $ hexDigits `genericIndex` x :[]
|
|
|
- prompt
|
|
|
+ Nothing -> putStrLn printErr
|
|
|
+ Just x -> putStrLn $ printFun $ hexDigits `genericIndex` x
|
|
|
+ prompt printFun
|
|
|
|
|
|
|
|
|
-hexDigits :: [Char]
|
|
|
+
|
|
|
+
|
|
|
+hexDigits :: [Integer]
|
|
|
hexDigits = [hexPi x | x <- [0..]]
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+printErr :: String
|
|
|
+printErr = "Error: Please give an Integer (ex: 3) or a range (ex: 3..5)."
|
|
|
+
|
|
|
+
|
|
|
main :: IO ()
|
|
|
main = do
|
|
|
- putStrLn "Enter a digit or range (Ctrl-C to exit)"
|
|
|
- prompt
|
|
|
+
|
|
|
+ args <- getArgs
|
|
|
+ let
|
|
|
+ printFunIO =
|
|
|
+ case args of
|
|
|
+ ["-b"] -> do
|
|
|
+ putStrLn "Outputting in binary."
|
|
|
+ return (\n -> showIntAtBase 2 (\x -> show x !! 0) n "")
|
|
|
+ ["-d"] -> do
|
|
|
+ putStrLn "Outputting in decimal."
|
|
|
+ return (\n -> show n ++ " ")
|
|
|
+ ["-h"] -> do
|
|
|
+ putStrLn "Generate hexadecimal Pi digits. Output in hexidemical by default.\n\
|
|
|
+ \\t-b\tOutput in binary.\n\
|
|
|
+ \\t-d\tOutput in decimal.\n\
|
|
|
+ \\t-h\tShow this help message."
|
|
|
+ exitWith ExitSuccess
|
|
|
+ _ -> do
|
|
|
+ putStrLn "Outputting in hex."
|
|
|
+ return (\n -> showIntAtBase 16 (\x -> show x !! 0) n "")
|
|
|
+ in do
|
|
|
+ printFun <- printFunIO
|
|
|
+ putStrLn "Enter a digit or range (Ctrl-C to exit)."
|
|
|
+ prompt printFun
|