# Values of sequenced IntegerDigits lists with two fixed elements

How can we access to all values of an IntegerDigits list with a special condition. This restriction is the locality of 0 or 1 in two special places.

For example if we want to have two 1s in the first and fourth places of sequenced IntegerDigits lists containing six digits, the ordered desired values are 9, 11, 13, 15, 25, 27, 31, 41 .... How can we obtain this ordered values?

FromDigits[{0,0,1,0,0,1},2]=9;
FromDigits[{0,0,1,0,1,1},2]=11;
FromDigits[{0,0,1,1,0,1},2]=13;
FromDigits[{0,0,1,1,1,1},2]=15;
FromDigits[{0,1,1,0,0,1},2]=25;
FromDigits[{0,1,1,0,1,1},2]=27;
FromDigits[{0,1,1,1,1,1},2]=31;
FromDigits[{1,0,1,0,0,1},2]=41;
and so on


nbits = 6
ranges = ConstantArray[{0, 1}, nbits]
rangeRestrictions = {-1 -> {1}, -4 -> {1}}
restrictedRanges = ReplacePart[ranges, rangeRestrictions]
FromDigits[#, 2] & /@ Tuples[restrictedRanges]

• What is all supposed to be? Jul 14, 2017 at 16:32
• @CarlWoll Fixed typo.
– Alan
Jul 14, 2017 at 16:33
• Very interesting and intelligent Jul 14, 2017 at 17:10
• Thank you for reminding. For keeping motivation for more answers, I think we should wait a bit more. However these answers from you, Carl, and kglr are atisfactory. Jul 14, 2017 at 20:05

I would use Quotient/Mod:

list[n_] := 16 Quotient[Range[0,n],4] + 2 Mod[Range[0,n],4] + 9
list[15]


{9, 11, 13, 15, 25, 27, 29, 31, 41, 43, 45, 47, 57, 59, 61, 63}

The Mod operation drops all but the last two binary digits, and then shifts left by 1 binary digit. The Quotient operation drops the last 2 binary digits, and then shifts left by 4 binary digits. Finally, adding 9 sets the 1st and 4th digits. Verification:

Column @ IntegerDigits[list[15], 2, 6] //TeXForm


$\begin{array}{l} \{0,0,1,0,0,1\} \\ \{0,0,1,0,1,1\} \\ \{0,0,1,1,0,1\} \\ \{0,0,1,1,1,1\} \\ \{0,1,1,0,0,1\} \\ \{0,1,1,0,1,1\} \\ \{0,1,1,1,0,1\} \\ \{0,1,1,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,0,0,1\} \\ \{1,1,1,0,1,1\} \\ \{1,1,1,1,0,1\} \\ \{1,1,1,1,1,1\} \\ \end{array}$

Another possibility is to use bit operations:

list2[n_] := BitOr[
BitShiftLeft[BitAnd[Range[0,n], BitNot[3]], 2] + BitShiftLeft[BitAnd[Range[0,n], 3], 1],
9
]


Check:

list[100] == list2[100]


True

Simple brute force approach for variable columns

Since you are interested in varying the column indices to fix, another idea is to set all the columns to 1, and then delete duplicates:

list3[cols_, n_] := DeleteDuplicates @ BitOr[
Total[2^(cols-1)],
Range[0, 2^Length[cols]n]
]


list3[{1,5}, 20]


{17, 19, 21, 23, 25, 27, 29, 31, 49, 51, 53, 55, 57, 59, 61, 63, 81, 83, 85, \ 87, 89, 91, 93, 95}

• There is a major problem: Please focus on {0, 0, 0, 1, 0, 0, 0, 1} : 8 digits with two 1s in the first and fifth positions. I used list[n_] := 64* Quotient[Range[0, n], 4] + 2 Mod[Range[0, n], 4] + 17 but the list[255] does not finish to {1,1,1,1,1,1,1,1}!? Jul 14, 2017 at 17:01
• Unfortunately I have to say this does not work correctly. Jul 14, 2017 at 17:07
• list[n_] := 32*Quotient[Range[0, n], 8] + 2 Mod[Range[0, n], 8] + 17 works for me. What sets of columns are you interested in? Jul 14, 2017 at 17:09
• Instead of 32 I put 64 erroneously! Jul 14, 2017 at 17:13

Using the magic numbers (2, 4 6) from @Carl's answer

ClearAll[constrainedIntegers]
constrainedIntegers[cols_, n_] := FromDigits[IntegerDigits[Plus@@(2^(cols - 1)), 2], 2] +
QuotientRemainder[Range[0, n], 4].{16, 2}


Examples:

constrainedIntegers[{1, 4}, 15]


{9, 11, 13, 15, 25, 27, 29, 31, 41, 43, 45, 47, 57, 59, 61, 63}

constrainedIntegers[{1, 3, 5}, 15]


{21, 23, 25, 27, 37, 39, 41, 43, 53, 55, 57, 59, 69, 71, 73, 75}

constrainedIntegers[{3, 9}, 15]


{260, 262, 264, 266, 276, 278, 280, 282, 292, 294, 296, 298, 308, 310, 312, 314}