MathGroup Archive 2002

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

Search the Archive

RE: A friendly challenge: Generalized Partition

  • To: mathgroup at smc.vnet.net
  • Subject: [mg34924] RE: [mg34858] A friendly challenge: Generalized Partition
  • From: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.com>
  • Date: Thu, 13 Jun 2002 02:38:12 -0400 (EDT)
  • Sender: owner-wri-mathgroup at wolfram.com


> -----Original Message-----
> From: gleam at flashmail.com [mailto:gleam at flashmail.com]
To: mathgroup at smc.vnet.net
> Sent: Tuesday, June 11, 2002 11:00 AM
> Subject: [mg34924] [mg34858] A friendly challenge: Generalized Partition
> 
> 
> In the 4.1 help browser, in Further Examples under Take, there is code
> for a generalized partition function, called gg.  This code is
> somewhat long and extremely slow.  I challenge you to duplicate the
> functionality of this code (ignoring the ggCheckArgs condition), while
> making it 1) as sort as possible, and/or 2) as fast as possible.
> 
> Your function must be in good form, leaving no stray assignments, i.e.
> using the appropriate scoping construct(s).
> 
> For efficiency testing, I will use (where func is your function):
> 
> a = Range[2000];
> b = Table[Random[Integer, {1, 20}], {150}];
> First[Timing[Do[func[a, b], {100}]]]
> 
> I will post my versions after a little while.  For reference, on my
> machine, the function from the help files, omitting the ggCheckArgs
> condition, takes 8 seconds; my fastest version takes 0.33 seconds.  My
> shortest version is 44 characters in length, and takes 0.94 seconds.
> 
> Good luck!
> 
> Paul
> 
> 

Paul,

perhaps it would have been better to put your cards onto the table -- and I
hope that you not only do perfect testing (the proposal above isn't, first
because ggCheckArgs is striktly needed in these cases, second you should
allow 0 in b, third you should test for the algorithmic complexity; this is
only an arbitrary snapshot!) but also I hope you give an analysis of the
different algorithms giving the causes why one or the other algorithm is
superior, and when.

Now considering the example in Help:

In[2]:= s = {a, b, c, d, e, f, g, h, i, j};
In[3]:= t = {2, 3, 0, 4, 1};
 
