{-# LANGUAGE OverloadedLists #-} module Math.OEIS ( -- * Functions searchSeq, searchSeq', lookupSeq, lookupSeq', getSeqData, getSeqData', extendSeq, extendSeq', -- * Types SeqData, SearchStatus(..), Keyword(..), OEISSeq(..) ) where import Data.Functor import Data.List import Data.Maybe (fromMaybe, listToMaybe) import qualified Data.Vector as V import System.IO.Unsafe (unsafePerformIO) import Math.OEIS.Internal import Math.OEIS.Types -- | Get all search results on OEIS -- -- e.g. -- -- > ghci>searchSeq (ID "A000027") 0 -- > [OEIS {number = "A000027", ids = ["M0472","N0173"], seqData = [1,2,3,4,5,6,7,... -- -- > ghci>searchSeq (SubSeq [1,2,3,4]) 0 -- > [OEIS {number = "A000027", ids = ["M0472","N0173"], seqData = [1,2,3,4,5,6,7,... -- > ghci>length it -- > 53 -- > ghci>searchSeq (SubSeq [1,2,3,4]) 17 -- > [OEIS {number = "A000027", ids = ["M0472","N0173"], seqData = [1,2,3,4,5,6,7,8,9, -- > ghci>length it -- > 17 -- -- > ghci>searchSeq (SubSeq [1,1,4,5,1,4,1,9,1,9,8,9,3]) 0 -- > [] searchSeq :: SearchStatus -> Int -> V.Vector OEISSeq searchSeq ss = unsafePerformIO . searchSeq' ss -- | searchSeq in IO searchSeq' :: SearchStatus -> Int -> IO (V.Vector OEISSeq) searchSeq' ss bound = do results' <- getResults ss 0 bound [] let seqs | V.null results' = [] | otherwise = parseOEIS <$> results' return seqs -- | Look up a sequence on OEIS. -- -- e.g. -- -- > ghci>lookupSeq (ID "A000027") -- > Just (OEIS {number = "A000027", ids = ["M0472","N0173"], seqData = [1,2,3,4,5,6,7,... -- -- > ghci>lookupSeq (SubSeq [1,2,3,4]) -- > Just (OEIS {number = "A000027", ids = ["M0472","N0173"], seqData = [1,2,3,4,5,6,7,... lookupSeq :: SearchStatus -> Maybe OEISSeq lookupSeq = unsafePerformIO . lookupSeq' -- | lookupSeq in IO lookupSeq' :: SearchStatus -> IO (Maybe OEISSeq) lookupSeq' ss = do result <- getResult ss 0 return $ case result of Just result' -> Just $ parseOEIS result' _ -> Nothing -- | Get sub-sequence on OEIS. -- -- e.g. -- -- > ghci>getSeqData (ID "A000027") -- > Just [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77] -- -- > ghci>getSeqData (SubSeq [1,2,3,4]) -- > Just [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77] -- getSeqData :: SearchStatus -> Maybe SeqData getSeqData = unsafePerformIO . getSeqData' -- | getSeqData in IO getSeqData' :: SearchStatus -> IO (Maybe SeqData) getSeqData' = ((seqData <$>) <$>) . lookupSeq' -- | Extend from sub-sequence. -- -- e.g. -- -- > ghci>extendSeq [1,2,3,4] -- > [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77] -- -- > ghci> extendSeq [1,3,2,5,6,1,6] -- > [1,3,2,5,6,1,6] extendSeq :: SeqData -> SeqData extendSeq = unsafePerformIO . extendSeq' -- | extendSeq in IO extendSeq' :: [Integer] -> IO [Integer] extendSeq' [] = return [] extendSeq' sd = do oeis <- lookupSeq' (SubSeq sd) return $ case oeis of Just s -> extend sd (seqData s) _ -> sd where extend :: SeqData -> SeqData -> SeqData extend sd ext = fromMaybe sd . listToMaybe . filter (sd `isPrefixOf`) $ tails ext