sloane 2.0.0 → 2.0.1
raw patch · 8 files changed
+97/−25 lines, 8 files
Files
- README.md +17/−7
- Sloane/Config.hs +1/−1
- Sloane/DB.hs +7/−0
- Sloane/GF.hs +5/−8
- Sloane/Transform.hs +29/−0
- sloane.1 +23/−6
- sloane.cabal +1/−1
- sloane.hs +14/−2
README.md view
@@ -1,6 +1,6 @@ ----title: SLOANE(1) Sloane User Manual | Version 2.0.0-date: 2 Jan 2015+title: SLOANE(1) Sloane User Manual | Version 2.0.1+date: 7 Jan 2015 --- # NAME@@ -10,14 +10,16 @@ # SYNOPSIS -sloane [-a|--all] [-k KEYS] [-n N] [--url] [--local] [TERMS...]+sloane [-a|--all] [-k KEYS] [-n N] [--url] [--local] TERMS... -sloane [--filter] [--invert]+sloane -A NUMBER -sloane [--transform NAME] [--list-transforms]+sloane --filter [--invert] -sloane [--update] [--version] [--help]+sloane --transform NAME +sloane (--list-transforms | --update | --version | --help)+ # DESCRIPTION The `sloane` command searches Sloane's On-Line Encyclopedia of Integer@@ -71,6 +73,10 @@ --local : Grep for a sequence in the local database. +-A *NUMBER*+: Fetch the sequence with this number from the local database. Prints+ the sequence, but nothing else, to sdout.+ --filter : Read sequences from stdin and return those that are in the local database.@@ -124,7 +130,11 @@ firefox `sloane --url -n 3 "(2+2)-free posets"` -In the final example the local cache is used to filter out sequences+To retrieve sequence A022493 from the local database use the `-A` option:++ sloane -A022493++In the final example the local database is used to filter out sequences from the standard input that are in OEIS: sloane --filter <<END
Sloane/Config.hs view
@@ -29,7 +29,7 @@ h <- getHomeDirectory let dsloane = h </> ".sloane" return Config- { nameVer = "sloane 2.0.0"+ { nameVer = "sloane 2.0.1" , home = h , sloaneDir = dsloane , sloaneDB = dsloane </> "sloane.db"
Sloane/DB.hs view
@@ -6,6 +6,8 @@ module Sloane.DB ( DB+ , ANumber+ , Seq , Reply , update , read@@ -14,6 +16,7 @@ , null , insert , lookup+ , lookupSeq , grep , take , aNumbers@@ -41,6 +44,7 @@ import System.Directory type ANumber = Text+type Seq = Text type Key = Char type Entry = Text type Reply = Map Key Entry@@ -101,6 +105,9 @@ lookup :: ANumber -> DB -> Maybe Reply lookup = M.lookup++lookupSeq :: ANumber -> DB -> Maybe Seq+lookupSeq anum db = lookup anum db >>= M.lookup 'S' grep :: Text -> DB -> DB grep q = M.filter $ \reply ->
Sloane/GF.hs view
@@ -87,6 +87,7 @@ nthRootApprox :: Integer -> GF -> [GF] nthRootApprox n f@(Series (1:_)) = iterateUntilFixed (nthRootNext n f) (Series [1])+nthRootApprox _ _ = error "GF has constant term different from 1" nthRootNext :: Integer -> GF -> GF -> GF nthRootNext n f g = Series (take (1 + 2*degree f) ds)@@ -106,6 +107,7 @@ nthRoot1 n f@(Series (1:_)) = let css = transpose (map coeffs (nthRootApprox n f)) in Series $ map fromJust (takeWhile isJust (map saddlePoint css))+nthRoot1 _ _ = error "GF has constant term different from 1" nthRoot :: Integer -> GF -> GF nthRoot _ (Series []) = Series []@@ -116,19 +118,14 @@ (^^^) :: GF -> Rational -> GF (^^^) f r = case (numerator r, denominator r) of (n, 1) -> f ^^ n- (0, _) -> ogf [1]+ (0, _) -> ogf [1::Int] (n, k) -> nthRoot k f ^^ n --- XXX: Seems correct, but isn't producing anything--- nthRoot :: Integer -> GF -> GF--- nthRoot n f = sum [ (f-1)^k * fromRational (bin n k) | k<-[0..]]--- where--- -- bin n k = {1/n choose k}--- bin n k = product [(1-i*n+n) % i | i<-[1..k] ] / (n%1)^k-+-- XXX: Deprecate and use (^^^(1%2)) instead? squareRoot :: GF -> GF squareRoot = Series . map toRational . squareRoot' . map fromRational . coeffs +-- XXX: Deprecate? squareRoot' :: [Double] -> [Double] squareRoot' [] = [] squareRoot' (c:ct) = ds
Sloane/Transform.hs view
@@ -19,6 +19,8 @@ , tCONVi , tEXPCONV , tDIFF+ , tMOBIUS+ , tMOBIUSi , tEULER , tEXP , tLOG@@ -159,6 +161,31 @@ tDIFF :: NamedTransform tDIFF = NT "DIFF" (\cs -> zipWith (-) (drop 1 cs) cs) +-- The Mobius function of the poset of integers under divisibility+mobius :: Integer -> Integer -> Integer+mobius a b+ | a == b = 1+ | b `rem` a == 0 = -sum [ mobius a c | c <- [a..b-1], b `rem` c == 0 ]+ | otherwise = 0++-- The number theoretical Mobius function+mu :: Integer -> Integer+mu = mobius 1++tMOBIUS :: NamedTransform+tMOBIUS = NT "MOBIUS" $ \cs ->+ [ sum [mu (n `div` k) % 1 * (cs !! (fromInteger k-1))+ | k<-[1..n], n `rem` k == 0+ ]+ | (n,_) <- zip [1..] cs+ ]++tMOBIUSi :: NamedTransform+tMOBIUSi = NT "MOBIUSi" $ \cs ->+ [ sum [ (cs !! (fromInteger k-1)) | k<-[1..n], n `rem` k == 0 ]+ | (n,_) <- zip [1..] cs+ ]+ tEULER :: NamedTransform tEULER = NT "EULER" (\cs -> let f = product $ zipWith (\n c -> (1 - x^n)^^^c) [1::Int ..] cs@@ -238,6 +265,8 @@ , tCONVi , tEXPCONV , tDIFF+ , tMOBIUS+ , tMOBIUSi , tEULER -- , tEULERi , tEXP
sloane.1 view
@@ -1,17 +1,19 @@-.TH "SLOANE" "1" "2 Jan 2015" "Sloane User Manual" "Version 2.0.0"+.TH "SLOANE" "1" "7 Jan 2015" "Sloane User Manual" "Version 2.0.1" .SH NAME .PP sloane \- a command line interface to Sloane\[aq]s On\-Line Encyclopedia of Integer Sequences <http://oeis.org> .SH SYNOPSIS .PP-sloane [\-a|\-\-all] [\-k KEYS] [\-n N] [\-\-url] [\-\-local] [TERMS...]+sloane [\-a|\-\-all] [\-k KEYS] [\-n N] [\-\-url] [\-\-local] TERMS... .PP-sloane [\-\-filter] [\-\-invert]+sloane \-A NUMBER .PP-sloane [\-\-transform NAME] [\-\-list\-transforms]+sloane \-\-filter [\-\-invert] .PP-sloane [\-\-update] [\-\-version] [\-\-help]+sloane \-\-transform NAME+.PP+sloane (\-\-list\-transforms | \-\-update | \-\-version | \-\-help) .SH DESCRIPTION .PP The \f[C]sloane\f[] command searches Sloane\[aq]s On\-Line Encyclopedia@@ -95,6 +97,12 @@ .RS .RE .TP+.B \-A \f[I]NUMBER\f[]+Fetch the sequence with this number from the local database.+Prints the sequence, but nothing else, to sdout.+.RS+.RE+.TP .B \-\-filter Read sequences from stdin and return those that are in the local database.@@ -184,7 +192,16 @@ \f[] .fi .PP-In the final example the local cache is used to filter out sequences+To retrieve sequence A022493 from the local database use the+\f[C]\-A\f[] option:+.IP+.nf+\f[C]+sloane\ \-A022493+\f[]+.fi+.PP+In the final example the local database is used to filter out sequences from the standard input that are in OEIS: .IP .nf
sloane.cabal view
@@ -1,5 +1,5 @@ Name: sloane-Version: 2.0.0+Version: 2.0.1 Synopsis: A command line interface to Sloane's On-Line Encyclopedia of Integer Sequences Description: A command line interface to Sloane's On-Line Encyclopedia
sloane.hs view
@@ -5,6 +5,7 @@ -- import Data.List (intercalate)+import Data.Maybe (maybeToList) import Data.Monoid import Data.Text (Text) import qualified Data.Text as T@@ -14,12 +15,11 @@ import Network.Curl.Download (openURI) import Options.Applicative import Sloane.Config-import Sloane.DB (DB)+import Sloane.DB (DB, ANumber, Seq) import qualified Sloane.DB as DB import Sloane.Transform type URL = String-type Seq = Text data Options = Options { full :: Bool -- Print all fields?@@ -27,6 +27,7 @@ , limit :: Int -- Fetch at most this many entries , url :: Bool -- Print URLs of found entries , local :: Bool -- Lookup in local DB+ , anumber :: Int -- Get the sequence with this number from the local DB , filtr :: Bool -- Filter out sequences in local DB , invert :: Bool -- Return sequences NOT in DB , transform :: String -- Apply the named transform@@ -80,6 +81,9 @@ clean = T.filter (`elem` " 0123456789-") . T.map tr tr c = if c `elem` ";," then ' ' else c +mkANumber :: Int -> ANumber+mkANumber n = let s = show n in T.pack ('A' : replicate (6-length s) '0' ++ s)+ filterDB :: Options -> DB -> IO [Seq] filterDB opts db = filter match . parseSeqs <$> IO.getContents where@@ -111,6 +115,11 @@ <*> switch ( long "local" <> help "Use the local database rather than oeis.org" )+ <*> option auto+ ( short 'A'+ <> metavar "NUMBER"+ <> value 0+ <> help "Fetch the sequence with this number from the local database" ) <*> switch ( long "filter" <> help ("Read sequences from stdin and return"@@ -149,10 +158,13 @@ $ parserFailure pprefs pinfo ShowHelpText mempty opts <- customExecParser pprefs pinfo let tname = transform opts+ let anum = anumber opts+ let lookupSeq = maybeToList . DB.lookupSeq (mkANumber anum) let sloane | version opts = putStrLn . nameVer | update opts = DB.update | listTransforms opts = const $ mapM_ (putStrLn . name) transforms+ | anum > 0 = \c -> lookupSeq <$> DB.read c >>= mapM_ IO.putStrLn | filtr opts = \c -> DB.read c >>= filterDB opts >>= mapM_ IO.putStrLn | null (terms opts) = const usage | not (null tname) = const $ applyTransform opts tname