In[4]:=
ggCheckArgs[s_, t_] := 
  Head[s] === List && VectorQ[t, Head[#] === Integer && # >= 0 &] && 
    Plus @@ t <= Length[s]

In[5]:=
gg[s_, t_] /; ggCheckArgs[s, t] := 
  First /@ Rest[FoldList[Through[{Take, Drop}[#1[[2]], #2]] &, {{}, s}, t]]

I like this algorithm, because it has a clear idea and gives a direct of it.
This is all that should be requested from an example.

Look at the kernel of this algorithm:

In[6]:=
FoldList[Through[{Take, Drop}[#1[[2]], #2]] &, {{}, s}, t]
Out[6]= {{{}, {a, b, c, d, e, f, g, h, i, j}}, 
         {{a, b}, {c, d, e, f, g, h, i, j}}, 
         {{c, d, e}, {f, g, h, i, j}}, 
         {{}, {f, g, h, i, j}}, 
         {{f, g, h, i}, {j}}, 
         {{j}, {}}}

Isn't this pretty?

Here a mild variation:

In[7]:= Remove[ggCheckArgs]
In[8]:=
ggCheckArgs[s_List, {tt__Integer?NonNegative}] := Plus[tt] <= Length[s]
In[9]:=
gg[s_, t_] /; ggCheckArgs[s, t] := 
  Rest[FoldList[Through[{Take, Drop}[#1[[2]], #2]] &, {{}, s}, t]][[All, 1]]

In[10]:= gg[s, t]
Out[10]=
{{a, b}, {c, d, e}, {}, {f, g, h, i}, {j}}
 

No some work for you:

In[13]:= gg0[s_, t_] := 
  Module[{r = {}}, Fold[(AppendTo[r, Take[#1, #2]]; Drop[#1, #2]) &, s, t];
r]

(another mild variation of gg)

 

In[15]:= gg1[s_, t_] :=
  Module[{l = FoldList[Plus, 1, t]},
    Take[s, #] & /@ Transpose[{Drop[l, -1], Drop[l - 1, 1]}]
    ]
 


In[17]:= Off[Take::"seqs"]
In[18]:= gg2[s_, t_] :=
  Module[{l = FoldList[Plus, 1, t]},
    Thread[Take[s, Transpose[{Drop[l, -1], Drop[l - 1, 1]}]], List, -1]
    ]


 
In[20]:= On[Take::"seqs"]
In[21]:= gg3[s_, t_] :=
  Module[{l = FoldList[Plus, 1, t]},
    With[{r = Transpose[{Drop[l, -1], Drop[l - 1, 1]}]}, 
      Thread[Unevaluated[Take[s, r]], List, -1]]
    ]

 

In[23]:= gg4[s_, t_] := Module[{c = 0},
    Map[Take[s, {c + 1, c = c + #}] &, t]]

 

In[25]:= gg5[s_, t_] := Module[{c = 0},
    MapThread[Take[#2, {c + 1, c = c + #1}] &, {t, Table[s, {Length[t]}]}]]

 

In[27]:= gg6[s_, t_] := Module[{c = 0, f},
    Thread[f[s, t], List, -1] /. f -> (Take[#1, {c + 1, c = c + #2}] &)]

 

In[29]:= gg7a[s_, t_] := 
  Module[{c1, c2 = 1, c3 = 1, e2 = Length[t], r, h, rr}, rr = h[];
    While[c2 < e2, c1 = t[[c2++]]; r = {}; 
      While[c1-- > 0, r = {r, s[[c3++]]}]; rr = h[rr, r]]; 
    List @@ Flatten /@ Flatten[rr, Infinity, h]]

 
In[33]:= gg7c[s_, t_] := 
  Module[{c1, c2 = 1, c3 = 1, e2 = Length[t], r, h, rr = {}},
    While[c2 < e2, c1 = t[[c2++]]; r = h[]; 
      While[c1-- > 0, r = h[r, s[[c3++]]]]; 
      rr = {rr, Flatten[r, Infinity, h]}]; Flatten[rr] /. h -> List]

 

In[35]:= gg8c[s_, t_] := 
  Module[{c1, c3 = 1, r, h, rr = {}},
    Scan[(c1 = #; r = h[]; While[c1-- > 0, r = h[r, s[[c3++]]]]; 
          rr = {rr, Flatten[r, Infinity, h]}) &, t]; Flatten[rr] /. h ->
List]

 

In[42]:= gg8e[s_, t_] := Module[{c1, c3 = 1, r, h, rr = Sequence[]},
    Scan[(c1 = #; r = h[]; While[c1-- > 0, r = h[r, s[[c3++]]]]; 
          rr = h[rr, {r}]) &, t]; Block[{h = Sequence}, {rr}]]

 

In[53]:= gg9b[s_, t_] := 
  With[{ll = Range[Length[t]]}, 
    Cases[
      Transpose[{Flatten[Table[#,{t[[#]]}]&/@ll], s}],{#, e_}:>e]&/@ll]
 


In[58]:= gg10[s_, t_] := 
  With[{pp = Table[Unique[Unevaluated[p]], {#}] & /@ t}, 
    Replace[s, Pattern[#, Blank[]] & /@ Flatten[pp] -> pp]]

(This possibly will not work with your generated test data, but it is
obvious, how to repair it! (It works with s and t above).)


 
In[64]:= gg11x[s_, t_] := 
  Flatten /@ 
    Split[Insert[s, {}, List /@ Rest[FoldList[Plus, 1, t]]], #1 =!= {} &]

 


In[68]:= gg11[s_, t_] := 
  ReleaseHold[
    Split[Insert[s, Hold[], 
        List /@ Rest[FoldList[Plus, 1, t]]], #1 =!= Hold[] &]]


There are a thousend more variations. Good luck!

--
Hartmut



  • Prev by Date: RE: Re: A friendly challenge: Generalized Partition
  • Next by Date: Re: Nonlinear Programming?
  • Previous by thread: RE: Re: A friendly challenge: Generalized Partition
  • Next by thread: RE: Re: A friendly challenge: Generalized Partition