Skip to main content

list manipulation - Listing all monotone increasing binary digits



For $n=5$, I have $32$ binary digits and for this there are $2^{32}$ combinations. Out of this many, the interesting ones (i.e., the ones that have monotone increasing binary digits) are only about "$2111$". I know how these can be found very easily but I am missing Mathematica knowledge. Therefore I cannot complete my program.


First I need to seperate these $32$ bits according to Pascals triangle numbers. Since $n=5$, these numbers are $1,5,10,10,5,1$. Their sum is $32$ and I separate the digits accordingly. My list is as follows:


List={

{0|00000|0000000000|0000000000|00000|0}

... those who satisfy the rule below

{1|11111|1111111111|1111111111|11111|1}}


From right to the left I start with the 5 bits and take all possible combinations:


|00000|--> 00001,00010,00011...11111

This says I have the following ones in the list


{0|00000|0000000000|0000000000|00001|1,    
0|00000|0000000000|0000000000|00010|1,
0|00000|0000000000|0000000000|00011|1,...,
0|00000|0000000000|0000000000|11111|1}

Then I go left via keeping |11111|1 as fixed. Now I have $10$ digits and the following are the elements of the list



{0|00000|0000000000|0000000001|11111|1,    
0|00000|0000000000|0000000010|11111|1,
0|00000|0000000000|0000000011|11111|1,...,
0|00000|0000000000|1111111111|11111|1}

Then, I do the same thing again but fixing |1111111111|11111|1. Then the followings are the elements of the set:


{0|00000|0000000000|1111111111|11111|1,    
0|00000|0000000001|1111111111|11111|1,
0|00000|0000000010|1111111111|11111|1,...,
0|00000|1111111111|1111111111|11111|1}


Again the same thing and we are done:


{0|00001|1111111111|1111111111|11111|1,    
0|00010|1111111111|1111111111|11111|1,
0|00011|1111111111|1111111111|11111|1,...,
0|11111|1111111111|1111111111|11111|1}

So in total there are $2^5$ numbers from the first stage, From the other two stages we have $2^{10}-1$ for each and for the last stage $2^5-1$ numbers. We also have all zeros and all ones and if I calculated correctly there are $2111$ of them. I used the character "|" for separation. The final list should look like


List={{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},....,{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}}


I only have the following code part:


IntegerDigits[2, 2, 5]
{0, 0, 0, 1, 0}

IntegerDigits[2, 2, 10]
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0}

Using this code in a 'for loop' I can obtain such combinations but I must concatenate these to the previous bits which are all zeros and all subsequent bits which are all 1s. This is what I don't know how to do.



Answer



One idea is to make use of Tuples:



monotoneTuples[b_, m_, e_] := Rest @ Tuples@Join[
ConstantArray[{0}, b],
ConstantArray[{0,1}, m],
ConstantArray[{1}, e]
]

monotoneTuples will create your partitioned set. For example:


Column @ monotoneTuples[5, 3, 1] //TeXForm



$\begin{array}{l} \{0,0,0,0,0,0,0,1,1\} \\ \{0,0,0,0,0,0,1,0,1\} \\ \{0,0,0,0,0,0,1,1,1\} \\ \{0,0,0,0,0,1,0,0,1\} \\ \{0,0,0,0,0,1,0,1,1\} \\ \{0,0,0,0,0,1,1,0,1\} \\ \{0,0,0,0,0,1,1,1,1\} \\ \end{array}$



Then, you can join each of these sets:


res = Join[
monotoneTuples[31,1,0],
monotoneTuples[26,5,1],
monotoneTuples[16,10,6],
monotoneTuples[6,10,16],
monotoneTuples[1,5,26],
monotoneTuples[0,1,31]

];
res //Length


2110



Addendum


For memory reasons, it makes sense to create a list of integers instead of a list of bit vectors, especially if you will be creating a lot of them. So, an alternative is:


monotoneIntegers[list_] := With[{a = Accumulate[Prepend[0] @ Most @ Reverse @ list]},
Prepend[0][Join @@ (Range[2, 2^Reverse@list] 2^a - 1)]

]

For example, compare:


integers = monotoneIntegers[{1,3,2}]
bitvectors = IntegerDigits[%, 2, 6]


{0, 1, 2, 3, 7, 11, 15, 19, 23, 27, 31, 63}


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




The memory usage of the integers is much less:


ByteCount @ integers
ByteCount @ bitvectors


200


1968



and the disparity increases with more bits.


Comments

Popular posts from this blog

plotting - How to draw lines between specified dots on ListPlot?

I would like to create a plot where I have unconnected dots and some connected. So far, I have figured out how to draw the dots. My code is the following: ListPlot[{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4,13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full] I have thought using ListLinePlot command, but I don't know how to specify to the command to draw only selected lines between the dots. Do have any suggestions/hints on how to do that? Thank you. Answer One possibility would be to use Epilog with Line : ListPlot[ {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4, 13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full, Epilog -> { Line[ ...

dynamic - How can I make a clickable ArrayPlot that returns input?

I would like to create a dynamic ArrayPlot so that the rectangles, when clicked, provide the input. Can I use ArrayPlot for this? Or is there something else I should have to use? Answer ArrayPlot is much more than just a simple array like Grid : it represents a ranged 2D dataset, and its visualization can be finetuned by options like DataReversed and DataRange . These features make it quite complicated to reproduce the same layout and order with Grid . Here I offer AnnotatedArrayPlot which comes in handy when your dataset is more than just a flat 2D array. The dynamic interface allows highlighting individual cells and possibly interacting with them. AnnotatedArrayPlot works the same way as ArrayPlot and accepts the same options plus Enabled , HighlightCoordinates , HighlightStyle and HighlightElementFunction . data = {{Missing["HasSomeMoreData"], GrayLevel[ 1], {RGBColor[0, 1, 1], RGBColor[0, 0, 1], GrayLevel[1]}, RGBColor[0, 1, 0]}, {GrayLevel[0], GrayLevel...

list manipulation - Selecting multiple columns from a matrix?

Sample data: data = { {{2013, 1, 1}, 24.13, 167.67, 231.82}, {{2013, 1, 2}, 32.15, 170.92, 225.99}, {{2013, 1, 3}, 35.43, 172.68, 221.67}, {{2013, 1, 4}, 36.73, 173.05, 218.32}, {{2013, 1, 5}, 58.19, 165.96, 197.05}, {{2013, 1, 6}, 69.99, 163.50, 187.52}, {{2013, 1, 7}, 71.37, 154.21, 175.58}, {{2013, 1, 8}, 72.51, 149.66, 163.25}}; I want a DateListPlot with three graphs, so for a matrix formed by columns 1 and 2, one for columns 1 and 3, and 1 for columns 1 and 4. At the moment I'm using this code: data2 = Transpose[{data[[All, 1]], data[[All, 2]]}]; data3 = Transpose[{data[[All, 1]], data[[All, 3]]}]; data4 = Transpose[{data[[All, 1]], data[[All, 4]]}]; DateListPlot[{data2, data3, data4}, Joined -> True, Filling -> {3 -> {1}}] but I have a hunch that this can be done more efficiently. I don't like the Transpose s in particular. Any ideas? edit (for extra credit) What if I need to multiply the second column by 2, which in my solution is simp...