[Tutor] Need help understanding output...
Steven D'Aprano
steve at pearwood.info
Wed Aug 18 23:24:24 CEST 2010
On Wed, 18 Aug 2010 09:21:51 pm Laurens Vets wrote:
> On 8/12/2010 1:26 AM, Steven D'Aprano wrote:
> > On Thu, 12 Aug 2010 07:04:15 am Laurens Vets wrote:
> >> I need to generate a list of 30 numbers randomly chosen from 1, 2,
> >> 3, 4, 5& 6. However, I cannot have more than 2 numbers which are
> >> the same next to each other.
[...]
> Thank you all for your help! I've added another condition to this
> program, namely, in a range of 60, each 'random' number can only
> occur 10 times. I came up with the following:
The more of these restrictions you add, the less random the sequence is.
A truly random (that is, uniformly random) sequence should come up with
30 identical numbers occasionally. *Very* occasionally, to be sure, but
it still should be possible.
If what you need is a sequence of numbers which is only slightly random,
then that's fine. But I don't fully understand what your aim is here.
Anyway, here's my take on generating 30 semi-random integers from 1 to 6
where there are no more than 10 of each number and no more than two in
a row of anything.
Completely untested:
def make_counts(total=30):
counts = {}
t = total
for i in range(1, 7):
n = random.randint(0, min(t, 10))
counts[i] = n
t -= n
assert sum(counts.values) == total # Is this guaranteed?
return counts
def make_seq():
result = []
counts = make_counts(30)
for i in range(30):
t = random.choose(counts.keys())
while [t] != result[-2:]
if len(counts) == 1 and counts.keys() == result[-2:]:
# Stuck!
raise ValueError
t = random.choose(counts.keys())
result.append(t)
counts[t] -= 1
if counts[t] == 0:
del counts[t]
return result
I'm a bit dubious about the assertion in make_counts... I think I need
to be a bit more clever about generating the counts to guarantee that
there will be exactly 30 in total. At the moment it only guarantees no
more than 30.
Note also the test inside the while loop in make_seq. Given your
additional restriction, it might happen that you have a sequence like
[blah blah... 3, 3] and 3 is the only remaining key in count. In that
case, the while loop will never terminate.
Another alternative is not to try to be clever at all. Instead, use a
nice simple rejection method:
* generate a list of thirty random numbers
* reject it if it has 3 numbers in a row, or more than 10 of any number
* if rejected, start again with a new random list
--
Steven D'Aprano
More information about the Tutor
mailing list