1
$\begingroup$

I have a list of integers {3,4,2,2}.

This list will give patterns {x_,_,y_,y_,_,_,z_,z_,w_,w_,x_} and {0,0,0,1,1,1,1,0,0,1,1}.

Notice that I want to assign successive 0,1 with the same symbol.

How to make this?

*edit

Compare the patterns

{x_,_,y_,y_,_,_,z_,z_,w_,w_,x_}
{0, 0, 0,1, 1,1, 1,0,  0,1, 1 }
{1, _, 2,2, _,_, 3,3,  4,4, 1 }

Suppose I have symbols {x_,y_,z_,w_} (you may use {a_,b_,c_,d_,...}).

To transform lst={3,4,2,2} to {x_,_,y_,y_,_,_,z_,z_,w_,w_,x_}, begin with {x_,_,_,_,_,_,_,_,_,_,_}.

Then put y_ at positions lst[[1]] and lst[[1]]+1.

Then put z_ at positions lst[[1]]+lst[[2]] and lst[[1]]+lst[[2]]+1.

Then put w_ at positions lst[[1]]+lst[[2]]+lst[[3]] and lst[[1]]+lst[[2]]+lst[[3]]+1.

And finally put x_ at the last position.

$\endgroup$
5
  • $\begingroup$ observe that when 0 is next to 1, assign them with the same symbol. If 0 is next to 0 (or 1 is next to 1), assign with _. $\endgroup$
    – praaeew
    Dec 29, 2012 at 14:54
  • $\begingroup$ Please tell us how you intend to use the pattern {x_,_,y_,y_,_,_,z_,z_,w_,w_,x_}? Also, how would you extend the symbol list it there were, say, 7 control integers rather than 4? $\endgroup$
    – m_goldberg
    Dec 29, 2012 at 17:49
  • $\begingroup$ praaeew, thanks for the update, which I finally understand. Would you please consider splitting that into a separate question? I think it deserves to be addressed on its own. $\endgroup$
    – Mr.Wizard
    Dec 29, 2012 at 17:53
  • $\begingroup$ Also, how should a list {3, 4, 1, 2} be handled? $\endgroup$
    – Mr.Wizard
    Dec 29, 2012 at 18:06
  • $\begingroup$ The integer in the list must be >=2. $\endgroup$
    – praaeew
    Dec 30, 2012 at 2:45

2 Answers 2

4
$\begingroup$

Like others I cannot follow the {x_,_,y_,y_,_,_,z_,z_,w_,w_,x_} part but for the integer sequence this problem is related to: How to apply or map a list of functions to a list of data?

Any of those solutions should be adaptable but for this particular application I like TomD's method the best. It is both concise and very fast.

f[pat : {__Integer}, rep_List] /; Min[pat] > 0 :=
  Join @@ ConstantArray @@@ Partition[Riffle[pat, rep, {1, -1, 2}], 2]

f[{3, 4, 2, 2}, {0, 1}]
{0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1}

Here is one that is a bit shorter and faster still:

f2[p : {__Integer}, r_List] /; Min[p] > 0 :=
  Inner[ConstantArray, PadRight[r, Length @ p, r], p, Join]

f2[{3, 4, 2, 2}, {0, 1}]
{0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1}

In response to your updated question you could use this:

lst = {3, 4, 2, 2};

ReplacePart[
 ConstantArray[_, Tr@lst],
 Prepend[
  {{#}, {# + 1}} -> (Pattern[#, _] &@Unique[]) & /@ Accumulate@lst,
  {{1}, {-1}} -> x_
 ]
]
{x_, _, $1_, $1_, _, _, $2_, $2_, $3_, $3_, x_}

This generates as many Unique symbols as required to fill out the list.

I still think this is distinct from the integer sequence result and should be split to a separate question. I also echo m_goldberg's question: "How do you intend to use the pattern?" as there may be another approach.

$\endgroup$
2
  • $\begingroup$ Actually, the problem is there are two copies of {1,2,3,4,5,6,7} named group 0 and group 1, and I want to arrange them as a cycle in which there are double digit 4 places. The list {3,4,4,3} separates group 0 and 1 by {0,0,0,1,1,1,1,0,0,0,0,1,1,1}. A valid arrangement is such as {1, 5, 2,2, 6,7, 3,3, 6,7, 4,4, 5, 1}. (sorry for asking {3,4,2,2} that is not compatible with real problem.) $\endgroup$
    – praaeew
    Dec 30, 2012 at 3:20
  • $\begingroup$ @praaeew I'm once again having trouble understanding you (we probably have a different way of thinking). If the update to my answer does not solve your problem, please post a new question with further clarification of the pattern you seek. $\endgroup$
    – Mr.Wizard
    Jan 1, 2013 at 14:46
2
$\begingroup$

One part of the question is easy -- constructing a sequence of ones and zeros according to a pattern given by a control list of integers:

binaryPattern[controlList : {_Integer ..}] := 
   Flatten@MapIndexed[
      If[EvenQ @@ #2, ConstantArray[1, #1], ConstantArray[0, #1]] &, controlList]

binaryPattern[{3, 4, 2, 2}]

{0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1}

binaryPattern[{1, 2, 3, 4}]

{0, 1, 1, 0, 0, 0, 1, 1, 1, 1}

About the other part, I haven't a clue of what the OP has in mind.

Edit

Slightly modifying the function Mr. Wizard defined in his comment to this answer, I present a function that produces sequences of digits from any base from two to ten. I confess I can think of no use case for this extended version.

nAryPattern[controlList : {__Integer}, base_Integer: 2] /; 11 > base > 1 := 
   Join @@ MapIndexed[ConstantArray[Mod[#2[[1]] - 1, base], #] & controlList]  

Table[nAryPattern[Range[5], base], {base, 2, 5}]

{
{0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0},
{0, 1, 1, 2, 2, 2, 0, 0, 0, 0, 1, 1, 1, 1, 1},
{0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 0, 0, 0, 0, 0},
{0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4}
}

$\endgroup$
1
  • $\begingroup$ I propose this extension: binaryPattern[ctrl : {__Integer}, m_Integer: 2] := Join @@ MapIndexed[Mod[#2[[1]] - 1, m] ~ConstantArray~ # &, ctrl] -- the second (optional) argument determines the length of the repeating cycle. This is also a bit faster and more concise. $\endgroup$
    – Mr.Wizard
    Dec 29, 2012 at 12:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.