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

2

=================

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