[Haskell-begin] Alternating sequence

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

[Haskell-begin] Alternating sequence

Dirk Markert
I am trying to generate the following list:
2, 3, 5 -- and then alternating (+2) resp (+4) -- 7, 11, 13, 17, 19, 23

I came up with the following solution
2:3:unfoldr (\(a,b) -> Just (a,(a+b, if b == 2 then 4 else 2))) (5,2)

Are there easier ways to generate the desired list?

Dirk
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20080721/6a69ff23/attachment-0001.htm
Reply | Threaded
Open this post in threaded view
|

[Haskell-begin] Alternating sequence

Bernie Pope

On 21/07/2008, at 11:34 PM, Dirk Markert wrote:

> I am trying to generate the following list:
> 2, 3, 5 -- and then alternating (+2) resp (+4) -- 7, 11, 13, 17, 19,  
> 23
>
> I came up with the following solution
> 2:3:unfoldr (\(a,b) -> Just (a,(a+b, if b == 2 then 4 else 2))) (5,2)
>
> Are there easier ways to generate the desired list?

Hi Dirk,

I doubt this is "easier", but it is a nice opportunity to show off  
some cyclic programming:

    suffix = 5 : [ x + y | (x,y) <- zip suffix (cycle [2,4])]
    list = 2 : 3 : suffix

cycle is from the Prelude and is used above to build an "infinite"  
list of [2,4,2,4 ...]

Note that suffix is recursive. Lazy evaluation allows us to pull  
values out of it whilst building it at the same time. Obviously it is  
important that we start building the list before trying to pull any  
values out of it, hence the "5 :" at the start is important.

I may not have answered your question, but hopefully it is interesting  
nonetheless.

Cheers,
Bernie.


Reply | Threaded
Open this post in threaded view
|

[Haskell-begin] Alternating sequence

Felipe Lessa
On Mon, Jul 21, 2008 at 11:21 AM, Bernie Pope <[hidden email]> wrote:
>   suffix = 5 : [ x + y | (x,y) <- zip suffix (cycle [2,4])]
>   list = 2 : 3 : suffix

'suffix' can be simplified a bit by using zipWith:

suffix = 5 : zipWith (+) suffix (cycle [2,4])


Thanks,

--
Felipe.
Reply | Threaded
Open this post in threaded view
|

[Haskell-begin] Alternating sequence

Kurt Hutchinson
In reply to this post by Dirk Markert
On Mon, Jul 21, 2008 at 9:34 AM, Dirk Markert <[hidden email]> wrote:
> I am trying to generate the following list:
> 2, 3, 5 -- and then alternating (+2) resp (+4) -- 7, 11, 13, 17, 19, 23
>
> I came up with the following solution
> 2:3:unfoldr (\(a,b) -> Just (a,(a+b, if b == 2 then 4 else 2))) (5,2)
>
> Are there easier ways to generate the desired list?


So you've got the beginnings of an infinite list, and a rule to modify
that to generate new elements. How about turning that rule into a list
of its own, and then combining them?

  rule = cycle [ 2, 4 ]  -- this will give an infinite list of 2's and 4's

Combining two lists is usually done with 'zip'. But in this case, we
don't just want tuples, we want the sum of each pair. You can combine
lists with a function by using 'zipWith'. Start at the point where the
rule kicks in.

  rest = 5 : zipWith (+) rest rule

Now just tack on your first elements.

  list = 2 : 3 : rest

Here it is all in one place:

  list = 2 : 3 : rest
    where
    rule = cycle [ 2, 4 ]
    rest = 5 : zipWith (+) rest rule

Kurt
Reply | Threaded
Open this post in threaded view
|

[Haskell-begin] Alternating sequence

Heinrich Apfelmus
In reply to this post by Dirk Markert
Dirk Markert wrote:
> I am trying to generate the following list:
> 2, 3, 5 -- and then alternating (+2) resp (+4) -- 7, 11, 13, 17, 19, 23
>
> I came up with the following solution
> 2:3:unfoldr (\(a,b) -> Just (a,(a+b, if b == 2 then 4 else 2))) (5,2)
>
> Are there easier ways to generate the desired list?

Use a left scan

   result = 2:3:scanl (+) 5 (cycle [2,4])


Regards,
apfelmus

Reply | Threaded
Open this post in threaded view
|

[Haskell-begin] Alternating sequence

Dirk Markert
In reply to this post by Bernie Pope
Hi Bernie,

I like your much more. I tried also to find a solution using cycle but
didn't succeed.

Thank you,
Dirk

2008/7/21 Bernie Pope <[hidden email]>:

> Hi Dirk,
>
> I doubt this is "easier", but it is a nice opportunity to show off some
> cyclic programming:
>
>   suffix = 5 : [ x + y | (x,y) <- zip suffix (cycle [2,4])]
>   list = 2 : 3 : suffix
>
> cycle is from the Prelude and is used above to build an "infinite" list of
> [2,4,2,4 ...]
>
> Note that suffix is recursive. Lazy evaluation allows us to pull values out
> of it whilst building it at the same time. Obviously it is important that we
> start building the list before trying to pull any values out of it, hence
> the "5 :" at the start is important.
>
> I may not have answered your question, but hopefully it is interesting
> nonetheless.
>
> Cheers,
> Bernie.
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20080721/12a4c1e3/attachment.htm
Reply | Threaded
Open this post in threaded view
|

