# How to generate patterns by a list of integers

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.

-
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 _. –  praaeew Dec 29 '12 at 14:54
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? –  m_goldberg Dec 29 '12 at 17:49
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. –  Mr.Wizard Dec 29 '12 at 17:53
Also, how should a list {3, 4, 1, 2} be handled? –  Mr.Wizard Dec 29 '12 at 18:06
The integer in the list must be >=2. –  praaeew Dec 30 '12 at 2:45

## 2 Answers

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.

-
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.) –  praaeew Dec 30 '12 at 3:20
@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. –  Mr.Wizard Jan 1 '13 at 14:46

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}
}

-
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. –  Mr.Wizard Dec 29 '12 at 12:04