Похоже, вы могли бы просто брать x = ceil (log_2 (n)) бит за раз и просто использовать их в качестве случайных чисел. Проблема, с которой вы столкнетесь, заключается в том, что если число, которое вы получаете, превышает ваш лимит (например, 5), то вы захотите выполнить магию, чтобы получить его меньше 5, но равномерно. В этом случае, что кажется логичным, это то, что вы бы просто взяли еще x битов, но, поскольку вы указали, что мы не можем тратить биты, нам нужно быть более креативными. Я бы порекомендовал повернуть вправо или влево, но это не всегда поможет вам выйти из ситуации. (Рассмотрим строку из 111, когда вы хотели n = 5). Мы могли бы сделать до x
поворотов, чтобы посмотреть, приведет ли один из поворотов к правильному диапазону, или мы могли бы просто перевернуть все биты и добавить 1 (дополнение к двум). Я верю, что это сделает его единообразным.
Так, например, если у вас была следующая строка (самый правый бит - первый, который вы получили):
101001111010010101
И вы используете n = 5, затем ceil (log2 (n)) = 3, так что вы будете использовать три бита за раз, и ваши результаты (на каждом временном шаге) будут следующими:
t=0 : 101 = 5
t=1: 010 = 2
t=2: 010 = 2
t=3: 111 = 7 -> too large, rotates won't work, so we use 2's complement: 001 = 1
t=4: 001 = 1
t=5: 101 = 5