How could I make a list where I get every number/letter which has a prime index number?
primeIndex :: [a] -> [a]
primeIndex [1..20] == [2, 3, 5, 7, 11, 13, 17, 19]
primeIndex "primesarefun" == "rieau"
How could I make a list where I get every number/letter which has a prime index number?
primeIndex :: [a] -> [a]
primeIndex [1..20] == [2, 3, 5, 7, 11, 13, 17, 19]
primeIndex "primesarefun" == "rieau"
Following the general approach mentioned above by @Joseph Sible-Reinstate Monica, the problem can be solved like this:
primes
True
elements solely at prime indicesRegarding the first part, there are a number of available algorithms in the relevant page of the Haskell Wiki. We can just pick one of them.
import Data.List.Ordered
_Y :: (t -> t) -> t
_Y g = g (_Y g)
joinL :: (Ord a, Eq a) => [[a]] -> [a]
joinL ((x:xs):t) = x : union xs (joinL t)
joinL ([]:t) = joinL t
joinL [] = []
primesLME :: [Integer]
primesLME = 2 : _Y ((3:) . minus [5,7..] . joinL . map (\p-> [p*p, p*p+2*p..]))
primes = primesLME
with LME standing for Linear MErging.
Regarding the second part, a function to transform primes
into the required list of booleans, say primeMask
, can be taken from SO_q59092535.
-- boolean list from index list (with unfoldr):
booleansFromIndices :: [Integer] -> [Bool]
booleansFromIndices indices =
let sfn (pos,ind) = Just $ -- stepping function for unfoldr
if (null ind)
then ( False, (pos+1, []) )
else ( pos==head ind,
(pos+1, if (pos==head ind) then tail ind else ind))
in unfoldr sfn (0,indices)
primeMask :: [Bool]
primeMask = drop 1 $ booleansFromIndices primes -- 1-based indexing
In a ghci
session:
λ>
λ> take 10 primes
[2,3,5,7,11,13,17,19,23,29]
λ>
λ>
λ> take 15 primeMask
[False,True,True,False,True,False,True,False,False,False,True,False,True,False,False]
λ>
λ> take 20 $ map (\b -> if b then '1' else '0') primeMask
"01101010001010001010"
λ>
λ> str = "primesarefun"
λ>
λ> zip primeMask str
[(False,'p'),(True,'r'),(True,'i'),(False,'m'),(True,'e'),(False,'s'),(True,'a'),(False,'r'),(False,'e'),(False,'f'),(True,'u'),(False,'n')]
λ>
λ> filter fst $ zip primeMask str
[(True,'r'),(True,'i'),(True,'e'),(True,'a'),(True,'u')]
λ>
λ> map snd $ filter fst $ zip primeMask str
"rieau"
λ>
λ> primeIndex = \xs -> map snd $ filter fst $ zip primeMask xs
λ>
λ> primeIndex [1..20]
[2,3,5,7,11,13,17,19]
λ>