[Haskell-begin] Alternating sequence

Dirk Markert
In reply to this post by Felipe Lessa
Hi Felipe,

very nice simplification. Now I can even recognize the pattern used in the
fibonacci number solution.

Thanks,
Dirk

2008/7/21 Felipe Lessa <[hidden email]>:

> On Mon, Jul 21, 2008 at 11:21 AM, Bernie Pope <[hidden email]>
> wrote:
> >   suffix = 5 : [ x + y | (x,y) <- zip suffix (cycle [2,4])]
> >   list = 2 : 3 : suffix
>
> 'suffix' can be simplified a bit by using zipWith:
>
> suffix = 5 : zipWith (+) suffix (cycle [2,4])
>
>
> Thanks,
>
> --
> Felipe.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20080721/d185ba25/attachment.htm
Reply | Threaded
Open this post in threaded view
|

[Haskell-begin] Alternating sequence

Dirk Markert
In reply to this post by Kurt Hutchinson
Hi Kurt,

thank you for the detailed explanation. Indeed, I could follow your
explanation on first reading :-)

Dirk

2008/7/21 Kurt Hutchinson <[hidden email]>:

> On Mon, Jul 21, 2008 at 9:34 AM, Dirk Markert <[hidden email]>
> wrote:
> > I am trying to generate the following list:
> > 2, 3, 5 -- and then alternating (+2) resp (+4) -- 7, 11, 13, 17, 19, 23
> >
> > I came up with the following solution
> > 2:3:unfoldr (\(a,b) -> Just (a,(a+b, if b == 2 then 4 else 2))) (5,2)
> >
> > Are there easier ways to generate the desired list?
>
>
> So you've got the beginnings of an infinite list, and a rule to modify
> that to generate new elements. How about turning that rule into a list
> of its own, and then combining them?
>
>  rule = cycle [ 2, 4 ]  -- this will give an infinite list of 2's and 4's
>
> Combining two lists is usually done with 'zip'. But in this case, we
> don't just want tuples, we want the sum of each pair. You can combine
> lists with a function by using 'zipWith'. Start at the point where the
> rule kicks in.
>
>  rest = 5 : zipWith (+) rest rule
>
> Now just tack on your first elements.
>
>  list = 2 : 3 : rest
>
> Here it is all in one place:
>
>  list = 2 : 3 : rest
>    where
>    rule = cycle [ 2, 4 ]
>    rest = 5 : zipWith (+) rest rule
>
> Kurt
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20080721/11916c94/attachment.htm
Reply | Threaded
Open this post in threaded view
|

[Haskell-begin] Alternating sequence

Dirk Markert
In reply to this post by Heinrich Apfelmus
Hi apfelmus,

of course a left scan. What else!
Really a very, very nice solution.

Thank you,
Dirk

2008/7/21 apfelmus <[hidden email]>:

> Use a left scan
>
>  result = 2:3:scanl (+) 5 (cycle [2,4])
>
>
> Regards,
> apfelmus
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20080721/2bcb38f0/attachment-0001.htm
Reply | Threaded
Open this post in threaded view
|

[Haskell-begin] Alternating sequence

Andrew Wagner
In reply to this post by Dirk Markert
Another way to define 'rule' here, just for kicks:
rule = 2 : 4 : rule


On Mon, Jul 21, 2008 at 11:57 AM, Dirk Markert <[hidden email]> wrote:

> Hi Kurt,
>
> thank you for the detailed explanation. Indeed, I could follow your
> explanation on first reading :-)
>
> Dirk
>
> 2008/7/21 Kurt Hutchinson <[hidden email]>:
>>
>> On Mon, Jul 21, 2008 at 9:34 AM, Dirk Markert <[hidden email]>
>> wrote:
>> > I am trying to generate the following list:
>> > 2, 3, 5 -- and then alternating (+2) resp (+4) -- 7, 11, 13, 17, 19, 23
>> >
>> > I came up with the following solution
>> > 2:3:unfoldr (\(a,b) -> Just (a,(a+b, if b == 2 then 4 else 2))) (5,2)
>> >
>> > Are there easier ways to generate the desired list?
>>
>>
>> So you've got the beginnings of an infinite list, and a rule to modify
>> that to generate new elements. How about turning that rule into a list
>> of its own, and then combining them?
>>
>>  rule = cycle [ 2, 4 ]  -- this will give an infinite list of 2's and 4's
>>
>> Combining two lists is usually done with 'zip'. But in this case, we
>> don't just want tuples, we want the sum of each pair. You can combine
>> lists with a function by using 'zipWith'. Start at the point where the
>> rule kicks in.
>>
>>  rest = 5 : zipWith (+) rest rule
>>
>> Now just tack on your first elements.
>>
>>  list = 2 : 3 : rest
>>
>> Here it is all in one place:
>>
>>  list = 2 : 3 : rest
>>    where
>>    rule = cycle [ 2, 4 ]
>>    rest = 5 : zipWith (+) rest rule
>>
>> Kurt
>
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/beginners
>
>