Псевдовипадковий генератор
Є багато областей, де нам потрібні випадкові дані.
Одна з них – тестування. Нам можуть знадобитися випадкові дані: текст, числа тощо, щоб добре все перевірити.
У JavaScript ми можемо використовувати Math.random()
. Але якщо щось піде не так, ми хотіли б мати можливість повторити тест, використовуючи точно ті самі дані.
Для цього використовуються так звані “сіяні псевдовипадкові генератори”. Вони беруть “зерно”, перше значення, а потім генерують наступні за допомогою формули, так що те саме насіння дає ту саму послідовність, а отже, весь потік легко відтворюється. Нам потрібно лише згадати зерно, щоб повторити його.
Приклад такої формули, яка генерує рівномірно розподілені значення:
next = previous * 16807 % 2147483647
Якщо ми використаємо 1
як зерно, то значення будуть такими:
16807
282475249
1622650073
- …and so on…
Завдання полягає в тому, щоб створити функцію-генератор pseudoRandom(seed)
, яка приймає seed
і створює генератор з цією формулою.
Приклад використання:
let
generator =
pseudoRandom
(
1
)
;
alert
(
generator.
next
(
)
.
value)
;
// 16807
alert
(
generator.
next
(
)
.
value)
;
// 282475249
alert
(
generator.
next
(
)
.
value)
;
// 1622650073
function
*
pseudoRandom
(
seed
)
{
let
value =
seed;
while
(
true
)
{
value =
value *
16807
%
2147483647
;
yield
value;
}
}
;
let
generator =
pseudoRandom
(
1
)
;
alert
(
generator.
next
(
)
.
value)
;
// 16807
alert
(
generator.
next
(
)
.
value)
;
// 282475249
alert
(
generator.
next
(
)
.
value)
;
// 1622650073
Зверніть увагу, те ж саме можна зробити зі звичайною функцією, наприклад:
function
pseudoRandom
(
seed
)
{
let
value =
seed;
return
function
(
)
{
value =
value *
16807
%
2147483647
;
return
value;
}
}
let
generator =
pseudoRandom
(
1
)
;
alert
(
generator
(
)
)
;
// 16807
alert
(
generator
(
)
)
;
// 282475249
alert
(
generator
(
)
)
;
// 1622650073
Це також працює. Але тоді ми втрачаємо можливість перебору за допомогою for..of
і використання композиції генераторів, що може бути корисною в інших випадках.