Mathematica 9 is now available
Services & Resources / Wolfram Forums
-----
 /
MathGroup Archive
2003
*January
*February
*March
*April
*May
*June
*July
*August
*September
*October
*November
*December
*Archive Index
*Ask about this page
*Print this page
*Give us feedback
*Sign up for the Wolfram Insider

MathGroup Archive 2003

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Need a nice way to do this

  • To: mathgroup at smc.vnet.net
  • Subject: [mg40288] Re: [mg40279] Need a nice way to do this
  • From: Andrzej Kozlowski <akoz at mimuw.edu.pl>
  • Date: Sun, 30 Mar 2003 04:07:59 -0500 (EST)
  • Sender: owner-wri-mathgroup at wolfram.com

Here is one (nice?) way of doing this  that does not depend on how many 
different values s contains:

f1[s_List] := MapIndexed[Length[DeleteCases[Take[s, First[#2]], #1]] &, 
s]

and here is another one that works only (as it stands) with just two 
distinct values:

f2[l_List] := Module[{mult =
    Length /@ Split[l], list1,
         list2, values}, list1 = Rest[FoldList[Plus, 0, Table[mult[[i]], 
{i, 1,
        Length[mult],
     2}]]]; list2 =
       FoldList[Plus,
          0, Table[mult[[i]], {i, 2, 2(
           Floor[(Length[mult] + 1)/2]) - 1, 2}]];
             values = Take[Flatten[Transpose[{list2,
               list1}]], Length[mult]]; Flatten[Table[Table[values[[i]], 
{
         mult[[i]]}], {i, 1, Length[mult]}]]]


The second function is a lot more complex and may not satisfy your 
criteria of "niceness" but it is also a lot more efficient.

Let's first make sure they both work correctly with your original s:

In[3]:=
s={a,b,b,a,a,a,b,a,b,a,a};

In[4]:=
f1[s]

Out[4]=
{0,1,1,2,2,2,4,3,5,4,4}

In[5]:=
f2[s]

Out[5]=
{0,1,1,2,2,2,4,3,5,4,4}

Now let's try something bigger:

In[6]:=
s=Table[If[Random[Integer]==1,a,b],{10^3}];

In[7]:=
a=f1[s];//Timing

Out[7]=
{1.37 Second,Null}

In[8]:=
b=f2[s];//Timing

Out[8]=
{0.04 Second,Null}

In[9]:=
a==b

Out[9]=
True

So "niceness" doesn't always pays, it seems.


Andrzej Kozlowski
Yokohama, Japan
http://www.mimuw.edu.pl/~akoz/
http://platon.c.u-tokyo.ac.jp/andrzej/

On Saturday, March 29, 2003, at 07:19  pm, Steve Gray wrote:

> 	Given a list consisting of only two distinct values, such as
> s={a,b,b,a,a,a,b,a,b,a,a}, I want to derive a list of equal length
> g={0,1,1,2,2,2,4,3,5,4,4}. The rule is: for each position
> 1<=p<=Length[s], look at list s and set g[[p]] to the number of
> elements in s to the left of p which are not equal to s[[p]].
> 	In a more general version, which I do  not need now, s would
> not be restricted to only two distinct values.
>
> 	Thank you for any ideas, including other applications where
> this particular calculation is used. The current application is an
> unusual conjecture in geometry.
>
>
>
>



  • Prev by Date: Re: Need a nice way to do this
  • Next by Date: Re: A difficult problem
  • Previous by thread: Re: Need a nice way to do this
  • Next by thread: Re: Need a nice way to do this