long long mySol(long long n, long long d) {
long long r = 1;
for (long long i=d + 1; i<n + 1; ++i) r *= i;
return r;
}
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <assert.h>
#include <criterion/criterion.h>
long long mySol(long long n, long long d) ;
static void generate_n_d(long long *n, long long *d, long long min_d, long long max_d, long long max_delta) {
*d = min_d + rand() % (max_d + 1 - min_d);
unsigned long long max_n = *d + 1;
long double prod = *d + 1;
unsigned long long prodi = *d + 1;
while (prod < LLONG_MAX && max_delta > 0) {
--max_delta;
++max_n;
prod *= max_n;
prodi *= max_n;
printf("min_d = %lld, max_d = %lld, max_n = %lld, prod = %.0Lf, prodi = %llu\n",
max_d, min_d, max_n, prod, prodi
);
fflush(stdout);
assert((long double)prodi == prod);
}
*n = *d + (rand() % (max_n - 1 - *d)) + 1;
}
Test(tests, generate_n_d_overflow) {
long long tests_param[3][4] = {
/*{test count, min d , max d , max delta } */
{25ll , 4ll , 512ll , 20ll },
{25ll , 256ll , 262144ll , 200ll },
{50ll , 65536ll, 0x1p31 , 1000ll },
//0x1p31 = 2^32
};
for (size_t i=0; i<3; ++i) {
for (long long j=0; j<tests_param[i][0]; ++j) {
long long n;
long long d;
generate_n_d(&n, &d, tests_param[i][1], tests_param[i][2], tests_param[i][3]);
printf("%lld %lld %lld\n", n, d, mySol(n, d));
}
}
}