Люди ужасно плохо справляются с придумыванием случайных чисел. Я хотел научиться быстро генерировать «достаточно случайные» числа. Мне не нужно было что-то совершенное, просто способ придумывания случайных цифр за полминуты. Поискав онлайн, я нашёл старый пост в Usenet, написанный Джорджем Марсалья:
Выберите двухразрядное число, допустим, 23. Оно будет вашим «порождающим значением» (seed).
Создайте новое двухразрядное число: количество десяток плюс шесть, умноженное на количество единиц.
Пример последовательности: 23 –> (2 + 6 * 3) = 20 –> (2 + 6 * 0) = 02 –> 12 –> 13 –> 19 –> 55 –> 35 –> …
Его период будет порядком множителя (6) в группе остатков, простых относительно модуля, 10 (в данном случае 59).
«Случайными цифрами» будет количество единиц двухразрядных чисел, то есть 3,0,2,2,3,9,5,… то есть члены последовательности mod 10.
Больше всего Марсалья известен своим набором тестов diehard-генераторов случайных чисел (RNG), так что он в этом понимает (здесь и далее под RNG я имею в виду генератор псевдослучайных чисел (PRNG)). Мне стало любопытно, почему это работает и как он выбрал 6.
Мы будем писать на Raku, языке для гремлинов. На случай, если вы тоже гремлин, под спойлерами я буду объяснять все странные особенности.
Читать полностью »