[/b/] [/d/] [/tu/] [/a/] [/ph/] [/wa/] [/cg/] [/t/] [/p/]

[Burichan] [Foliant] [Futaba] [Greenhell] [Gurochan] [Photon] - [Home] [Manage] [Archive]

[Return]
Posting mode: Reply
Leave these fields empty (spam trap):
Name
Link
Subject
Comment
File
Verification
Password (for post and file deletion)
  • Supported file types are: GIF, JPG, PDF, PNG
  • Maximum file size allowed is 20480 KB.
  • Images greater than 200x200 pixels will be thumbnailed.

File: 1639345051010.jpg -(11051166 B, 3969x2394) Thumbnail displayed, click image for full size.
11051166 No.197230  

Посоветуйте псевдослучайную функцию. Нужно чтобы она выдавала числа от 0 до n, но при этом числа не повторялись на интервале n. Очевидное решение взять массив от 1 до n и перемешать смущает необходимостью где-то хранить этот самый массив.

>> No.197232  
File: 1639348336784.jpg -(108850 B, 500x400) Thumbnail displayed, click image for full size.
108850

Можешь попробовать псевдослучайные последовательности максимальной длинны (ПСП).
https://en.wikipedia.org/wiki/Pseudorandom_binary_sequence
Правда в таких последовательностях нет нуля и длинна кратна степени двойки, а точнее 2^n-1. Перебрав все числа она начинает повторяться. Для каждой длинны нужен свой порождающий полином и он не берется с потолка.

>> No.197234  

>>197230
https://www.pcg-random.org/
Только это не криптографическая функция, этим нельзя шифровать.

typedef struct { uint64_t state;  uint64_t inc; } pcg32_random_t;
uint32_t pcg32_random_r(pcg32_random_t* rng)
{
uint64_t oldstate = rng->state;
rng->state = oldstate * 6364136223846793005ULL + (rng->inc|1);
uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u;
uint32_t rot = oldstate >> 59u;
return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));
}
>> No.197235  

Относительно стойкая функция, если массив in[] заполнен случайными числами + счетчик.

#define ROTL(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
#define QR(a, b, c, d) ( \
a += b, d ^= a, d = ROTL(d,16), \
c += d, b ^= c, b = ROTL(b,12), \
a += b, d ^= a, d = ROTL(d, 8), \
c += d, b ^= c, b = ROTL(b, 7))
#define ROUNDS 20
void chacha_block(uint32_t out[16], uint32_t const in[16])
{
int i;
uint32_t x[16];
for (i = 0; i < 16; ++i)
x[i] = in[i];
for (i = 0; i < ROUNDS; i += 2) {
QR(x[0], x[4], x[ 8], x[12]);
QR(x[1], x[5], x[ 9], x[13]);
QR(x[2], x[6], x[10], x[14]);
QR(x[3], x[7], x[11], x[15]);
QR(x[0], x[5], x[10], x[15]);
QR(x[1], x[6], x[11], x[12]);
QR(x[2], x[7], x[ 8], x[13]);
QR(x[3], x[4], x[ 9], x[14]);
}
for (i = 0; i < 16; ++i)
out[i] = x[i] + in[i];
}
>> No.197236  

>>197232

> и длинна кратна степени двойки

Вот из-за этого не подходит.
>>197234
>>197235
И как тут произвольный n задавать?

Вобщем пока на ум приходит только модифицированный вариант с массивом - взять массив чисал от 0 до n и перемешать с использованием псевдослучайного генератора, заново инициализированного известным seed. Оно конечно дико неэффективно получается по cpu, но зато по крайней мере хранить достаточно только seed и offset в массиве.

>> No.197250  

Числа случайные, но одни и те же.

#include <stdio.h>

int get_rand(int min, int max) {
static long gen = 0x30;
gen = gen * 0xF324D29EL;
return ((int)(((gen>>0x8) & 0x7FFE) % (max-min+1)) + min);
}

int main(void) {
int i;

for (i = 0; i < 10; i++)
printf("%d\n", get_rand(1, 100));

return 0;
}
>> No.197251  

>>197230
Условие у задачи ебанутое. Ты сам придумал? Что значит “выдавать числа”? В смысле integer или array of integer?
Ты говоришь про массив от 1 до n. От единицы? Почему от единицы, куда 0 делся? Вроде же от 0 нужно было.
Нужна именно функция в каноничном ее понимании, то есть stateless? Eсли ты хочешь чтобы функция возвращала integer, то у тебя никак не получится сделать ее stateless, потому что ты сам пишешь, что надо где-то хранить ключ и офсет. А если речь про stateful, то это какбе уже не функция а класс нужен.

>> No.197252  

Напиши лучше конкретную задачу, которую тебе надо решить, а демагогию академическую оставь студентам.

>> No.197256  

>>197251
Можно и с 0, не принципиально. Функция stateless, но в качестве аргумента вполне естественно кормить ей seed и offset.
>>197252
Если тебе станет от этого легче, то раздача бонусов в игре так, чтобы они не повторялись.

>> No.197258  
>Функция stateless, но в качестве аргумента вполне естественно кормить ей seed и offset.

Ну тогда тебе придётся часть кода написать за пределами функции. То есть это уже не функция получается, и я так понял тебе некритично вообще функция там или что.
А разве выданные бонусы не записываются куда-нибудь в базу данных для последующего анализа? А то сейчас рандомно, а завтра окажется что какой-то бонус нарушает баланс и надо поменять его вероятность. Имея историю в бд, можно эти вероятности вертеть как угодно. Конечно, функция с офсетом и сидом будет быстрее, чем в базе хранить, но мэйнтейнабилити у неё никакая, придётся ее всю переписывать если спецификация поменяется.

>> No.197259  

>>197258

> А разве выданные бонусы не записываются куда-нибудь в базу данных для последующего анализа?

Вот этого я и хочу избежать. Имея offset и seed это все отлично восстанавливается через ту же функцию.

>> No.197264  

>>197259
Но ты же не сможешь поменять вероятности при необходимости. С этим проблем нет?

>> No.197265  

>>197264
Не думаю что это станет большой проблемой.



Delete Post []
Password

[/b/] [/d/] [/tu/] [/a/] [/ph/] [/wa/] [/cg/] [/t/] [/p/]