0
$\begingroup$

I want to make a list of x zeroes and y ones in random locations. It feels like this should be doable in Mathematica in a very few characters, but my solution (which works perfectly) is relatively verbose.

I'm here using 0 and 1 rather than False and True.

exactlyNOnes[n_Integer, outOf_Integer] := Module[{list, rands},
   list = Table[0, outOf];
   While[Total[list] < n, 
    list = ReplacePart[list, RandomInteger[outOf - 1] + 1 -> 1]];
   list
   ];

I'm curious to know how wiser people would solve this.

$\endgroup$
2
  • 5
    $\begingroup$ You could use RandomSample, something like: RandomSample @ Join[ConstantArray[1, n], ConstantArray[0, m]]. $\endgroup$
    – Carl Woll
    Commented Mar 6, 2023 at 2:51
  • $\begingroup$ @CarlWoll That's the most elegant solution here. If you make it an answer, I'll accept it. $\endgroup$ Commented Mar 7, 2023 at 3:30

1 Answer 1

1
$\begingroup$

Here is a (comparison of two) solutions for relatively small x+y, that I can think of.

x = 7; (* seven ones *)
y = 2; (* two zeros *)

Generate an exhaustive list and Select (36 cases):

alist = IntegerDigits[#, 2, x + y] &@Range[0, 2^(x + y) - 1];
res1 = Select[Count[#, 1] == x && Count[#, 0] == y &][alist]

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


The other solution is based on Subsets and using ReplacePart for direct replacements:

replacements = Thread[# -> 0] & /@ Subsets[Range[x + y], {y}]

res2 = ReplacePart[ConstantArray[1, x + y], #] & /@ replacements // 
  Sort

res1 == res2

True

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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