@@ -22,38 +22,53 @@ void semicorr(auto &a, auto &b) {
2222}
2323
2424auto is_integer (auto a) {
25- static const ftype eps = 1e-8 ;
26- return cp_algo::abs (imag (a)) < eps
27- && cp_algo::abs (real (a) - cp_algo::round (real (a))) < eps;
25+ static const ftype eps = 1e-9 ;
26+ return cp_algo::abs (a - cp_algo::round (a)) < eps;
2827}
2928
3029string matches (string const & A, string const & B, char wild = ' *' ) {
31- static point project[2 ][128 ];
30+ static ftype project[2 ][128 ];
3231 static bool init = false ;
3332 if (!init) {
3433 init = true ;
34+ std::random_device rd;
35+ std::mt19937 gen (rd ());
36+ std::uniform_real_distribution<> dis (.5 , 2 .);
3537 for (int i = 0 ; i < 128 ; i++) {
36- project[0 ][i] = cp_algo::polar<ftype>(1 ., (ftype)cp_algo::random::rng ());
37- project[1 ][i] = conj (project[0 ][i]);
38+ ftype x = dis (gen);
39+ project[0 ][i] = x;
40+ project[1 ][i] = 1 . / x;
3841 }
3942 }
4043 project[0 ][(int )wild] = project[1 ][(int )wild] = 0 ;
4144 vector<cvector> P;
42- P.emplace_back (size (A));
43- P.emplace_back (size (A));
44- for (auto [i, c]: A | views::enumerate) {
45- P[0 ].set (i, project[0 ][(int )c]);
46- }
47- for (auto [i, c]: B | views::reverse | views::enumerate) {
48- P[1 ].set (i, project[1 ][(int )c]);
49- }
45+ P.emplace_back ((size (A) + 1 ) / 2 );
46+ P.emplace_back ((size (A) + 1 ) / 2 );
47+ int N = P[0 ].size ();
48+ auto assign = [&](int z) {
49+ return [&, z](auto ic) {
50+ auto [i, c] = ic;
51+ if (i < N) {
52+ real (P[z].r [i / fft::flen])[i % fft::flen] = project[z][(int )c];
53+ } else {
54+ i -= N;
55+ imag (P[z].r [i / fft::flen])[i % fft::flen] = project[z][(int )c];
56+ }
57+ };
58+ };
59+ ranges::for_each (A | views::enumerate, assign (0 ));
60+ ranges::for_each (B | views::reverse | views::enumerate, assign (1 ));
5061 cp_algo::checkpoint (" cvector fill" );
5162 semicorr (P[0 ], P[1 ]);
52- string ans (size (P[0 ]), ' 0' );
53- auto start = (size (B) - 1 ) / fft::flen * fft::flen;
54- for (size_t j = start; j < size (ans); j += fft::flen) {
55- auto r = P[0 ].at (j);
56- auto check = is_integer (r);
63+ string ans (2 * size (P[0 ]), ' 0' );
64+ int start = (ssize (B) - 1 ) / fft::flen * fft::flen;
65+ for (int j = start; j < ssize (ans); j += fft::flen) {
66+ decltype (is_integer (real (P[0 ].at (j)))) check;
67+ if (j < N) {
68+ check = is_integer (real (P[0 ].at (j)));
69+ } else {
70+ check = is_integer (imag (P[0 ].at (j - N)));
71+ }
5772 for (int z = 0 ; z < 4 ; z++) {
5873 ans[j + z] ^= (bool )check[z];
5974 }
0 commit comments