/* * vim:tw=76:ts=2:sw=2:cindent:expandtab */ #include #include #include #include #include #include #include "reciprocal_div64.h" #include "intrange.h" #include "salsarnd.h" int main(int argc, char *argv[]) { int64_t i; uint64_t *shuf; uint64_t tmp; uint64_t rnd = 0; uint64_t lo, hi; uint64_t nr; uint64_t flagmask; struct reciprocal_value64 recip; char *p; int flagknuth; if (argc != 4) _exit(1); flagknuth = *argv[3] - '0'; errno = 0; lo = strtoull(argv[1], &p, 10); if ((errno != 0) || (argv[1] == p)) _exit(2); hi = strtoull(argv[2], &p, 10); if ((errno != 0) || (argv[2] == p)) _exit(2); if (lo == hi) { printf("%" PRIu64 "\n", lo); fflush(stdout); return 0; } if (lo > hi) { _exit(2); } nr = hi - lo + 1; if (nr > (SIZE_MAX / sizeof(uint64_t))) _exit(3); shuf = malloc(nr * sizeof(uint64_t)); if (!shuf) _exit(4); for (i = 0; lo <= hi; i++, lo++) { shuf[i] = lo; } if (flagknuth) { i = nr; while (i > 1) { rnd = randrange_u64(i, randrange_val64(i)); i--; tmp = shuf[rnd]; shuf[rnd] = shuf[i]; shuf[i] = tmp; } } else if ((nr & (nr-1)) == 0) { flagmask = nr-1; for (i = nr - 1; i >= 0; i--) { rnd = get_random64() & flagmask; tmp = shuf[i]; shuf[i] = shuf[rnd]; shuf[rnd] = tmp; } } else { recip = reciprocal_value64(nr); for (i = nr - 1; i >= 0; i--) { rnd = reciprocal_remainder64(get_random64(), nr, recip); tmp = shuf[i]; shuf[i] = shuf[rnd]; shuf[rnd] = tmp; } } for (i = 0; i < nr; i++) printf("%" PRIu64 "\n", shuf[i]); fflush(stdout); return 0; }