简体   繁体   中英

how to find three identical values in a row in python

Suppose that random numbers are selected one at a time with replacement from among the set 0, 1, 2, ..., 8, 9. Use 10,000 simulations to estimate the average number of values required to select three identical values in a row.

Here is the code I tried:

import numpy as np

newlist = 0*[0]
ct = 0
set = [0,1,2,3,4,5,6,7,8,9]
random = np.random.choice(set, size=1)
for i in range(10000):
    if random == random:
        ct +=1
        while ct == 3:
            newlist.append()
print(random)

I think this is what you are trying to do. The code runs the test 10000 times and when the last three values are equal we append the number of iterations it took to the results and continue to the next loop:

import numpy as np
from collections import deque

results = []
number_selection = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

for _ in range(10000):
    _iterations = 1
    d = deque(maxlen=3)

    while True:
        random_value = np.random.choice(number_selection, size=1)
        if len(d) == 3 and len(set(d)) == 1:  # if last three items added to deque were equal we add the number of iterations to results and break to next loop
            results.append(_iterations)
            break  # break the while loop

        _iterations += 1
        d.append(random_value.item())

print('Average is: {0}'.format(float(sum(results)) / max(len(results), 1)))

Hope this helps!

Algorithm

  1. Generate a window of 3 randomly selected items from your set
  2. Initialize a counter that will hold the number of times an equality of 3 items is found
  3. At each iteration, shift the window to the left and add a new randomly selected item
  4. If all items in the window are equal, increment the counter
  5. Repeat 3 and 4 until you finished 10000 simulations

Code

import random

# [1, 2, 3] + 4 => [2, 3, 4]
def shift_left(arr, new_value):
    arr[0:len(arr) - 1] = arr[1:len(arr)]
    arr[len(arr) - 1] = new_value
    return arr

# [1, 1, 1] => True | [1, 2, 3] => False
def all_equal(window):
    for j in range(len(window) - 1):
        if window[j] != window[j+1]:
            return False
    return True

# Where real work happens
def avg(number_of_simulations, row_size, possible):
    number_of_equals = 0
    window = [random.choice(possible) for _ in range(row_size)] # window generation
    if all_equal(window):
        number_of_equals += 1

    for i in range(number_of_simulations - row_size):
        # Add new random number AND remove number from 3 iterations before
        window = shift_left(window, random.choice(possible))
        if all_equal(window):
            number_of_equals += 1 # Increment if all items are equal

    return number_of_equals

if __name__ == '__main__':
    possible_values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    number_of_simulations = 10000
    row_size = 3
    answer = avg(number_of_simulations, row_size, possible_values)
    print(f'Found {answer} among {number_of_simulations}')

how about:

opts = list(range(9))

# simulate once
def get_three(): 
    c = 1
    x = np.random.choice(opts, 1)
    i = 1
    while c < 3:
        x1 = np.random.choice(opts, 1)
        if x == x1:
            c += 1
        else:
            x = x1
            c = 1
        i += 1
    return i

# simulate n times
n = 10000 
result = sum([get_three() for i in range(n)]) / n
result # 90.5146

Theoretically you should expect the expected value to be n * 1/n^3 which is 1/n^2 , given that you have n numbers in your initial list. For simulating it, I would go for the following:

import numpy as np

count = 0
num_iterations = 1000
numbers = [0,1,2,3,4,5,6,7,8,9]
for _ in range(num_iterations):
    if len(set(np.random.choice(numbers, 3, replace=True))) == 1:
        count += 1

print("Avg is {}".format(count/num_iterations))

Explanation:

Since numpy.choice with replacement uniformly selects three members from numbers , the case of three consecutive choices of the same number is equivalent to having a set with cardinality of 1. If you increase num_iterations to something around 10000, you would see that it simulates the case with an acceptable precision (the average would be around 0.01) which is expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM