----------------------------------------------------------------------------- -- | -- -- Module : Data.Rivers.Ecology -- Copyright : (c) Drew Day 2011 -- License : BSD-style -- Maintainer : drewday@gmail.com -- Stability : experimental -- Portability : probably portable -- -- -- This module is an attempt to construct many and varied examples of "River"s and -- "Streams". At the moment, the concept of what "River"s are (or are not) is -- not entirely clear in the mind of any particular person on Earth, myself foremost -- amoung the befuddled. -- -- Primarily because I lay claim to inventing the idea, this is a worrisome situation. -- Nevertheless, whatever these things are, regular old "Data.Stream" streams (and kin) -- are subsets (or sub-classes, or.. sub-something) of these things, and hence they must -- qualify to be mapped in this ecosystem (by definition). -- -- As of now, these example originate primarily from three excellent papers on Streams -- and their properties. More precisey, they originate from my haphazard and occasionally -- mindless transcription of what I saw from these documents. Therefore, the authors of -- the following papers deserve /much of the credit/, but bear /none of the responsibility/ -- of the contents of this module. -- -- [@CONTRACTIVE@] -- -- * Graham Hutton and Mauro Jaskelioff, \"Representing contractive functions on streams\", -- -- * Submitted to the /Journal of Functional Programming/ (October 2011). -- -- * Link: -- -- * PDF: -- -- [@PEARL-UFP@] -- -- * Ralph Hinze, \"Functional pearl: streams and unique fixed points\". -- -- * /Proceedings of the 13th ACM SIGPLAN international conference on Functional Programming (ICFP '08)/ -- (22-24 September 2008). pp. 189-200. (c) ACM -- -- * Link: -- -- * PDF: -- -- [@PROVING-UFP@] -- -- * Ralf Hinze and Daniel W. H. James, \"Proving The Unique Fixed-Point Principle Correct\" -- -- * /Proceeding of the 16th ACM SIGPLAN international conference on Functional programming (ICFP '11)/ -- (September 2011). pp. 359-371. (c) ACM -- -- * Link: -- -- * PDF: -- -- -- -- This module should clearly document the behavior of /all/ functions. In fact, the -- code in this module is generally not intended to be imported and used directly. Instead -- the purpose of this module is to: -- -- 1. show *many* examples of Streams, especially non-trivial ones (ie, more complicated than 'fibionacci') -- -- 2. provide visual (and eventually, pictoral) *proof* of equality (insofar that this is possible) -- -- 3. ... more things -- -- 4. ... should go here -- -- 5. ... becuase there's a point to all of this, right? -- -- -- Note: To accomidate the documentation, the text-width of this document is 129 characters. -- -- -- As a witness to the correctness of the examples, I include the result of running doctest: -- -- > $ doctest Data/Rivers/Ecology.hs -- > Cases: 74 Tried: 74 Errors: 0 Failures: 0 -- ----------------------------------------------------------------------------- module Data.Rivers.Ecology where import Data.Rivers.Idiom import Data.Rivers.Streams -- -- -- -- -- -- -- -- -------------------------------------------------------------------------------------------------------------------------------- -- * Silly Streams -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -- ** /Constant/ Zeroes -------------------------------------------------------------------------------------------------------------------------------- sZero :: S Integer sZero = 0 <|| smerge sZero (stail sZero) -- ^ -- >>> stake 30 $ sZero -- [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] gZero :: G Integer Integer gZero [] = 0 gZero xs = xs !! ( (length xs ) `div` 2) -- ^ -- >>> stake 30 $ fwdFix gZero -- [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] rZero :: G Integer Integer rZero [] = 0 rZero xs = xs !! ( (length xs - 1) `div` 2) -- ^ -- >>> stake 30 $ revFix rZero -- [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] cZero :: S Integer cZero = cfix (cZeroH, cZeroT) ([], -1) -- ^ -- >>> stake 30 $ cZero -- [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] cZeroH :: (Num a) => ([a] , Int) -> a cZeroH ([] , _ ) = 0 cZeroH (xs , n ) = xs !! (n `div` 2) cZeroT :: (Num t) => ([a], t ) -> a -> ([a] , t ) cZeroT (xs , n ) x = (x:xs, n+1) -------------------------------------------------------------------------------------------------------------------------------- -- ** /Constant/ Ones -------------------------------------------------------------------------------------------------------------------------------- -- | -- Believe it or not, this is in OEIS: -- -- >>> take 30 $ fromOEIS "A000012" -- [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] sOne :: S Integer sOne = 1 <|| sOne -- ^ -- >>> stake 30 $ sOne -- [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] sOnes :: S Integer sOnes = 1 <|| smerge sOnes (stail sOnes) -- ^ -- >>> stake 30 $ sOnes -- [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] gOne :: G Integer Integer gOne [] = 1 gOne xs = last xs gOne' :: G Integer Integer gOne' __ = 1 -- ^ -- >>> stake 30 $ fwdFix gOne -- [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] rOne :: G Integer Integer rOne [] = 1 rOne (x:__) = x -- ^ -- >>> stake 30 $ revFix rOne -- [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] cOne :: S Integer cOne = cfix (cOneH, cOneT) 1 -- ^ -- >>> stake 30 $ cOne -- [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] cOneH :: t -> t cOneH x = x cOneT :: t -> t -> t cOneT x _ = x {-- FIXME altOnes :: S Integer altOnes = 0 <|| altOnes + 1 - carry -- ^ -- >>> stake 30 $ altOnes -- [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] --} -------------------------------------------------------------------------------------------------------------------------------- -- ** The /Natural/ Numbers -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 30 $ fromOEIS "A000027" -- [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] sNat :: S Integer sNat = 0 <|| sMap (+1) sNat -- ^ -- >>> stake 30 $ sNat -- [0,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] sNatIt :: S Integer sNatIt = siterate (+1) 0 -- ^ -- >>> stake 30 $ siterate (+1) 0 -- [0,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] natnat :: S Integer natnat = 0 <|| (2 * natnat |~| 2 * natnat + 1) + 1 -- ^ -- >>> stake 30 $ natnat -- [0,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] gNat :: G Integer Integer gNat [] = 0 gNat xs = last xs +1 gNat' :: [a] -> Int gNat' = length -- ^ -- >>> stake 30 $ fwdFix gNat -- [0,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] rNat :: G Integer Integer rNat [] = 0 rNat (x:_) = x +1 -- ^ -- >>> stake 30 $ revFix rNat -- [0,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] cNat :: S Integer cNat = cfix (cNatH, cNatT) 0 -- ^ -- >>> stake 30 $ cNat -- [0,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] cNatH :: t -> t cNatH x = x cNatT :: (Num a) => a -> t -> a cNatT x _ = x +1 -------------------------------------------------------------------------------------------------------------------------------- -- *** /Natural/ Numbers from Binary -------------------------------------------------------------------------------------------------------------------------------- bin :: S Integer bin = 0 <|| 2 * bin + 1 |~| 2 * bin + 2 -- ^ -- >>> stake 30 $ bin -- [0,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] -------------------------------------------------------------------------------------------------------------------------------- -- * Simple Streams -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -- ** Power Streams -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -- *** Powers of (-2) -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 15 $ fromOEIS "A122803" -- [1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384] revPowersOfN2 :: S Integer revPowersOfN2 = revFix a122803 -- ^ -- >>> stake 15 $ revPowersOfN2 -- [1,-2,4,-8,16,-32,64,-128,256,-512,1024,-2048,4096,-8192,16384] a122803 :: G Integer Integer a122803 [] = 1 a122803 (x:_) = -2 * x -------------------------------------------------------------------------------------------------------------------------------- -- *** Powers of (2) - Bool -------------------------------------------------------------------------------------------------------------------------------- -- Clearly, this won't be in OEIS, per se. -- -- pot :: S Bool pot = True <|| pot |~| srepeat False -- ^ -- >>> stake 15 $ pot -- [True,True,False,True,False,False,False,True,False,False,False,False,False,False,False] -------------------------------------------------------------------------------------------------------------------------------- -- *** Powers of (3) -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 15 $ fromOEIS "A000244" -- [1,3,9,27,81,243,729,2187,6561,19683,59049,177147,531441,1594323,4782969] revPowersOf3 :: S Integer revPowersOf3 = revFix pothree -- ^ -- >>> stake 15 $ revPowersOf3 -- [1,3,9,27,81,243,729,2187,6561,19683,59049,177147,531441,1594323,4782969] pothree :: G Integer Integer pothree [] = 1 pothree (x:_) = 3 * x -------------------------------------------------------------------------------------------------------------------------------- -- ** Squares -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 30 $ fromOEIS "A000290" -- [0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289,324,361,400,441,484,529,576,625,676,729,784,841] a000290 :: S Integer a000290 = bsum $ 2 * sNat + 1 -- ^ -- >>> stake 30 $ bsum $ 2 * sNat + 1 -- [0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289,324,361,400,441,484,529,576,625,676,729,784,841] -------------------------------------------------------------------------------------------------------------------------------- -- ** Factorial Numbers -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 10 $ fromOEIS "A000142" -- [1,1,2,6,24,120,720,5040,40320,362880] sFac :: S Integer sFac = 1 <|| (sNat + 1) * sFac -- ^ -- >>> stake 10 $ sFac -- [1,1,2,6,24,120,720,5040,40320,362880] -------------------------------------------------------------------------------------------------------------------------------- -- * The Family of Fibionacci (and Lucas!) -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -- ** Forever Fibionacci -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 29 $ fromOEIS "A000045" -- [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811] sFib :: S Integer sFib = 0 <|| 1 <|| sMap2 (+) sFib (stail sFib) -- ^ -- >>> stake 29 $ sFib -- [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811] sFib2 :: S Integer sFib2 = 0 <|| (1 <|| sFib2) + sFib2 -- ^ -- >>> stake 29 $ sFib2 -- [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811] revGfibs :: G Integer Integer revGfibs [] = 0 revGfibs [_] = 1 revGfibs (x:y:_) = y + x -- ^ -- >>> stake 29 $ revFix revGfibs -- [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811] cFib :: S Integer cFib = cfix (cFibH, cFibT) (0,1) cFibH :: (a,b) -> a cFibH (x,_) = x cFibT :: (Num a) => (a, a) -> a -> (a, a) cFibT (x,y) ____ = (y, x+y) -- ^ -- >>> stake 29 $ cFib -- [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811] gFibs :: G Integer Integer gFibs xs = case length xs of 0 -> 0 1 -> 1 n -> xs !! (n-2) + xs !! (n-1) -- ^ -- >>> stake 29 $ fwdFix gFibs -- [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811] -------------------------------------------------------------------------------------------------------------------------------- -- ** Lonely Lucas -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 28 $ fromOEIS "A000032" -- [2,1,3,4,7,11,18,29,47,76,123,199,322,521,843,1364,2207,3571,5778,9349,15127,24476,39603,64079,103682,167761,271443,439204] sLucas :: S Integer sLucas = 2 <|| 1 <|| sMap2 (+) sLucas (stail sLucas) -- ^ -- >>> stake 28 $ sLucas -- [2,1,3,4,7,11,18,29,47,76,123,199,322,521,843,1364,2207,3571,5778,9349,15127,24476,39603,64079,103682,167761,271443,439204] rLucas :: G Integer Integer rLucas [] = 2 rLucas [_] = 1 rLucas (x:y:_) = x + y -- ^ -- >>> stake 28 $ revFix rLucas -- [2,1,3,4,7,11,18,29,47,76,123,199,322,521,843,1364,2207,3571,5778,9349,15127,24476,39603,64079,103682,167761,271443,439204] -------------------------------------------------------------------------------------------------------------------------------- -- *** under (4*n + 1) -------------------------------------------------------------------------------------------------------------------------------- -- | The Fibionacci (4n + 1) and Lucas (4n + 1) numbers -- -- drop0L is evidently a bisect twice function -- fib4np1 :: S Integer fib4np1 = drop0L sFib -- ^ -- >>> stake 10 $ drop0L sFib -- [1,5,34,233,1597,10946,75025,514229,3524578,24157817] -- -- >>> take 10 $ fromOEIS "A033889" -- [1,5,34,233,1597,10946,75025,514229,3524578,24157817] luc4np1 :: S Integer luc4np1 = drop0L sLucas -- ^ -- >>> stake 10 $ drop0L sLucas -- [1,11,76,521,3571,24476,167761,1149851,7881196,54018521] -- -- >>> take 10 $ fromOEIS "A056914" -- [1,11,76,521,3571,24476,167761,1149851,7881196,54018521] -------------------------------------------------------------------------------------------------------------------------------- -- *** under (2*n) -------------------------------------------------------------------------------------------------------------------------------- -- | The Fib (2*n) and Lucas (2*n) numbers -- -- dromIp1L is evidently a bisect function -- fib2n :: S Integer fib2n = dropIp1L sFib -- ^ -- >>> stake 20 $ dropIp1L sFib -- [0,1,3,8,21,55,144,377,987,2584,6765,17711,46368,121393,317811,832040,2178309,5702887,14930352,39088169] -- -- >>> take 20 $ fromOEIS "A001906" -- [0,1,3,8,21,55,144,377,987,2584,6765,17711,46368,121393,317811,832040,2178309,5702887,14930352,39088169] luc2n :: S Integer luc2n = dropIp1L sLucas -- ^ -- >>> stake 20 $ dropIp1L sLucas -- [2,3,7,18,47,123,322,843,2207,5778,15127,39603,103682,271443,710647,1860498,4870847,12752043,33385282,87403803] -- -- >>> take 20 $ fromOEIS "A005248" -- [2,3,7,18,47,123,322,843,2207,5778,15127,39603,103682,271443,710647,1860498,4870847,12752043,33385282,87403803] -------------------------------------------------------------------------------------------------------------------------------- -- *** under (sum) -------------------------------------------------------------------------------------------------------------------------------- fibpfib :: S Integer fibpfib = plus sFib sFib -- ^ -- >>> stake 21 $ [1] <<| plus sFib sFib -- [1,0,2,2,4,6,10,16,26,42,68,110,178,288,466,754,1220,1974,3194,5168,8362] -- -- >>> take 21 $ fromOEIS "A006355" -- [1,0,2,2,4,6,10,16,26,42,68,110,178,288,466,754,1220,1974,3194,5168,8362] -------------------------------------------------------------------------------------------------------------------------------- -- *** under (diff) -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 20 $ fromOEIS "A039834" -- [1,1,0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597] dxFib :: S Integer dxFib = diff sFib -- ^ -- >>> stake 20 $ [1] <<| diff sFib -- [1,1,0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597] -- | -- >>> take 20 $ fromOEIS "A061084" -- [1,2,1,3,4,7,11,18,29,47,76,123,199,322,521,843,1364,2207,3571,5778] dxLucas :: S Integer dxLucas = diff sLucas -- ^ -- >>> stake 20 $ diff sLucas -- [-1,2,1,3,4,7,11,18,29,47,76,123,199,322,521,843,1364,2207,3571,5778] -------------------------------------------------------------------------------------------------------------------------------- -- * Padovans and Perrins, and Pells -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -- ** Padovan -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 30 $ fromOEIS "A000931" -- [1,0,0,1,0,1,1,1,2,2,3,4,5,7,9,12,16,21,28,37,49,65,86,114,151,200,265,351,465,616] padovanPP11010 :: S Integer padovanPP11010 = [1,0,0,1,0] <<| padovan -- ^ -- >>> stake 30 $ padovanPP11010 -- [1,0,0,1,0,1,1,1,2,2,3,4,5,7,9,12,16,21,28,37,49,65,86,114,151,200,265,351,465,616] -- | -- >>> take 30 $ fromOEIS "A134816" -- [1,1,1,2,2,3,4,5,7,9,12,16,21,28,37,49,65,86,114,151,200,265,351,465,616,816,1081,1432,1897,2513] padovan :: S Integer padovan = 1 <|| 1 <|| 1 <|| sMap2 (+) padovan (stail padovan) -- ^ -- >>> stake 30 $ padovan -- [1,1,1,2,2,3,4,5,7,9,12,16,21,28,37,49,65,86,114,151,200,265,351,465,616,816,1081,1432,1897,2513] -- rpadovan :: G Integer Integer rpadovan [] = 1 rpadovan [_] = 1 rpadovan (_:_:[]) = 1 rpadovan (_:y:z:_) = y + z -- ^ -- >>> stake 30 $ revFix rpadovan -- [1,1,1,2,2,3,4,5,7,9,12,16,21,28,37,49,65,86,114,151,200,265,351,465,616,816,1081,1432,1897,2513] -- | -- >>> take 31 $ fromOEIS "A133034" -- [1,0,1,1,1,0,0,1,0,1,1,1,2,2,3,4,5,7,9,12,16,21,28,37,49,65,86,114,151,200,265] d2xpadovan :: S Integer d2xpadovan = diff $ diff $ revFix rpadovan -- ^ -- >>> stake 30 $ diff $ diff $ revFix rpadovan -- [0,1,-1,1,0,0,1,0,1,1,1,2,2,3,4,5,7,9,12,16,21,28,37,49,65,86,114,151,200,265] -------------------------------------------------------------------------------------------------------------------------------- -- ** Perrin -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 30 $ fromOEIS "A001608" -- [3,0,2,3,2,5,5,7,10,12,17,22,29,39,51,68,90,119,158,209,277,367,486,644,853,1130,1497,1983,2627,3480] perrin :: S Integer perrin = 3 <|| 0 <|| 2 <|| sMap2 (+) perrin (stail perrin) -- ^ -- >>> stake 30 $ perrin -- [3,0,2,3,2,5,5,7,10,12,17,22,29,39,51,68,90,119,158,209,277,367,486,644,853,1130,1497,1983,2627,3480] rperrin :: G Integer Integer rperrin [] = 3 rperrin [_] = 0 rperrin (_:_:[]) = 2 rperrin (_:y:z:_) = y + z -- ^ -- >>> stake 30 $ revFix rperrin -- [3,0,2,3,2,5,5,7,10,12,17,22,29,39,51,68,90,119,158,209,277,367,486,644,853,1130,1497,1983,2627,3480] -------------------------------------------------------------------------------------------------------------------------------- -- ** Pell -------------------------------------------------------------------------------------------------------------------------------- -- | -- Generating Function: -- -- z -- -------------------- -- z^2 + 2z - 1 -- -- | -- >>> take 20 $ fromOEIS "A000129" -- [0,1,2,5,12,29,70,169,408,985,2378,5741,13860,33461,80782,195025,470832,1136689,2744210,6625109] cPell :: S Integer cPell = cfix (cPellH, cPellT) (0,1) cPellH :: (a,a) -> a cPellH (x,_) = x cPellT :: (Num a) => (a, a) -> a -> (a, a) cPellT (x,y) ____ = (y, x+2*y) -- ^ -- >>> stake 20 $ cPell -- [0,1,2,5,12,29,70,169,408,985,2378,5741,13860,33461,80782,195025,470832,1136689,2744210,6625109] -- rpell :: G Integer Integer rpell [] = 0 rpell [_] = 1 rpell (x:y:_) = 2*x + y -- ^ -- >>> stake 20 $ revFix rpell -- [0,1,2,5,12,29,70,169,408,985,2378,5741,13860,33461,80782,195025,470832,1136689,2744210,6625109] -------------------------------------------------------------------------------------------------------------------------------- -- * Who invited the J's? -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -- ** Jacobsthal Sequence -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 20 $ fromOEIS "A001045" -- [0,1,1,3,5,11,21,43,85,171,341,683,1365,2731,5461,10923,21845,43691,87381,174763] jacob :: S Integer jacob= 0 <|| 1 <|| sMap2 (+) (sMap (*2) jacob) (stail jacob) -- ^ -- >>> stake 20 $ jacob -- [0,1,1,3,5,11,21,43,85,171,341,683,1365,2731,5461,10923,21845,43691,87381,174763] rjacob :: G Integer Integer rjacob [] = 0 rjacob [_] = 1 rjacob (x:y:_) = x + 2*y -- ^ -- >>> stake 20 $ revFix rjacob -- [0,1,1,3,5,11,21,43,85,171,341,683,1365,2731,5461,10923,21845,43691,87381,174763] -------------------------------------------------------------------------------------------------------------------------------- -- ** Jacobsthal-Lucas Sequence -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 20 $ fromOEIS "A014551" -- [2,1,5,7,17,31,65,127,257,511,1025,2047,4097,8191,16385,32767,65537,131071,262145,524287] jacobl :: S Integer jacobl = 2 <|| 1 <|| sMap2 (+) (sMap (*2) jacobl) (stail jacobl) -- ^ -- >>> stake 20 $ jacobl -- [2,1,5,7,17,31,65,127,257,511,1025,2047,4097,8191,16385,32767,65537,131071,262145,524287] rjacobl :: G Integer Integer rjacobl [] = 2 rjacobl [_] = 1 rjacobl (x:y:_) = x + 2*y -- ^ -- >>> stake 20 $ revFix rjacobl -- [2,1,5,7,17,31,65,127,257,511,1025,2047,4097,8191,16385,32767,65537,131071,262145,524287] -------------------------------------------------------------------------------------------------------------------------------- -- ** Josephus Numbers -------------------------------------------------------------------------------------------------------------------------------- -- GF: -- z - 2 -- -------------- -- 2z^2 + z - 1 -- CF: -- (1/2) * (2^n - 2*(-1)^n) -- | -- >>> take 30 $ drop 1 $ fromOEIS "A006257" -- [1,1,3,1,3,5,7,1,3,5,7,9,11,13,15,1,3,5,7,9,11,13,15,17,19,21,23,25,27,29] jos :: S Integer jos = 1 <|| 2 * jos - 1 |~| 2 * jos + 1 -- ^ -- >>> stake 30 $ jos -- [1,1,3,1,3,5,7,1,3,5,7,9,11,13,15,1,3,5,7,9,11,13,15,17,19,21,23,25,27,29] josAlt :: S Integer josAlt = 2 * (stail sNat - msb) + 1 -- ^ -- >>> stake 30 $ josAlt -- [1,1,3,1,3,5,7,1,3,5,7,9,11,13,15,1,3,5,7,9,11,13,15,17,19,21,23,25,27,29] -------------------------------------------------------------------------------------------------------------------------------- -- * Basically Binary (Base 2) -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -- ** Most Significant Bit -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 30 $ drop 1 $ fromOEIS "A053644" -- [1,2,2,4,4,4,4,8,8,8,8,8,8,8,8,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16] msb :: S Integer msb = 1 <|| 2 * msb |~| 2 * msb -- ^ -- >>> stake 30 $ msb -- [1,2,2,4,4,4,4,8,8,8,8,8,8,8,8,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16] -------------------------------------------------------------------------------------------------------------------------------- -- ** Thue-Morse Sequence -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 30 $ fromOEIS "A010060" -- [0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0] athue :: S Integer athue = 0 <|| interleave' (inv athue) (stail athue) -- ^ -- >>> stake 30 $ athue -- [0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0] thue :: S Integer thue = 0 <|| thue' thue' :: S Integer thue' = 1 <|| interleave thue' (inv thue') -- ^ -- >>> stake 30 $ thue -- [0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0] -------------------------------------------------------------------------------------------------------------------------------- -- ** Something with twos! -------------------------------------------------------------------------------------------------------------------------------- binlike1 :: S Integer binlike1 = 0 <|| 1 <|| smerge (sMap (* 2) binlike1) (stail binlike1) -- ^ -- >>> stake 30 $ binlike1 -- [0,1,0,1,2,0,0,1,2,2,4,0,0,0,0,1,2,2,4,2,4,4,8,0,0,0,0,0,0,0] -------------------------------------------------------------------------------------------------------------------------------- -- ** Something with twos! (2) -------------------------------------------------------------------------------------------------------------------------------- binlike2 :: S Integer binlike2 = 0 <|| 1 <|| smerge (stail binlike2) (sMap (* 2) binlike2) -- ^ -- >>> stake 30 $ binlike2 -- [0,1,1,0,1,2,0,2,1,0,2,2,0,4,2,0,1,4,0,2,2,0,2,4,0,4,4,0,2,8] -------------------------------------------------------------------------------------------------------------------------------- -- ** Who knows what this is? -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 30 $ fromOEIS "A000035" -- [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1] lsb :: S Integer lsb = bsum 0 |~| 1 -- ^ -- >>> stake 30 $ bsum 0 |~| 1 -- [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1] -------------------------------------------------------------------------------------------------------------------------------- -- ** Binary Sum Carry -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 30 $ fromOEIS "A011371" -- [0,0,1,1,3,3,4,4,7,7,8,8,10,10,11,11,15,15,16,16,18,18,19,19,22,22,23,23,25,25] sumcarry :: S Integer sumcarry = bsum carry -- ^ -- >>> stake 30 $ sumcarry -- [0,0,1,1,3,3,4,4,7,7,8,8,10,10,11,11,15,15,16,16,18,18,19,19,22,22,23,23,25,25] -------------------------------------------------------------------------------------------------------------------------------- -- * Fractals -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -- ** Apollonian Fractal -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -- *** D2: (-1,2,2,3) -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 20 $ fromOEIS "A060790" -- [1,2,2,3,15,38,110,323,927,2682,7754,22403,64751,187134,540822,1563011,4517183,13054898,37729362,109039875] apolloD2 :: (Floating a) => [a] -> a apolloD2 [] = 2 apolloD2 [_] = 2 apolloD2 (_:_:[]) = 3 apolloD2 (x:y:z:_) = (x + y + z) + 2*sqrt(x*y + y*z + z*x) -- ^ -- >>> stake 20 $ revFix apolloD2 -- [2.0,2.0,3.0,15.0,38.0,110.0,323.0,927.0,2682.0,7754.0,22403.0,64751.0,187134.0,540822.0,1563011.0,4517183.0,1.3054898e7,3.7729362e7,1.09039875e8,3.15131087e8] apolloD2alt :: (Floating a) => [a] -> a apolloD2alt [] = 2 apolloD2alt [_] = 2 apolloD2alt (_:_:[]) = 3 apolloD2alt (x:y:z:_) = (x + y + z) - 2*sqrt(x*y + y*z + z*x) -- ^ -- >>> stake 20 $ revFix apolloD2alt -- [2.0,2.0,3.0,-1.0,2.0,2.0,3.0,-1.0,2.0,2.0,3.0,-1.0,2.0,2.0,3.0,-1.0,2.0,2.0,3.0,-1.0] -- with (2,2) as the init -- -- http://www.wolframalpha.com/input/?i=%7B2%2C2%2C8%2C24%2C66%2C194%2C560%2C1616%2C4674%2C13506%2C39032%2C+112808%2C+326018%2C+942210%2C+2723040%2C+7869728%7D -- -- 1st, 2nd, and 3rd differences have the same shape (and are colinear) -- -- successive ratios converging to: -- 28.9005 -- -- generating function: -- 2*(z - 1) / (z^4 - 2z^3 -2z^2 -2z + 1) -- -- rep-pair items: -- 2424 -- with (3,3) as init -- -- http://www.wolframalpha.com/input/?i=%7B3%2C3%2C12%2C36%2C99%2C291%2C840%2C2424%2C7011%2C20259%2C5848%2C169212%7D -- -- successive ratios: -- 28.935 -- -- with (4,4) as init -- -- successive ratios: -- 2.8896 -- -- gen: -- same, but with 4 coeff -- -- odd ones of these have rep-pair items -- -- successive ratios: -- 2.8896 -- 4040 here apd2 :: (Floating a) => [a] -> a apd2 [] = -1 apd2 [_] = 2 apd2 (_:_:[]) = 2 apd2 (x:y:z:_) = (x + y + z) + sqrt(x*y + y*z + z*x) -------------------------------------------------------------------------------------------------------------------------------- -- *** D3: (-0,0,1,1) -------------------------------------------------------------------------------------------------------------------------------- fr :: Num t => (t, t, t, t, t, t, t, t) -> (t, t, t, t, t, t, t, t) fr (m', a, b, c, w', x, y, z) = let m = (4 * w' - m') w = 4 * (4 * w' - m') - w' in ( m, 2*m + a, 2*m + b, 2*m + c, w, 2*w + x, 2*w + y, 2*w + z ) apd3 :: Coalg (Integer, (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)) Integer Integer apd3 = (now, next) where now (n,s) = proy s n next (n,s) _ = let n' = (n+1) `mod` 8 in (n', if n' == 0 then fr s else s) proy :: (a,a,a,a,a,a,a,a) -> Integer -> a proy (x,_,_,_,_,_,_,_) 0 = x proy (_,x,_,_,_,_,_,_) 1 = x proy (_,_,x,_,_,_,_,_) 2 = x proy (_,_,_,x,_,_,_,_) 3 = x proy (_,_,_,_,x,_,_,_) 4 = x proy (_,_,_,_,_,x,_,_) 5 = x proy (_,_,_,_,_,_,x,_) 6 = x proy (_,_,_,_,_,_,_,x) 7 = x proy (_,_,_,_,_,_,_,_) _ = error "this is unreachable" streamApD3 :: S Integer streamApD3 = cfix apd3 (0,(0,0,1,1,1,2,2,3)) -- ^ -- >>> stake 32 $ streamApD3 -- [0,0,1,1,1,2,2,3,4,8,9,9,15,32,32,33,56,120,121,121,209,450,450,451,780,1680,1681,1681,2911,6272,6272,6273] streamApD3' :: S (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer) streamApD3' = Cons (0,0,1,1,1,2,2,3) (sMap fr streamApD3') -- ^ -- >>> stake 4 $ streamApD3' -- [(0,0,1,1,1,2,2,3),(4,8,9,9,15,32,32,33),(56,120,121,121,209,450,450,451),(780,1680,1681,1681,2911,6272,6272,6273)] -- GF: -- 4 - z -- ------------- -- z^2 - 4z + 1 -------------------------------------------------------------------------------------------------------------------------------- -- ** Some /Fractal/ Numbers -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 30 $ fromOEIS "A025480" -- [0,0,1,0,2,1,3,0,4,2,5,1,6,3,7,0,8,4,9,2,10,5,11,1,12,6,13,3,14,7] frac :: S Integer frac = sNat |~| frac -- ^ -- >>> stake 30 $ frac -- [0,0,1,0,2,1,3,0,4,2,5,1,6,3,7,0,8,4,9,2,10,5,11,1,12,6,13,3,14,7] -------------------------------------------------------------------------------------------------------------------------------- -- ** Greatest Odd Divisor -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 30 $ fromOEIS "A000265" -- [1,1,3,1,5,3,7,1,9,5,11,3,13,7,15,1,17,9,19,5,21,11,23,3,25,13,27,7,29,15] god :: S Integer god = 2 * frac + 1 -- ^ -- >>> stake 30 $ god -- [1,1,3,1,5,3,7,1,9,5,11,3,13,7,15,1,17,9,19,5,21,11,23,3,25,13,27,7,29,15] -------------------------------------------------------------------------------------------------------------------------------- -- ** Dunno -------------------------------------------------------------------------------------------------------------------------------- blah :: S Integer blah = 2 ^ carry * god -- ^ -- @diverges!!@ -------------------------------------------------------------------------------------------------------------------------------- -- * The Zoo -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -- ** Moser-de-Bruijn sequence -------------------------------------------------------------------------------------------------------------------------------- -- -- Moser-de Bruijn sequence: sum of distinct powers of 4 -- http://oeis.org/A000695 -- http://oeis.org/wiki/Negabinary -- http://oeis.org/A005351 -- http://oeis.org/A005352 -- http://oeis.org/A053985 -------------------------------------------------------------------------------------------------------------------------------- -- ** Fermi Dirac Numbers -------------------------------------------------------------------------------------------------------------------------------- -- fermi dirac numbers -- -- http://oeis.org/A186285 -- http://oeis.org/A050376 -------------------------------------------------------------------------------------------------------------------------------- -- ** 5-Smooth (Hamming) (Regular) Numbers -------------------------------------------------------------------------------------------------------------------------------- -- Hamming (or Regular) (or 5-smooth) Numbers -- -- These should be a stream, but this version produces different output than I expected. -- -- http://rosettacode.org/wiki/Hamming_numbers#Haskell -- -- "classic" -- | -- >>> take 30 $ fromOEIS "A051037" -- [1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36,40,45,48,50,54,60,64,72,75,80] hamming :: S Integer hamming = 1 <|| smap (2*) hamming |!| smap (3*) hamming |!| smap (5*) hamming -- ^ -- >>> stake 30 $ hamming -- [1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36,40,45,48,50,54,60,64,72,75,80] montest :: S Integer montest = 1 <|| smap (47*) montest |!| smap (59*) montest |!| smap (71*) montest -------------------------------------------------------------------------------------------------------------------------------- -- ** Dunno this one either? -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 30 $ fromOEIS "A092323" -- [0,1,1,3,3,3,3,7,7,7,7,7,7,7,7,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15] a092323 :: S Integer a092323 = diff sNat - msb -- ^ -- >>> stake 30 $ (diff sNat - msb) -- [0,-1,-1,-3,-3,-3,-3,-7,-7,-7,-7,-7,-7,-7,-7,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15] -------------------------------------------------------------------------------------------------------------------------------- -- ** Carry Bits -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 30 $ fromOEIS "A007814" -- [0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1] carry :: S Integer carry = 0 <|| carry + 1 |~| 0 -- ^ -- >>> stake 30 $ carry -- [0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1] altCarry :: S Integer altCarry = (bsum carry |~| bsum carry) |~| (sNat |~| sNat) -- wrong! -- ^ -- @FIXME@: Incorrect! -- tree :: Integral a => a -> S a tree n = n <|| turn n <<| tree (n+1) -- ^ -- >>> stake 30 $ tree 0 -- [0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1] -------------------------------------------------------------------------------------------------------------------------------- -- ** Non-Negative Integers. Repeated. Floor (n/2) -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 30 $ fromOEIS "A004526" -- [0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14] a004526 :: S Integer a004526 = bsum $ 0 `smerge` 1 -- ^ -- >>> stake 30 $ a004526 -- [0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14] -------------------------------------------------------------------------------------------------------------------------------- -- ** Square Pyramidal Numbers -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 16 $ 0 : fromOEIS "A000330" -- [0,0,1,5,14,30,55,91,140,204,285,385,506,650,819,1015] a000330 :: S Integer a000330 = bsum $ sNat^(2::Integer) -- ^ -- >>> stake 16 $ a000330 -- [0,0,1,5,14,30,55,91,140,204,285,385,506,650,819,1015] -------------------------------------------------------------------------------------------------------------------------------- -- ** The "Perturbation Method" -------------------------------------------------------------------------------------------------------------------------------- -- | perturbation method -- -- bsum s = bsum (stail s) - s + repeat (shead s) -- -- bsum s = 0 <| repeat (shead s) + bsum (stail s) -------------------------------------------------------------------------------------------------------------------------------- -- ** iterate k = 2^n-k -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 21 $ 1 : fromOEIS "A078008" -- [1,1,0,2,2,6,10,22,42,86,170,342,682,1366,2730,5462,10922,21846,43690,87382,174762] iterk2nk :: S Integer iterk2nk = cfix (iterk2nkH, iterk2nkT) (0,1) iterk2nkH :: (a, b) -> a iterk2nkH (x,_) = x iterk2nkT :: (Num a) => (a, a) -> a -> (a, a) iterk2nkT (x,y) ____ = (2*y, x+y) -- ^ -- >>> stake 21 $ [1,1] <<| iterk2nk -- [1,1,0,2,2,6,10,22,42,86,170,342,682,1366,2730,5462,10922,21846,43690,87382,174762] -------------------------------------------------------------------------------------------------------------------------------- -- ** What the heck is this? -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 15 $ fromOEIS "A090017" -- [0,1,4,18,80,356,1584,7048,31360,139536,620864,2762528,12291840,54692416,243353344] a090017 :: G Integer Integer a090017 [] = 0 a090017 [_] = 1 a090017 (x:y:_) = 2*(2*x + y) -- ^ -- >>> stake 15 $ revFix a090017 -- [0,1,4,18,80,356,1584,7048,31360,139536,620864,2762528,12291840,54692416,243353344] -------------------------------------------------------------------------------------------------------------------------------- -- ** Horadam (0,1,4,2) Numbers -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 15 $ fromOEIS "A085449" -- [0,1,2,8,24,80,256,832,2688,8704,28160,91136,294912,954368,3088384] horadam0142 :: G Integer Integer horadam0142 [] = 0 horadam0142 [_] = 1 horadam0142 (x:y:_) = 2*(x + 2*y) -- ^ -- >>> stake 15 $ revFix horadam0142 -- [0,1,2,8,24,80,256,832,2688,8704,28160,91136,294912,954368,3088384] -------------------------------------------------------------------------------------------------------------------------------- -- ** Some random thing I found. -------------------------------------------------------------------------------------------------------------------------------- -- | -- >>> take 15 $ fromOEIS "A002605" -- [0,1,2,6,16,44,120,328,896,2448,6688,18272,49920,136384,372608] a002605 :: G Integer Integer a002605 [] = 0 a002605 [_] = 1 a002605 (x:y:_) = 2*(x + y) -- ^ -- >>> stake 15 $ revFix a002605 -- [0,1,2,6,16,44,120,328,896,2448,6688,18272,49920,136384,372608]