CD
Size: a a a
CD
NK
NK
NK
NK
NE
rand7 я генерирую a = log2(7) бит. Мне надо b = log2(10). Можно ли придумать какой-то "аккумулятор" acc, который бы комбинировал эти a бит с очередной порцией a бит, пока сумма не превысит b бит, а затем можно было бы извлечь b бит и floating-point "счётчик количества бит в аккумуляторе" уменьшить на b? Т.е. вообще без rejection обойтись?NE
AT
while (h < 10) сделать while (h < std::numeric_limits<int>::max() / 7)CD
while (h < 10) сделать while (h < std::numeric_limits<int>::max() / 7)class Solution {
public:
int rand10() {
int acc = 0;
int acc_max = 0;
for (;;) {
acc = acc * 7 + rand7() - 1;
acc_max = acc_max * 7 + 7 - 1;
if (acc_max >= 10) {
acc_max %= 10;
if (acc > acc_max) {
return (acc - acc_max) % 10 + 1;
}
}
}
}
};CD
AT
CD
class Solution {
public:
int acc = 0;
int acc_max = 0;
void push_randk(int x, int k) {
acc_max = acc_max * k + (k - 1);
acc = acc * k + x;
}
int pull_randk(int k) {
if (acc_max < k)
return -1;
int extra_max = acc_max / k;
acc_max = acc_max % k;
if (acc <= acc_max)
return -1;
int extra_acc = (acc - acc_max - 1) / k;
int result = (acc - acc_max - 1) % k;
acc = 0;
acc_max = 0;
push_randk(extra_acc, extra_max);
return result;
}
int rand10() {
for (;;) {
if (auto x = pull_randk(10); x != -1)
return x + 1;
push_randk(rand7() - 1, 7);
}
}
};CD
CD
AT
AT
AT
class Solution {
public:
int acc = 0;
int acc_max = 0;
void push_randk(int x, int k) {
acc_max = acc_max * k + (k - 1);
acc = acc * k + x;
}
int pull_randk(int k) {
if (acc_max < k)
return -1;
int extra_max = acc_max / k;
acc_max = acc_max % k;
if (acc <= acc_max)
return -1;
int extra_acc = (acc - acc_max - 1) / k;
int result = (acc - acc_max - 1) % k;
acc = 0;
acc_max = 0;
push_randk(extra_acc, extra_max);
return result;
}
int rand10() {
for (;;) {
if (auto x = pull_randk(10); x != -1)
return x + 1;
push_randk(rand7() - 1, 7);
}
}
};randX in {1, 2, ..., X}AT
CD
randX in {1, 2, ..., X}