Re: Beginners Digest, Vol 103, Issue 8

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

Re: Beginners Digest, Vol 103, Issue 8

Saqib Shamsi
Hello Francesco,

Sorry for the late reply. Yes, your solution is elegant and does what I wanted. This is what I did

-- zipped is the list of tuples formed as you mentioned

λ> groupBy (\x y -> (snd x) == (snd y)) zipped
[[(1,0),(2,0),(3,0)],[(7,3),(8,3)],[(10,4),(11,4),(12,4)]]

λ> [[fst tpl | tpl <- x] | x <- it]
[[1,2,3],[7,8],[10,11,12]]

This works perfectly fine.

Thank you.
Regards,
Saqib Shamsi



On 14 January 2017 at 00:27, <[hidden email]> wrote:
Send Beginners mailing list submissions to
        [hidden email]

To subscribe or unsubscribe via the World Wide Web, visit
        http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        [hidden email]

You can reach the person managing the list at
        [hidden email]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1.  Better Code (Saqib Shamsi)
   2. Re:  Better Code (Francesco Ariis)
   3. Re:  Better Code (Joel Neely)
   4. Re:  Better Code (Joel Neely)


----------------------------------------------------------------------

Message: 1
Date: Fri, 13 Jan 2017 21:35:54 +0530
From: Saqib Shamsi <[hidden email]>
To: [hidden email]
Subject: [Haskell-beginners] Better Code
Message-ID:
        <CAKpYsCGKeWoHttqpZAF7jAkhe++PqLSfwZA820tA=[hidden email]>
Content-Type: text/plain; charset="utf-8"

Hi,

The problem that I wish to solve is to divide a (sored) list of integers
into sublists such that each sublist contains numbers in consecutive
sequence.

For example,
*Input:* [1,2,3,7,8,10,11,12]
*Output:* [[1,2,3],[7,8],[10,11,12]]

I have written the following code and it does the trick.

-- Take a list and divide it at first point of non-consecutive number
encounter
divide :: [Int] -> [Int] -> ([Int], [Int])
divide first [] = (first, [])
divide first second = if (last first) /= firstSecond - 1 then (first,
second)
                      else divide (first ++ [firstSecond]) (tail second)
                      where firstSecond = head second


-- Helper for breaking a list of numbers into consecutive sublists
breakIntoConsecsHelper :: [Int] -> [[Int]] -> [[Int]]
breakIntoConsecsHelper [] [[]] = [[]]
breakIntoConsecsHelper lst ans = if two == [] then ans ++ [one]
                                 else ans ++ [one] ++
breakIntoConsecsHelper two []
                                 where
                                      firstElem = head lst
                                      remaining = tail lst
                                      (one, two) = divide [firstElem]
remaining


-- Break the list into sublists of consective numbers
breakIntoConsecs :: [Int] -> [[Int]]
breakIntoConsecs lst = breakIntoConsecsHelper lst [[]]

-- Take the tail of the result given by the function above to get the
required list of lists.

However, I was wondering if there was a better way of doing this. Any help
would be highly appreciated.

Thank you.
Best Regards,
Saqib Shamsi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20170113/3f37c4a5/attachment-0001.html>

------------------------------

Message: 2
Date: Fri, 13 Jan 2017 17:55:16 +0100
From: Francesco Ariis <[hidden email]>
To: [hidden email]
Subject: Re: [Haskell-beginners] Better Code
Message-ID: <20170113165516.GB23022@casa.casa>
Content-Type: text/plain; charset=utf-8

On Fri, Jan 13, 2017 at 09:35:54PM +0530, Saqib Shamsi wrote:
> The problem that I wish to solve is to divide a (sored) list of integers
> into sublists such that each sublist contains numbers in consecutive
> sequence.
>
> For example,
> *Input:* [1,2,3,7,8,10,11,12]
> *Output:* [[1,2,3],[7,8],[10,11,12]]
>
> [...]
>
> However, I was wondering if there was a better way of doing this. Any help
> would be highly appreciated.

Hello Saquib,
    you could try using a 'trick' like this:

λ> zipWith (-) [1,2,3,7,8,10,11,12] (enumFrom 1)
[0,0,0,3,3,4,4,4]

Now you have an 'helper' list which can be glued to the first one
with zip

λ> zip [1,2,3,7,8,10,11,12] it
[(1,0),(2,0),(3,0),(7,3),(8,3),(10,4),(11,4),(12,4)]

and now grouped by using `groupBy` in Data.List.

Does that help?


------------------------------

Message: 3
Date: Fri, 13 Jan 2017 11:40:57 -0600
From: Joel Neely <[hidden email]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[hidden email]>
Subject: Re: [Haskell-beginners] Better Code
Message-ID:
        <CAEEzXAjPaZ+F3-+3FDMy+DRdXX-Qvrqvw6=[hidden email]>
