Send Beginners mailing list submissions to beginners@haskell.org 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 beginners-requ...@haskell.org
You can reach the person managing the list at beginners-ow...@haskell.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Beginners digest..." Today's Topics: 1. Re: Better Code (Carlo Matteo Scalzo) 2. Re: Better Code (Graham Gill) ---------------------------------------------------------------------- Message: 1 Date: Fri, 13 Jan 2017 22:43:27 +0000 From: Carlo Matteo Scalzo <cmsca...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] Better Code Message-ID: <CAMYQrycER4RkTe+cQrjRkitdXERb=3xkt+uocr_scmrfsit...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" Hi Saqib, perhaps something like this? divide :: [Int] -> [[Int]] divide [] = [] divide (x:xs) = divideAux xs [] [x] x divideAux :: [Int] -> [[Int]] -> [Int] -> Int -> [[Int]] divideAux [] result current max = result ++ [current] divideAux (x:xs) result current max = if x - max > 1 then divideAux xs (result ++ [current]) [x] x else divideAux xs result (current ++ [x]) x This can of course be generalised to other types (as per Joel's requirement) just by replacing the check on line 7, i.e., 'x - max > 1'. Happy to explain/talk about the code if you'd like me to :-) Cheers, Carlo On Fri, Jan 13, 2017 at 7:14 PM, Joel Neely <joel.ne...@gmail.com> wrote: > 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 <shamsi.sa...@gmail.com> > 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 >> Beginners@haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> >> > > > -- > Beauty of style and harmony and grace and good rhythm depend on > simplicity. - Plato > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -- Carlo Matteo Scalzo Mobile: +44 (0) 7934 583582 E-mail: cmsca...@gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20170113/6b9425f2/attachment-0001.html> ------------------------------ Message: 2 Date: Fri, 13 Jan 2017 18:43:19 -0500 From: Graham Gill <math.simp...@gmail.com> To: beginners@haskell.org Subject: Re: [Haskell-beginners] Better Code Message-ID: <6ba448e9-d180-6ca7-6e04-f1ee3ebf4...@gmail.com> Content-Type: text/plain; charset="utf-8"; Format="flowed" Here's one that does what you want, doesn't require the list to be sorted, and groups together consecutive and equal terms: groupConsecutive :: (Enum a,Eq a) => [a] -> [[a]] groupConsecutive = foldr go [] where go x ls@(hd@(y:_):yss) | x == y || x == pred y = (x:hd):yss | otherwise = [x]:ls go x [] = [[x]] go x ([]:yss) = [x]:yss Then > groupConsecutive [1,2,3,7,8,10,11,12] [[1,2,3],[7,8],[10,11,12]] > groupConsecutive [1,2,2,3,2,3] [[1,2,2,3],[2,3]] and > groupConsecutive "bookkeeper understudy" ["b","oo","kk","ee","p","e","r"," ","u","n","de","rstu","d","y"] The third case of go will never be reached. If you use a type that is also an instance of Bounded, and if your list contains the minimum element of the type, you'll get a runtime error on the use of pred. For example: > groupConsecutive [True,False,True] *** Exception: Prelude.Enum.Bool.pred: bad argument Graham On 13-Jan-2017 11:05 AM, Saqib Shamsi 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 > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20170113/a85d590f/attachment.html> ------------------------------ Subject: Digest Footer _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners ------------------------------ End of Beginners Digest, Vol 103, Issue 9 *****************************************