Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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.

share|improve this question
    
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
add comment

2 Answers

up vote 4 down vote accepted

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.

share|improve this answer
    
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
add comment

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

share|improve this answer
    
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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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