2

Suppose their is a while loop running 6 times. It gives a random number in a range of 1 to 10 each time. I want that all the 6 times two adjacent number should not be equal.

Means output should look like 4, 5, 10, 6, 1, 6 where all adjacent number are different

not like this 4, 4, 5, 10, 1 because first two adjacent number are same this is my code

5 Answers 5

3

this is an option: you store the previous random value and roll the dice again if the new random value r equals the previous one prev:

from random import randint

ret = []
prev = None

for _ in range(6):
    r = randint(1, 10)
    while r == prev:
        r = randint(1, 10)
    prev = r
    ret.append(r)

print(ret)

using the walrus operator you could save one line (not sure if that is more readable, though...):

for _ in range(6):
    while (r := randint(1, 10)) == prev:
        pass
    prev = r
    ret.append(r)
Sign up to request clarification or add additional context in comments.

Comments

2

You need the second loop to check if the new number generated is equal to previous or not, if they are equal generate the number again until they are unequal, and break the inner loop when they are unequal.

from random import randint

i = 1
while i<=20:
    if i==1:
        num = randint(1,10)
    else:
        while True:
            new = randint(1,10)
            if new!=num:
                num = new
                break
    print(num)
    i += 1   

#output:   
6
5
9
6
8
7

2 Comments

There are several issues with this code. For one. Counter is not defined.
@KatinkaHesselink, Thanks for the edit, I was actually trying a different approach, but then I decided to use the same code as OP has mentioned.
2

Another way of doing this is to notice that you condition excludes one option, e.g.: if the previous item was 7, then it only makes sense to choose one of the remaining 9 options. Hence make the max = 9, and add one if the variate is equal to or greater than 7.

For example:

from typing import List
from random import randint

def randseq_nondup(a: int, b: int, k: int) -> List[int]:
    """Generate k random values in [a,b], i.e. inclusive.
    
    Ensures that subsequent values are never the same.
    """
    result = [randint(a, b)]
    for _ in range(k-1):
        i = randint(a, b-1)
        # add one when appropriate to keep values distinct
        i += i >= result[-1]
        result.append(i)
    return result

For example, randseq_nondup(0, 9, 6) gives:

[1, 0, 5, 3, 4, 2]

when the RNG seeded with 42.


Some clarification for hiro:

This gives the same result as the other rejection sampling based approaches, but can be more efficient. Specifically it'll get more efficient as the as the number of options deceases, because there's a higher chance of randomly choosing the same value twice and the other approaches having to loop around and draw another value from the RNG.

Also, the probability of picking any value is only 1/10 the first time around, every time after that you can't pick the same value again so the probability of any specific value goes up to 1/9 (this is what the rejection is doing).

The way this algorithm shuffles up based on >= (e.g. rather than just ==) means that the resulting distribution is uniform. For example, imagine the first time we picked 4 the adjustment would work as follows:

before :  0  1  2  3  4  5  6  7  8
after  :  0  1  2  3  5  6  7  8  9

notice that every value is uniquely mapped to a value (i.e. it's a bijection). So this algorithm will give uniform variates if the underlying RNG is uniform (the same as the rejection sampling based approaches).

3 Comments

@hiroprotagonist I'm not sure why you think it's got a bias. This is a pretty standard way of sampling with this constraint, maybe you could explain?
@hiroprotagonist have tried to explain what's going on
oh. i missed the >=. sorry, my bad! thanks for adding the details. that is indeed better than my approach. +1.
1

The function/utility you are looking for is random.sample(). It returns a list of random distinct n numbers that are in the specified range.

The code you are looking for is as below-

import random
l = random.sample(range(1, 11), 6)

This code will generate 6 numbers that are between 1 and 10, and each number will be distinct from each other.

1 Comment

this will generate 6 distinct numbers. that is not what the OP wants. only adjacent numbers must not be equal.
1

The easiest way to do this is to use a placeholder variable for the previous number and to continuously randomly pick a number until it is not the same as the previous/adjacent number.

import random

# Initialise previous number holder as a number that is out of scope.
previous_num=11

# Initialise output number to be the same to trigger the loop.
num = 11

for _ in range(6):
    # Loop until the output number is not the same as the previous number.
    while num == previous_num:
        num = random.randint(1,10)
        
    # Set the previous number to the current number.  
    previous_num = num
    
    # Output the current number.
    print(num)

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.