Reputation: 249
I want a function f::[type]->[type]
that is recursive defined roughly like this :
It starts with a list with 1 element x
. Then it applies 3 "generator functions" lets call them
generatorA
, generatorB
, and generator C
, all functions ::type->type
, and adds those to the list IF they accept some condition. for each accepted generated number, it repeats applying generator A
, B
and C
and test conditions until condition test is false. So for each element accepted to the list, 3 new elements will be generated and tested for list.
An example would be:
f::[int]->[Int]
generatorA x = x+1
generatorB x = 2x+1
generatorC x = 3x+1
Condition: Must be composite number (not prime).
computing f [10]
it should start generatorA 10 = 11
, discard that.
generatorB 10 = 21
accept and then:
generatorA 21 = 22
accept and then:generatorA 22 = 23
prime discard.generatorB 21 = 43
discardgeneratorC 21 = 64
accept and etc. etc. etc.Question is: How do i code the function f
? I have no idea how to even begin. my best guess was
f (x:xs)
|condition==True = (something something)
|otherwise = xs
where
a=generatorA x
b=generatorB x
c=generatorC x
thanks for your help.
Upvotes: 2
Views: 953
Reputation: 81
use Data.Tree.unfoldTree :: (b -> (a, [b])) -> b -> Tree a
to build your list of values. then use flatten
if you want preorder, or concat . Data.Tree.levels
to have a breadth first order.
f x = flatten $ unfoldTree (\b -> (b, filter composite (map ($ b) [ga, gb, gc]))) x
this list will include the initial seed element, if you don't want that element. just call tail
.
Upvotes: 2
Reputation: 71119
If it starts with a singleton list it might as well start with a single value as its argument.
ga x = [y | let y=x+1, composite y] >>= (\x-> x:f x)
gb x = [y | let y=2*x+1, composite y] >>= (\x-> x:f x)
gc x = [y | let y=3*x+1, composite y] >>= (\x-> x:f x)
f :: Integer -> [Integer]
f x = ga x ++ gb x ++ gc x
I use Integer
s to avoid overflow issues. Testing:
*Main> take 40 $ f 10
[21,22,45,46,93,94,95,96,289,290,291,292,585,586,1173,1174,1175,1176,1177,1178,1
179,1180,2361,2362,2363,2364,2365,2366,2367,2368,2369,2370,4741,4742,4743,4744,4
745,4746,4747,4748]
f
can also be implemented to produce the results in shallower fashion,
import Data.List
f x = concat $ transpose [ga x, gb x, gc x]
Testing:
*Main> take 80 $ h 10
[21,22,64,45,65,46,129,91,66,136,130,93,196,92,259,273,133,94,388,183,393,274,26
1,187,134,274,260,820,589,280,777,93,267,275,391,95,394,184,519,1641,400,188,116
5,275,590,549,262,561,135,185,778,2461,1180,189,778,550,268,276,392,375,1179,549
,261,1642,801,841,1166,94,395,550,784,96,403,185,520,2462,1768,562,1555,276]
Upvotes: 3