Content-Type: text/plain; charset="utf-8"

The "helper list" technique is ingenious, but seems very specific to Int as
the type within the list.

I have had other tasks that seem to fit a more generalized problem
statement, of which the original question appears to me as special case:

Given a criterion of type a -> a -> Bool and a list [a], produce a list of
lists [[a]] in which sub-lists are made up of consecutive elements from the
original list that satisfy the criterion.

It appears to me that List.groupBy may meet that need, but I'm not able to
verify that at the moment (and would be glad of feedback).

-jn-





On Fri, Jan 13, 2017 at 10:55 AM, Francesco Ariis <[hidden email]> wrote:

> On Fri, Jan 13, 2017 at 09:35:54PM +0530, Saqib Shamsi wrote:
> > The problem that I wish to solve is to divide a (sored) list of integers
> > into sublists such that each sublist contains numbers in consecutive
> > sequence.
> >
> > For example,
> > *Input:* [1,2,3,7,8,10,11,12]
> > *Output:* [[1,2,3],[7,8],[10,11,12]]
> >
> > [...]
> >
> > However, I was wondering if there was a better way of doing this. Any
> help
> > would be highly appreciated.
>
> Hello Saquib,
>     you could try using a 'trick' like this:
>
> λ> zipWith (-) [1,2,3,7,8,10,11,12] (enumFrom 1)
> [0,0,0,3,3,4,4,4]
>
> Now you have an 'helper' list which can be glued to the first one
> with zip
>
> λ> zip [1,2,3,7,8,10,11,12] it
> [(1,0),(2,0),(3,0),(7,3),(8,3),(10,4),(11,4),(12,4)]
>
> and now grouped by using `groupBy` in Data.List.
>
> Does that help?
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>



--
Beauty of style and harmony and grace and good rhythm depend on simplicity.
- Plato
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20170113/35931560/attachment-0001.html>

------------------------------

Message: 4
Date: Fri, 13 Jan 2017 13:14:56 -0600
From: Joel Neely <[hidden email]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[hidden email]>
Subject: Re: [Haskell-beginners] Better Code
Message-ID:
        <CAEEzXAg=a2-xJm+vu0cGA3ETkViZP=[hidden email]>
Content-Type: text/plain; charset="utf-8"

Had a chance to chat with ghci, so earlier conjecture not confirmed:

Prelude Data.List> groupBy (\x y -> x == y-1) [1,2,3,7,8,10,11,12]

[[1,2],[3],[7,8],[10,11],[12]]

So close but no cigar.

On Fri, Jan 13, 2017 at 10:05 AM, Saqib Shamsi <[hidden email]>
wrote:

> Hi,
>
> The problem that I wish to solve is to divide a (sored) list of integers
> into sublists such that each sublist contains numbers in consecutive
> sequence.
>
> For example,
> *Input:* [1,2,3,7,8,10,11,12]
> *Output:* [[1,2,3],[7,8],[10,11,12]]
>
> I have written the following code and it does the trick.
>
> -- Take a list and divide it at first point of non-consecutive number
> encounter
> divide :: [Int] -> [Int] -> ([Int], [Int])
> divide first [] = (first, [])
> divide first second = if (last first) /= firstSecond - 1 then (first,
> second)
>                       else divide (first ++ [firstSecond]) (tail second)
>                       where firstSecond = head second
>
>
> -- Helper for breaking a list of numbers into consecutive sublists
> breakIntoConsecsHelper :: [Int] -> [[Int]] -> [[Int]]
> breakIntoConsecsHelper [] [[]] = [[]]
> breakIntoConsecsHelper lst ans = if two == [] then ans ++ [one]
>                                  else ans ++ [one] ++
> breakIntoConsecsHelper two []
>                                  where
>                                       firstElem = head lst
>                                       remaining = tail lst
>                                       (one, two) = divide [firstElem]
> remaining
>
>
> -- Break the list into sublists of consective numbers
> breakIntoConsecs :: [Int] -> [[Int]]
> breakIntoConsecs lst = breakIntoConsecsHelper lst [[]]
>
> -- Take the tail of the result given by the function above to get the
> required list of lists.
>
> However, I was wondering if there was a better way of doing this. Any help
> would be highly appreciated.
>
> Thank you.
> Best Regards,
> Saqib Shamsi
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
>


--
Beauty of style and harmony and grace and good rhythm depend on simplicity.
- Plato
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20170113/df78caf6/attachment.html>

------------------------------

Subject: Digest Footer

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


------------------------------

End of Beginners Digest, Vol 103, Issue 8
*****************************************


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners