5
$\begingroup$
 (* P1comb = f[P1]; *) P1comb = f[P1] - Count[{ }, P1]; P2comb = f[P2] - Count[{P1}, P2]; B1comb = f[B1] - Count[{P1, P2}, B1]; B2comb = f[B2] - Count[{P1, P2, B1}, B2]; P3comb = f[P3] - Count[{P1, P2, B1, B2}, P3]; B3comb = f[B3] - Count[{P1, P2, B1, B2, P3}, B3]; 

I am writing the above code, which works perfectly fine. Then I noticed a pattern, so I am just wondering if I might be able to write it better (more compactly) and more efficient using something like FoldList or NestList combined with a pure function, like

FoldList/NestList [] & {P1,P2,B1,B2,P3,B3} 

Thanks.

$\endgroup$

3 Answers 3

5
$\begingroup$

You might consider using FoldPairList:

Column[ FoldPairList[{f[#2] - count[#, #2], Append[#, #2]} &, {}, {P1, P2, B1,B2, P3, B3}] ] 

Mathematica graphics

I have replaced Count with count to display the expression.

It would also commonly be done like this:

elems = {P1, P2, B1, B2, P3, B3}; lists = Most@FoldList[Append, {}, elems]; MapThread[f[#] - count[#2, #] &, {elems, lists}] // Column 

Mathematica graphics

$\endgroup$
2
  • $\begingroup$ Thanks for both methods. I'd prefer to use the 1st one as it looks more compact! :) $\endgroup$ Commented Jun 18, 2018 at 1:21
  • $\begingroup$ Weirdly, after putting it into my big function, it used double of the execution time. I think it might be caused by Append? But don't worry. That's not really the point here. $\endgroup$ Commented Jun 18, 2018 at 1:25
2
$\begingroup$

Here is an example that avoids Append, but does pre-generate the partial sublists from your list:

list = {P1, P2, B1, B2, P3, B3}; f[#1] - Inactive[Count][Reverse[{##2}], #1] & @@@ (Reverse[list[[;; #]]] & /@ Range[Length[list]]) (* Out: {f[P1] - Inactive[Count][{}, P1], f[P2] - Inactive[Count][{P1}, P2], f[B1] - Inactive[Count][{P1, P2}, B1], f[B2] - Inactive[Count][{P1, P2, B1}, B2], f[P3] - Inactive[Count][{P1, P2, B1, B2}, P3], f[B3] - Inactive[Count][{P1, P2, B1, B2, P3}, B3]} *) 

Mathematica graphics

Of course, you should remove the Inactive part in your actual code :-)


See also Any built-in function to generate successive sublists from a list? for alternative ways to generate the initial sublists.

$\endgroup$
2
$\begingroup$
Clear[P1, P2, B1, B2, P3, B3] Clear[P1comb, P2comb, B1comb, B2comb, P3comb, B3comb] a = {P1, P2, B1, B2, P3, B3}; b = {P1comb, P2comb, B1comb, B2comb, P3comb, B3comb}; 

Using lower-case count initially, to be replaced with Count

Array[With[{c = b[[#]]}, c = f[a[[#]]] - count[Take[a, # - 1], a[[#]]]] &, Length[a]] 

Examples

P1comb 
-count[{}, P1] + f[P1] 
B3comb 
-count[{P1, P2, B1, B2, P3}, B3] + f[B3] 

Assigning values after symbolic construction.

With[{d = a}, d = {1, 2, 3, 4, 3, 2}]; B2 
4 
b /. count -> Count 
{f[1], f[2], f[3], f[4], -1 + f[3], -1 + f[2]} 
$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.