Created
December 11, 2017 15:45
-
-
Save oupo/cfd49cb4f58480b835720dc61804211f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <cstdint> | |
#include <vector> | |
#include <omp.h> | |
using namespace std; | |
typedef uint32_t u32; | |
typedef int64_t s64; | |
constexpr double C4 = 261.626; | |
constexpr double D4 = 293.665; | |
constexpr double E4 = 329.628; | |
constexpr double F4 = 349.228; | |
constexpr double G4 = 391.995; | |
struct LCG { | |
uint32_t seed; | |
LCG(uint32_t s) : seed(s) {} | |
int rand(); | |
}; | |
u32 next_seed(u32 seed) { | |
return seed * 0x41c64e6d + 0x6073; | |
} | |
u32 prev_seed(u32 seed) { | |
return seed * 0xEEB9EB65 + 0x0A3561A1; | |
} | |
int LCG::rand() { | |
seed = next_seed(seed); | |
return seed >> 16; | |
} | |
bool valid_seed(u32 seed, double baseFreq, vector<double> expectedFreqs) { | |
LCG lcg(seed); | |
for (double expected : expectedFreqs) { | |
double got = ((lcg.rand() % 8192) / 8192.0 * 0.25 + 1) * baseFreq; | |
double ratio; | |
if (expected < got) { | |
ratio = got / expected; | |
} else { | |
ratio = expected / got; | |
} | |
if (ratio >= 1.015) { | |
return false; | |
} | |
} | |
return true; | |
} | |
bool good_seed(u32 seed) { | |
int i; | |
for (i = 0; i < 10; i ++) seed = prev_seed(seed); | |
for (; i < 40; i ++) { | |
u32 upper = seed >> 24; | |
u32 hour = (seed >> 16) & 0xff; | |
u32 frame = seed & 0xffff; | |
u32 second = (frame - 17) / 60 + 10; | |
if (12 * 24 + second - 256 <= upper && upper <= 12 * 24 + second + 60 - 256 | |
&& hour < 24 && 0x0270 <= frame && frame <= 0x0400) { | |
return true; | |
} | |
seed = prev_seed(seed); | |
} | |
return false; | |
} | |
int main() { | |
#ifdef _OPENMP | |
fprintf(stderr, "OpenMP is enabled. max_threads=%d\n", omp_get_max_threads()); | |
fflush(stderr); | |
#endif | |
//vector<double> expected = { E4, E4, F4, G4, G4, F4, E4, E4, E4 }; | |
//double base = 325; | |
//bool select_good = false; | |
vector<double> expected = {D4, C4, C4, D4, D4, D4}; | |
double base = 255; | |
bool select_good = true; | |
#pragma omp parallel for | |
for (s64 seed = 0; seed < 0x20000000; seed ++) { | |
if (valid_seed(seed, base, expected) && (!select_good || good_seed(seed))) { | |
#pragma omp critical | |
cout << seed << endl; | |
} | |
} | |
cout << "finished" << endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment