Skip to content

Instantly share code, notes, and snippets.

@nrdmn
Last active September 15, 2019 13:17
Show Gist options
  • Save nrdmn/1690386959b6318109d9bedc8eeca936 to your computer and use it in GitHub Desktop.
Save nrdmn/1690386959b6318109d9bedc8eeca936 to your computer and use it in GitHub Desktop.
import System.Environment (getArgs)
import System.IO (hPutStrLn, stderr)
import Data.List (genericTake)
import Text.Read (readMaybe)
-- sqrt possibly inaccurate for large primes.
primes = 2 : [ n | n<-[3,5..], all (\x -> n `mod` x /= 0) $ takeWhile (<= (floor $ sqrt $ fromIntegral n)) primes]
-- guaranteed to be correct for all primes, but much slower:
-- primes = 2 : [ n | n<-[3,5..], all (\x -> n `mod` x /= 0) $ takeWhile (<= (quot n 2)) primes]
-- for all n out of [1..] there's a prime p so that n < p < 2*n (Bertrand's postulate)
main = do
args <- getArgs
let output = case args of
[] -> Just primes
[a] | Just n <- readMaybe a, n >= 0 -> Just $ genericTake n primes
_ -> Nothing
case output of
Just o -> putStr $ unlines $ show <$> o
Nothing -> hPutStrLn stderr "wrong usage"
@nrdmn
Copy link
Author

nrdmn commented Sep 15, 2019

import qualified Data.Map as M

factor n = factor_ M.empty (takeWhile (<= n) primes) n
    where factor_ acc _ 1 = acc
          factor_ acc (p:ps) n
              | n `rem` p == 0 = factor_ (M.insertWith (+) p 1 acc) (p:ps) (n `div` p)
              | otherwise      = factor_ acc ps n

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment