Message Boards Message Boards

1
|
9475 Views
|
11 Replies
|
15 Total Likes
View groups...
Share
Share this post:

How to contract a list?

I would like to "contract" a list of any length $k$, consisting of $n=2$ repeating elements, so that all repetitions within the sequence are deleted:

In[1]:= {a, a, b, b, a, b, b, b, a, a, b, b, a};
Out= {a, b, a, b, a, b, a} (*desired output*)

Or in the case of $n=3$:

In[2]:= {b, a, a, c, a, b, b, c, c, b, a, a, a, b, c, c, c, a, a}
Out= {b, a, c, a, b, c, b, a, b, c, a} (*desired output*)

I am thinking of FoldList or Fold but cannot figure out how to get there in the most succinct manner. Pattern matching also allowed. Thanks in advance for your help!

POSTED BY: Raspi Rascal
11 Replies

In a similar vein, with SequenceReplace:
SequenceReplace[anylist, {Repeated[v_]} :> v]

POSTED BY: Jesse Friedman

Or simply:

In[1]:= Split[listica][[All, 1]]
Out[1]= {a, b, a, b, a, b, a}

As an aside, although not particularly relevant here: note that Union always sorts its result into canonical order. If you don't need that behavior, DeleteDuplicates is often much faster:

In[2]:= RepeatedTiming[Union@RandomChoice[{a, b, c}, 10000000];]
Out[2]= {2.76162, Null}

In[3]:= RepeatedTiming[DeleteDuplicates@RandomChoice[{a, b, c}, 10000000];]
Out[3]= {0.674569, Null}
POSTED BY: Jesse Friedman
Posted 3 years ago

and a recursive version:

contract[{rest___, (last_) ..}] := Append[contract[{rest}], last]
contract[{}] := {}
POSTED BY: Oliver Seipel
Posted 3 years ago

a faster version based on Split:

Map[First, Split[list]]
POSTED BY: Oliver Seipel
Posted 3 years ago

@Raspi:

You are too humble.

Have a great and safe New Year.

POSTED BY: Mike Besso

My pleasure Raspi, luck with your book!

Actually i am writing a book ...

Ahhhh, therefore the reference to LaTeX in one of your recent posts and all these challenging problems! Surely a good project - always glad to help!

POSTED BY: Henrik Schachner

Thank you so much @Henrik for the interesting coding alternative, which I wasn't able to figure out on my own (pattern matching). I learn, forget, need to relearn, forget again, omg.

Actually I am writing a book (a solutions manual to a high school math text) and I have included a link to this discussion. So your coding contributions add permanent value to my book, thanks again!!

Happy New Year @everyone!

POSTED BY: Raspi Rascal

Hello Raspi,

here is an obvious way based on a replacement:

anylist //. {start___, PatternSequence[e_, e_], end___} :> {start, e, end}

But I would prefer Franciscos method using Split.

POSTED BY: Henrik Schachner

Oh today I wasn't aware of the Split function, my restricted active vocabulary is embarrassing. @Mike i am still the original beginner, haha! Yes, this solves the problem beautifully, very succinct, thank you very much @Francisco, appreciated!

Great community here!

POSTED BY: Raspi Rascal

Hi Raspi. The following code will do it: listica = {a, a, b, b, a, b, b, b, a, a, b, b, a}; Flatten[Map[Union, Split[listica]]]

Also works for the other list you provided. Hope this helps Francisco

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract