lundi 2 octobre 2023

C-Sharp -- Generating random integers from nonrandom seeds

I'm making a game, and every now and then a number of objects in the game need to know whether or not the player has moved. Because of the large numbers of objects involved, instead of alerting every object every frame, I've sorted them into bins with corresponding events. Bin 1 is alerted the first frame the player moves, then bin 2 the second frame, etc, up to some finite number.

However, I need some consistent way to assign each object a bin. Just using the object ids isn't working, as the way that the objects are generated gives patterns in their ids that may result in some bins being filled more or less than others, which decreases the gains in efficiency. If all the ids are even and so is the bin size, then only the even bins will be filled.

In short, the problem is this:

Given a sequence of non-random, unknown, unique integers S that may or may not have a pattern, how can I choose a hashing algorithm H and number of bins p so that H(S[i]) % p forms a roughly uniform distribution?

Simply choosing a prime number as the number of bins seems to be a good start, but I'm wondering if there's a hashing algorithm I can use to "scramble" the patterns of the input sequence and improve uniformity. Ideally, one already included in .Net.

Edit:

I've found some promising results in this answer. I'm still curious about this problem though, both from a mathematical perspective and whether there are tools to do this included in .NET.




Stop function random number

i want stop this function with a button, what can i do for that working ?

Thanks

var module = angular.module('numberApp', []);

module.controller('NumberController', function($scope, $timeout) {
    (function update() {
    $timeout(update, 1000 * 15);
    $scope.randomNumber = Math.floor(Math.random()*($scope.max-$scope.min+1)+$scope.min);
  }());

please help me to stop this function with a button ;-)




dimanche 1 octobre 2023

How can I generate a Bernoulli random integer array in rust?

I am trying to create a random 2D array in which each entry is 0 with probability p and 1 otherwise. In python, numpy makes it simple:

rand_arr = (np.random.rand(nrows, ncols) < p).astype(np.dtype('uint8'))

In rust, I wrote something like this

use rand::Rng;
use rand::distributions::Bernoulli;
use ndarray::{Array2};

// Create a random number generator
let mut rng = rand::thread_rng();

// Create a Bernoulli distribution with the given probability
let bernoulli = Bernoulli::new(p).unwrap();

// Generate a 2D array of random boolean values using the Bernoulli distribution
let rand_arr: Array2<bool> = Array2::from_shape_fn((nrows, ncols), |_| {
    rng.sample(bernoulli)

// convert bools to 0 and 1
let rand_arr = data_round_errors.mapv(|b| if b { 1 } else { 0 });
});

This is awfully slow. About 30 times slower than the python version! Which tells me I am doing something wrong. How can I write a faster implementation of this?




Determine different seeds for which random shuffling list generates the same output

It is pretty intuitive that when shuffling a small enough collection, results will repeat themselves, even using different seeds each time, as it is just a matter of exhausting all unique combinations.

However, I can't find such information in the Python documentation. I am especially curious if there is any formula or algorithm to determine the different seed values for which the output would be identical. Is it possible to somehow forecast or calculate these seeds?

At first sight, I couldn't see any pattern or regular offset, and now it intrigues me if it's possible to find one 😁

I'm pasting the snippet of the code that I reproduced several times on my machine and within the online REPL.

import random

a = ["a", "b", "c", "d", "e"]
b = list(a)
c = list(a)

random.seed(0)
random.shuffle(a)
random.seed(344)
random.shuffle(b)
random.seed(496)
random.shuffle(c)

print(a == b == c == ["c", "b", "a", "e", "d"])  # True



how to compare user input for a password that matches a randomized challange response password?

im creating a code that asks the user to input their password as digits from a randomly generated string of digits between 1 and 3 that is beneath.

for example,

pin: 0 1 2 3 4 5 6 7 8 9

ran: 1 2 2 3 1 2 1 3 2 1

if the user's password is 56789, they would need to enter 21321

import random

# Store the actual PIN as a list of integers
pin = [5, 6, 7, 8, 9]

# Generate random numbers for digits 0 to 9
randNumbers = [random.randint(1, 3) for x in range(10)]

# Create lists to map random numbers to digits
random_to_digit = [None, '0', '1', '2']

# Output digits 0-9 in a single line
print("PIN:", end=' ')
for i in range(10):
    print(i, end=' ')

# Output the corresponding random digits below in a single line
print("\nNUM:", end=' ')
for i in range(10):
    print(random_to_digit[randNumbers[i]], end=' ')

# Request and get the input response from the user
pwdEntry = input("\nPlease enter your converted password: ")

if pwdEntry[0] == randNumbers[5] and pwdEntry[1] == randNumbers[6] and pwdEntry[2] == randNumbers[7] and pwdEntry[3] == randNumbers[8] and pwdEntry[4] == randNumbers[9]:
    print("success")
else:
    print("failure")

i tried comparing each item the user entered to the position in the list that the correct digit they would need to enter since the password 56789 is constant but it always results in failure.




Why does the range element in my code have problems when is uses the last number?

I am using the following code, which just selects a random number from a range and uses it as chance for other elements to be selected, and it works fine with no errors, but occasionally the number that it selects from the range(usually the last number like 16 or 20) does not work, and I don't know why.

Code:

import random

# List used for Age Classifications
ageClass = ["Newborn", "Young", "Aged", "Old", "Ancient", "Timeless"]
randAgeClass = ""
randAge = 0

# Probability of age classes
# Newer classes are much more likely to be selected than the older classes
chance = random.randrange(1, 20)
# Chance Debug
print(chance)

if chance in range(1, 5):
    randAgeClass = "Newborn"
elif chance in range(6, 10):
    randAgeClass = "Young"
elif chance in range(11, 13):
    randAgeClass = "Aged"
elif chance in range(14, 16):
    randAgeClass = "Old"
elif chance in range(17, 18):
    randAgeClass = "Ancient"
elif chance in range(19, 20):
    randAgeClass = "Timeless"
else:
    print("error")

# If statements for age classes
if randAgeClass == "Newborn":
    randAge = random.randrange(1, 20)
elif randAgeClass == "Young":
    randAge = random.randrange(21, 80)
elif randAgeClass == "Aged":
    randAge = random.randrange(81, 250)
elif randAgeClass == "Old":
    randAge = random.randrange(251, 500)
elif randAgeClass == "Ancient":
    randAge = random.randrange(501, 1000)
elif randAgeClass == "Timeless":
    randAge = random.randrange(1001, 6000)
else:
    print("error")

print("Vampire Name: Steve")
print("Age Classification:", randAgeClass)
print("Age:", randAge)

Here is how a successful output looks like: enter image description here

And here is how an unsuccessful output looks like: enter image description here

This only seems to be happening if the random number in the range that is chosen is the last number in the range like 5, 10, 16... Why is this happening and how do I fix this?

I tried using a list and that didn't work, so I would rather just use a range for this.




Generating unique random numbers from non-unique random numbers

The following function converts a list of non-unique random numbers into a list of unique random numbers using a helper list of sequential integers:

def get_d(rlist):
    # t[] is a list of ints 0..n-1 where n is big
    # enough not to cause issues when deleting items
    t  = list(range( len(rlist) + max(rlist) ))
    d  = []            # the output list we will populate
    for r in rlist:
        d.append(t[r]) # add r'th remaining item in t[] to d[]
        t.pop(r)       # delete that item from t[]
    return d

e.g.
get_d([3, 2, 3, 1, 5]) = [3, 2, 5, 1, 9]

I would like to get the same output using a counting method or other method. This is my attempt, which has some edge case or perhaps more fundamental issues:

def get_e(r):
    e = []
    for i,t in enumerate(r):
        c = 0
        # track numbers <= the current one
        for j in range(i):
            if r[j] <= t:
                c+=1
        # track numbers <= the current one when virtual deletions are accounted for
        for j in range(i):
            if r[j] > t and r[j]-c <= t:
                c+=1
        e.append(t+c)
    return e

Here is a test:

for r in [ [3,2,3,1,5], [0,0,1,0,0]]:
    d = get_d(r)
    e = get_e(r)
    print('match:   ' if d==e else 'mismatch:', r, '  : ',  d, '  ', e)


Output: 
match:    [3, 2, 3, 1, 5]   :  [3, 2, 5, 1, 9]    [3, 2, 5, 1, 9]
mismatch: [0, 0, 1, 0, 0]   :  [0, 1, 3, 2, 4]    [0, 1, 3, 3, 4]